Webrium
Подписаться

Connection refused и timed out: что говорит текст ошибки

Почему возникает отказ соединения и как отличить его от других сетевых ошибок

Схема фильтрации: из нескольких портов на сервере подключение принимает только один нужныйПорты на сервереПравильный порт

ssh: connect to host … port 22: Connection refused

Ошибка Connection refused — самая прямая из всех. Она означает, что на SYN клиента пришёл активный отказ: в прямом случае пакет дошёл до машины, а на указанном адресе и порту никто не слушает. Ответ приходит мгновенно: ядро сервера или промежуточный фильтр отправляет клиенту сброс TCP (сегмент RST) или ICMP-сообщение о недоступности порта. Это не значит, что сервис упал — он может быть запущен, но слушать не на том адресе.

Например, сервис, привязанный к 127.0.0.1, принимает соединения только с петлевого адреса этой же машины. Обращение на внешний адрес той же машины получит отказ, хотя сервис работает и порт открыт. Отдельный случай — адреса IPv6. Сокет, привязанный к ::, на Linux по умолчанию двухстековый и принимает и IPv4-соединения; это поведение задаёт параметр net.ipv6.bindv6only, смотрят его командой sysctl net.ipv6.bindv6only. В обратную сторону это не работает: сокет на IPv4-адресе соединений IPv6 не принимает. Если сервис слушает только IPv4, а имя localhost разрешилось в ::1, клиент получит отказ, хотя сервис работает. Часть клиентов после отказа на ::1 пробует второй адрес (127.0.0.1), часть — нет.

В контейнерной сети по умолчанию у контейнера своё сетевое пространство имён, и 127.0.0.1 внутри него — петля самого контейнера, а не хоста и не соседнего контейнера. При сетевом режиме хоста петля у контейнера общая с хостом, при общем сетевом пространстве имён — с контейнерами, которые его делят. Сервис, слушающий только на 127.0.0.1 внутри контейнера, через опубликованный порт недоступен. Исход зависит от пути подключения. Пакет, пришедший снаружи, переадресуется в контейнер и получает отказ Connection refused. При обращении через петлю хоста исход зависит от способа публикации порта:

  • Если порт слушает процесс-посредник, он принимает соединение, но за ним никто не слушает. Клиент видит установленное соединение с немедленным сбросом (Connection reset by peer) или пустым ответом.
  • Если публикация сделана только правилами трансляции адресов (NAT), приходит отказ Connection refused.

На хосте команда ss -ltnp не видит сокеты внутри сетевого пространства имён контейнера. Виден либо процесс-посредник публикации порта, либо ничего, если переадресация сделана правилами NAT. Чтобы проверить, кто слушает в контейнере, команду ss -ltnp запускают с правами суперпользователя в его сетевом пространстве имён с хоста: nsenter -t PID -n ss -ltnp, где PID — номер процесса сервиса на хосте.

Connection timed out — что значит и почему не очевидно

Ошибка Connection timed out означает, что на SYN-сегмент клиента не пришло никакого ответа. Это может быть молчаливое отбрасывание фильтром на сервере, неверный маршрут, потерянный обратный путь или отсутствие машины по адресу. Таймаут не доказывает, что сервер жив — он лишь говорит, что ответа не было, и даже не гарантирует, что пакет дошёл до сервера.

Ядро не возвращает ошибку сразу. Оно несколько раз повторяет SYN, и паузы между попытками со временем растут. Число повторов на Linux задаёт параметр net.ipv4.tcp_syn_retries (несмотря на имя, он действует и для IPv6), а значение на своей машине показывает команда sysctl net.ipv4.tcp_syn_retries. Ожидание длится долго, поэтому часть клиентов обрывает попытку собственным таймером и печатает собственный текст. Другая часть — в том числе ssh без настройки таймаута — ждёт ядро и печатает текст по его коду; таким клиентам таймаут задают явно. Таймаут соединения и таймаут ожидания ответа — разные события с похожим текстом:

  • Таймаут соединения (Connection timed out) возникает, когда SYN не получил ответа. Искать нужно в сети: фильтры, маршруты, недоступность машины.
  • Таймаут ожидания ответа (Connection timed out или Operation timed out) возникает, когда соединение установлено, но сервис молчит. Искать нужно в сервисе: зависший процесс, переполненная очередь, медленная обработка.

Текст ошибки зависит от системной библиотеки. На Linux с распространённой библиотекой это Connection timed out, с облегчённой (в минимальных образах контейнеров) — Operation timed out. На macOS и BSD таймаут тоже Operation timed out. Код ошибки (ETIMEDOUT) при этом один и тот же, но формулировка отличается.

Случаи, которые маскируются под другие ошибки

Переполненная очередь принятых соединений у слушающего сокета не даёт Connection refused. Новый SYN ядро Linux молча отбрасывает — клиент получает таймаут соединения. Завершающий ACK уже начатого рукопожатия игнорируется — клиент считает соединение установленным и виснет на чтении, получая таймаут ответа. Если включён параметр net.ipv4.tcp_abort_on_overflow, в ответ на этот ACK уходит RST, и клиент видит Connection reset by peer.

Окно между стартом процесса и открытием порта тоже маскируется. Менеджер служб при типе службы по умолчанию считает её запущенной сразу после старта процесса, а не после того, как процесс начал слушать порт. Если служба сама сообщает менеджеру о готовности, запуск засчитывается по этому сообщению; при сокетной активации порт слушает сам менеджер, и окна отказа нет. В окне между стартом и открытием порта клиенты получают отказ Connection refused, который проходит сам через несколько секунд.

Сброс сразу после установления соединения (Connection reset by peer) бывает признаком того, что соединение принял посредник — процесс публикации порта контейнера или балансировщик, за которым никто не слушает. Клиент видит сброс, хотя сервис работает и порт открыт. Тот же сброс даёт переполненная очередь при включённом net.ipv4.tcp_abort_on_overflow и сам сервис, закрывший соединение, не прочитав присланное.

Failed to connect … Connection refused — порядок проверки от клиента к серверу

Первым делом убедитесь, что клиент идёт на ту машину. Адрес подключения показывает curl -v — в строках с перебором адресов видно, на какой адрес идёт попытка. Устаревшая запись имени в /etc/hosts или кэше DNS даёт отказ или таймаут чужой машины.

С машины клиента проверьте соединение командой nc -vz хост порт с явным таймаутом (-w 2). Успех nc доказывает только то, что соединение кто-то принял — за опубликованным портом контейнера или балансировщиком это может быть посредник, за которым никто не слушает. Если клиент ходит к сервису через прокси, эти же тексты ошибок стоят в журнале ошибок прокси, а клиент видит уже код ответа. Поэтому успех nc подтверждают настоящим запросом (например, curl). Эта цепочка разобрана в материале 502 и 504: кто именно не ответил и что чинить.

На сервере проверьте слушающие сокеты командой ss -ltnp. Для контейнера ту же команду запустите с правами суперпользователя в его сетевом пространстве имён: nsenter -t PID -n ss -ltnp, где PID — номер процесса сервиса, как его видит хост. Номер покажет pgrep -f имя_процесса; если совпадений несколько, подставьте один номер — любой из процессов нужного контейнера, сетевое пространство имён у них общее. Захват пакетов на сервере (tcpdump -ni any port N) показывает три исхода с разными причинами:

  1. SYN виден, ответа нет

    • Пакет отброшен входящим правилом локального фильтра (для контейнера — в цепочке пересылки, а не во входящей).
    • Проверка обратного пути (rp_filter) отбросила пакет как подозрительный.
    • Переполненная очередь принятых соединений — новый SYN молча отброшен.
    • Ответ отброшен исходящим правилом того же локального фильтра и до точки захвата не дошёл.
    • Фильтр отклонил пакет с ICMP-ответом (например, “port unreachable”), но ICMP не попадает в захват с фильтром port N.
  2. SYN виден, SYN-ACK уходит, но клиент всё равно ждёт

    • Локальный фильтр ответ пропустил, но теряется обратный путь:
      • Неверный маршрут ответа.
      • Асимметричная маршрутизация (запрос и ответ идут разными путями).
      • Фильтр по дороге к клиенту отбрасывает SYN-ACK.
  3. SYN не виден

    • Пакет теряется раньше по пути (например, фильтр на промежуточном маршрутизаторе).
    • Клиент ходит на другую машину (устаревшая запись имени, неверный IP).
    • Фильтр захвата задан не по тому порту из-за трансляции портов (например, опубликован порт 8080, а сервис слушает 80).

Тупик: открыть порт и перезапустить сервис

Первым делом часто открывают порт в межсетевом экране и перезапускают сервис. При отказе Connection refused это обычно мимо: дорогу пакет уже прошёл, не хватает слушателя на нужном адресе. При таймауте Connection timed out перезапуск тоже обычно не помогает: до сервиса ничего не доходит.

Исключения есть, и их два:

  1. Фильтр с правилом отклонения Некоторые фильтры настроены отвечать на запрещённые пакеты сбросом TCP (RST) или ICMP-сообщением о недоступности порта. В этом случае клиент видит Connection refused, хотя порт на сервере открыт. Открытие порта в фильтре — верное действие, но отличить этот случай от отсутствия слушателя можно только по захвату пакетов на сервере.

  2. Зависший процесс, переполнивший очередь соединений Если процесс завис и перестал забирать соединения из очереди, перезапуск помогает. Если процесс не успевает за потоком соединений, перезапуск даёт только временное облегчение. Переполнение видно по счётчикам nstat -az TcpExtListenOverflows TcpExtListenDrops и по колонкам Recv-Q и Send-Q у слушающего сокeta в выводе ss.

Перебор обоих действий (открыть порт, перезапустить сервис) иногда срабатывает случайно, но не оставляет понимания, что было сломано. Правильный порядок — прочитать текст ошибки и подтвердить её одной командой с каждой стороны.

No route to host и другие ошибки

Ошибки No route to host и Network is unreachable говорят о том, что пакет не удалось доставить: либо клиент не смог его отправить, либо в ответ на него пришло ICMP-сообщение о недостижимости или запрете хоста либо сети. No route to host (код EHOSTUNREACH) возникает, когда:

  • Маршрутизатор прислал ICMP-сообщение о недостижимости хоста.
  • Фильтр на маршрутизаторе или сервере отклонил пакет с ответом «запрещено административно» (так в IPv4; в IPv6 текст ошибки другой).
  • В локальном сегменте сети никто не ответил на ARP-запрос (машина выключена или неверный адрес).

Network is unreachable (код ENETUNREACH) означает, что у клиента нет маршрута к сети назначения, либо маршрутизатор или фильтр ответил, что сеть недостижима.

Ошибки разрешения имени (Name or service not known, Could not resolve host) возникают до любой попытки соединения. Это отказ DNS, порт и состояние сервиса здесь ни при чём.

Позиция редакции

Текст ошибки соединения уже называет слой, на котором искать:

  • Connection refused: слушатель и его адрес (127.0.0.1 против 0.0.0.0, :: против ::1).
  • Connection timed out: фильтры, маршруты, недоступность машины.
  • No route to host / Network is unreachable: маршрутизация и ARP.
  • Ошибка имени: разрешение DNS.

Его стоит прочитать буквально, отличив таймаут соединения от таймаута ответа, и подтвердить одной командой с каждой стороны (nc на клиенте, ss на сервере), прежде чем менять хоть одну настройку.

Неверна эта позиция, если между клиентом и сервером стоит посредник — прокси, балансировщик, фильтр с правилом отклонения или процесс публикации порта контейнера. Тогда ошибку формирует он, и по её тексту о состоянии сервера судить нельзя. Различить случаи позволяет только захват пакетов на самом сервере.

Вторая оговорка: таймаут соединения при исправной сети может давать переполненная очередь принятых соединений. Тогда причина в сервисе, а не в фильтрах и маршруте, и видно это по ss на сервере (переполненная Recv-Q).

С чем это связано

Метка над заголовком говорит, зачем туда идти: продолжить тему, перейти к практике или увидеть возражение.

Цепочка запроса: прокси передаёт запрос, но бэкенд не отвечаетПроксиБэкенд не ответил
Углубление

502 и 504: кто именно не ответил и что чинить

Как отличить сбой сервера от задержки в цепочке и быстро вернуть инфраструктуру в строй.

Схема стыка: совпадение гарантий TCP и разрыв данных UDPНадёжность TCPПотери UDP
Предыстория

Чем TCP отличается от UDP и что из этого следует

Как TCP устанавливает соединение — обмен SYN, SYN-ACK и ACK, на который опирается разбор отказа и таймаута, — и чем поток TCP отличается от датаграмм UDP.

Цепочка DNS-запроса от браузера до сервера через резолвер, корневые и TLD-серверыЗапрос браузераСервер сайта
Практика

Домен не открывается: как проверить DNS по шагам

Как по шагам проверить DNS, когда домен не открывается: ответ авторитетных серверов, делегирование, кеш резолвера — и как понять, что DNS ни при чём.

Вложенные слои: программа, зависимости и настройки упакованы в контейнер DockerПрограмма в Docker
Просто

Docker простыми словами: что он решает и чего не решает

Запускаете программу на одном компьютере, а она не работает на другом — Docker упаковывает её так, что запустится везде без настроек.

Письмо по вторникам

Один разбор недели и короткий список того, что изменилось. Без дайджестов на сорок ссылок.

Начните вводить — материалы появятся здесь.

↑↓ выбрать · Enter открыть · Esc закрыть