SSH Connection refused или timed out: в чем разница
Разберитесь в причинах ошибок SSH. Connection refused означает, что сервер ответил отказом, а Connection timed out указывает на отсутствие ответа от узла по пути следования.
Что означают ошибки "Connection refused" и "Connection timed out" при работе по SSH
Ошибки SSH "Connection refused" и "Connection timed out" указывают на противоположные типы сбоев, поэтому методы их устранения никогда не совпадают. Ошибка "refused" означает, что пакет достиг сервера, но ядро ответило, что на данном порту никто не ожидает соединений. Ошибка "timed out" означает, что пакет не дошел до адресата, который мог бы на него ответить, поэтому клиент ожидал ответа и в итоге прервал попытку. "Refused" — это проблема сервиса на стороне сервера. "Timed out" — это проблема сетевого пути до сервера.
Изучите точную формулировку сообщения, выведенного клиентом, так как текст ошибки содержит полный диагноз.
ssh: connect to host 203.0.113.10 port 22: Connection refused
ssh: connect to host 203.0.113.10 port 22: Connection timed outВторой признак — время ожидания. Ошибка "refused" возвращается мгновенно, примерно за время одного цикла обмена пакетами (round trip). Ошибка "timed out" возникает через несколько секунд, так как клиент продолжает повторные попытки отправки перед тем, как сдаться. В macOS для этого же состояния выводится сообщение Operation timed out. Если сам протокол для вас в новинку, то статья как работает SSH и что делает sshd содержит базовые сведения, на которые опирается данное руководство.
Почему "Connection refused" — это хорошая новость
Refused означает, что TCP (transmission control protocol) отправил сброс соединения. Ваш клиент отправляет SYN-пакет на порт 22. Он проходит через интернет, достигает сетевого стека сервера, и ядро обнаруживает, что на этом порту нет слушающего сокета, поэтому отвечает RST-пакетом (reset). Ваш SSH-клиент преобразует этот RST в сообщение Connection refused.
Этот единственный ответный пакет доказывает многое. Адрес указан верно. Хост включен и маршрутизация работает. Ничто на пути следования не отбрасывает трафик до этого порта молча, так как с удаленной стороны пришел ответ. Следовательно, все оставшиеся причины кроются на самом сервере.
sshdне запущен, так как произошел сбой при старте или сервис не был включен.sshdслушает другой порт, что часто случается после изменения настроек безопасности.sshdпривязан к конкретному адресу, напримерListenAddress 127.0.0.1, поэтому доступ к нему возможен только с самого сервера.- Межсетевой экран настроен на отклонение (reject), а не на отбрасывание (drop), поэтому он отправляет RST от имени хоста. Действие
rejectв ufw и правило nftables, заканчивающееся наreject with tcp reset, работают именно так.
Существует еще один случай, который выглядит похоже, но таковым не является: вы ввели адрес, принадлежащий другому работающему хосту. Этот хост отвечает на ваш SYN, не имеет SSH на порту 22 и вежливо отказывает вам. Проверьте адрес, прежде чем тратить час на работу с неверным сервером. Понимание того, что такое слушающий порт в Linux, поможет быстрее разобраться с остальной частью этого раздела.
Как исправить ошибку Connection refused
Вы не сможете исправить это через SSH, так как именно SSH перестал работать. Откройте веб-консоль или последовательную консоль (serial console) вашего провайдера, войдите в систему и выполните следующие команды.
systemctl status ssh
sudo ss -tlnp
sudo sshd -T | grep -Ei '^(port|listenaddress|addressfamily)'systemctl status ssh используется в качестве имени юнита в Ubuntu и Debian. В RHEL и производных дистрибутивах, таких как AlmaLinux, юнит называется sshd. ss -tlnp выводит список всех TCP-сокетов в состоянии прослушивания (listening) вместе с процессом, которому они принадлежат; это основной источник истины: если в выводе нет строки с sshd, значит, никто не слушает порт, независимо от того, что указано в конфигурационном файле. sshd -T выводит итоговую конфигурацию после объединения всех файлов Include — именно здесь можно обнаружить забытый порт в /etc/ssh/sshd_config.d/.
Внимательно изучите столбец адресов. 0.0.0.0:22 означает все IPv4-адреса на сервере. [::]:22 означает все IPv6-адреса. 127.0.0.1:22 означает только loopback, поэтому любое удаленное подключение к нему будет отклонено, в то время как локальный ssh localhost будет работать корректно.
Если никто не слушает порт, запустите сервис и ознакомьтесь с ошибкой, если он не запускается.
sudo sshd -t
sudo systemctl enable --now ssh
sudo journalctl -u ssh -n 50 --no-pagersshd -t проверяет конфигурацию и выводит имя файла и номер строки с ошибочной директивой, не затрагивая работающий сервис. Запускайте эту команду перед каждым перезапуском, так как при наличии ошибок в конфигурации sshd завершит работу при старте, и ваше следующее подключение будет отклонено.
Ловушка socket activation в Ubuntu
В Ubuntu 24.04 для OpenSSH поставляется systemd socket unit. Если этот юнит включен, systemd удерживает порт прослушивания и запускает sshd для каждого соединения. В этом случае Port 2222 в sshd_config не дает эффекта, и сервер продолжает отвечать на старом порту. Перед внесением правок проверьте, какой режим используется в вашей системе.
systemctl is-enabled ssh.socket
systemctl status ssh.socketЕсли socket активирован, укажите порт в настройках socket unit, а не в sshd_config.
sudo systemctl edit ssh.socket[Socket]
ListenStream=
ListenStream=2222Пустая строка ListenStream= обязательна, так как настройки списков в systemd дополняют уже существующую конфигурацию. Если её пропустить, сервер будет слушать оба порта. Примените изменения с помощью sudo systemctl daemon-reload и sudo systemctl restart ssh.socket, затем убедитесь командой sudo ss -tlnp, что новый порт успешно занят. Смена порта — стандартный этап при укреплении безопасности SSH на VPS, и именно на этом шаге пользователи чаще всего теряют доступ к серверу.
Почему «Connection timed out» означает отсутствие ответа
Тайм-аут — это тишина. Ваш клиент отправил пакет SYN, несколько раз повторил попытку в течение минуты или двух, но не получил в ответ ни одного пакета. Это не дает никакой информации о сервере, так как от него не поступило ни одного сигнала.
Тишина — это именно то, что создает правило DROP, так как отбрасывание пакетов (dropping) является намеренным действием. Отказ (rejection) сообщает любому сканеру, что хост существует, поэтому ufw и сетевые экраны всех облачных провайдеров просто отбрасывают нежелательные пакеты, не отправляя ничего обратно. Ваш тайм-аут обычно означает, что межсетевой экран выполняет свою работу на порту, который вы хотели открыть.
- Адрес указан неверно: DNS-запись все еще указывает на переустановленный сервер или допущена опечатка, из-за которой запрос попадает на неиспользуемый адрес.
- Хост недоступен: он выключен или находится в процессе перезагрузки. Блокировка аккаунта провайдером из-за проблем с оплатой выглядит снаружи точно так же.
- Межсетевой экран хоста блокирует порт 22, чаще всего потому, что
ufw enableбыл выполнен до того, как было создано разрешающее правило. - Межсетевой экран провайдера перед инстансом отбрасывает пакет, и операционная система даже не видит его.
- Ваша собственная сеть блокирует исходящий трафик на порт 22, что часто встречается в офисных сетях и отелях.
Run the test from the right side of the connection
Here is the mistake that costs the most time. You cannot diagnose a dropped packet from inside the box the packets are not reaching. If you could log in to run the command, you would not have the problem. Every command in this section runs on your own machine.
getent hosts vps.example.com
ssh -G vps.example.com | grep -Ei '^(hostname|port|user)'
ssh -vvv -o ConnectTimeout=10 user@vps.example.com
nc -vz -w 5 203.0.113.10 22getent hosts shows the address your machine will really use, which catches a stale DNS record in seconds. ssh -G prints the settings your client applies after reading ~/.ssh/config, so it catches an old Host block that quietly rewrites the hostname, the port or the user. ssh -vvv shows how far the attempt got: a last line about connecting to the address followed by a long pause is a timeout, while a line reporting the remote OpenSSH version means TCP already succeeded and your real problem is authentication. On Windows, Test-NetConnection 203.0.113.10 -Port 22 in PowerShell replaces nc.
Test the port, not the host. A failed ping proves nothing, because many providers filter ICMP (internet control message protocol) at the edge. A successful ping proves nothing either, because it says nothing about port 22.
Then change the one variable no command can change for you: your network. Retry from a phone hotspot. If the hotspot connects and your desk does not, the block is on your side of the internet, or your office address has been banned on the server.
Сетевой экран провайдера, невидимый с сервера
Большинство панелей управления VPS предлагают сетевой экран, который иногда называют группой безопасности или облачным файрволом. Он работает перед вашим экземпляром и содержит собственный список правил. ufw status на сервере не видит эти правила, поэтому фраза «но я же открыл порт 22» встречается так часто. Откройте панель управления и изучите этот список, прежде чем менять правила внутри системы.
Один инструмент позволяет решить этот вопрос, но для него нужен доступ к консоли. Запустите его на сервере, а затем попробуйте подключиться с вашего ноутбука, пока команда выполняется.
sudo tcpdump -ni any tcp port 22Если во время попытки подключения клиента ничего не отображается, значит, пакеты отбрасываются до того, как они достигают операционной системы. В этом случае проблема заключается в сетевом экране провайдера или маршруте к хосту. Если SYN-пакеты приходят, но ответ не уходит, значит, отброс происходит локально и связан с ufw или nftables. Этот простой тест позволяет сразу разделить возможные причины таймаута, поэтому стоит воспользоваться консолью.
Порядок правил ufw, IPv6 и блокировка самого себя
Ошибка в порядке применения правил ufw приводит к потере доступа чаще, чем любая другая причина. sudo ufw enable немедленно устанавливает политику запрета входящих соединений по умолчанию, поэтому, если правило для SSH не добавлено заранее, текущая сессия сохраняется благодаря состоянию established, но все новые попытки подключения завершаются по таймауту. Сначала разрешайте, затем включайте.
sudo ufw allow OpenSSH
sudo ufw status verboseПрофиль приложения OpenSSH охватывает только порт 22. Если вы планируете перенести SSH на порт 2222, вам потребуется правило sudo ufw allow 2222/tcp, которое нужно добавить до изменения порта, а не после. Более широкий набор правил описан в основах работы с ufw на VPS, а безопасный порядок действий — в первоначальной настройке нового VPS.
IPv6 вызывает таймаут, который выглядит необъяснимым. Если у имени хоста есть запись AAAA, клиент сначала пытается подключиться по IPv6, поэтому сервер без настроенных правил для IPv6 зависает, в то время как попытка по IPv4 проходит успешно. Разделяйте эти настройки вручную.
ssh -4 user@vps.example.com
ssh -6 user@vps.example.comЕсли -4 подключается, а -6 — нет, проблему нужно искать в правилах IPv6 на сервере; руководство открытие того же порта для IPv6 в ufw поможет это исправить.
Вы также могли заблокировать сами себя. fail2ban отслеживает лог аутентификации и добавляет правило в брандмауэр для адресов, с которых поступают повторяющиеся неудачные попытки входа, поэтому неверный ключ или фоновый скрипт могут заблокировать весь офисный IP-адрес. Блокировка с отбрасыванием пакетов (drop) выглядит как таймаут. Блокировка с отклонением (reject) возвращает No route to host. Проверка из консоли:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 198.51.100.24Добавление вашего адреса в ignoreip описано в настройке fail2ban на Ubuntu 24.04.
Ошибки, которые не являются ни отказом в соединении, ни таймаутом
No route to host означает, что пришло ICMP-сообщение о недоступности узла. Либо у вашей машины нет маршрута к этой сети, либо кто-то на пути следования пакета ответил административным запретом — именно это отправляет правило REJECT в iptables.
Network is unreachable означает, что отвечает ваша собственная машина. У неё вообще нет маршрута для этого семейства адресов; это стандартный ответ, когда имя хоста разрешается только в IPv6-адрес при наличии соединения только по IPv4.
kex_exchange_identification: Connection closed by remote host означает, что TCP-соединение было установлено, но сервер разорвал его до завершения обмена ключами. Порт открыт, и sshd работает, поэтому проверьте нагрузку на сервер, логи в MaxStartups или блокировку, которая сработала в момент вашего подключения.
Permission denied (publickey) означает, что вы дошли до этапа аутентификации и не прошли её. Сеть и межсетевой экран работают исправно, поэтому рекомендации из этого руководства здесь не применимы. Перейдите к исправлению ошибки Permission denied (publickey) в SSH.
Как восстановить доступ и избежать повторной блокировки
Любой серьезный хостинг VPS предоставляет консоль, не зависящую от сетевых настроек гостевой системы: последовательную консоль (serial console) или VNC-экран в браузере. Эта консоль является основным способом восстановления для обоих случаев, описанных в данном руководстве, так как она продолжает работать, даже если служба sshd остановлена или правила межсетевого экрана отбрасывают все входящие пакеты. Найдите консоль в панели управления, войдите как root или под своим обычным пользователем и выполните проверки, описанные выше. Если вы не задавали пароль для root, большинство панелей позволяют сбросить его.
Если консоль отсутствует, используйте режим восстановления (rescue mode), предоставляемый провайдером. Он загружает минимальную систему восстановления и монтирует ваш диск, что позволяет отредактировать /etc/ssh/sshd_config или удалить блокирующее правило межсетевого экрана в автономном режиме, после чего можно перезагрузить сервер.
Две привычки помогут предотвратить повторную блокировку. Всегда держите открытой вторую SSH-сессию при редактировании sshd или настроек межсетевого экрана, так как она сохраняет установленное соединение, пока вы тестируете новые настройки в другом окне. Также используйте автоматический откат перед внесением рискованных изменений в правила межсетевого экрана.
sudo systemd-run --unit=ufw-rollback --on-active=10min /usr/sbin/ufw disable
sudo systemctl stop ufw-rollback.timerПервая строка планирует автоматическое отключение ufw через десять минут. Примените новые правила, откройте новую SSH-сессию, чтобы убедиться в их работоспособности, а затем выполните вторую строку, чтобы отменить откат. Если вы все же потеряли доступ, подождите десять минут, и межсетевой экран отключится самостоятельно. Сервер останется без фильтрации до тех пор, пока вы снова не включите ufw, поэтому используйте этот метод только во время работы за клавиатурой, а не в качестве постоянного решения.
Порядок действий при работе
- Прочитайте текст ошибки и обратите внимание на время, прошедшее до её появления.
- Refused: перейдите в консоль и проверьте
sudo ss -tlnpна наличие слушающего сокета, его порта и адреса, к которому он привязан. - Timed out: подтвердите адрес со своей машины, затем проверьте брандмауэр провайдера в панели управления, а после — локальный брандмауэр на сервере.
- Ни одна из этих строк: у вас уже установлено TCP-соединение, поэтому рассматривайте проблему как вопрос аутентификации или нагрузки на сервер, а не как сетевую ошибку.
FAQ
Почему SSH выдает "Connection refused", хотя sshd запущен?
Потому что отказ исходит от сокета, а не от самого сервиса, и работающий sshd все равно может отклонить соединение. Откройте консоль провайдера и выполните sudo ss -tlnp. Сокет на 127.0.0.1:22 отклоняет всех удаленных клиентов, так как он привязан только к loopback. Сокет на другом порту отклоняет всех, кто по-прежнему использует 22 порт. Если используется systemd socket activation, порт берется из ssh.socket, а не из sshd_config, поэтому проверьте также systemctl is-enabled ssh.socket. Правило ufw reject также возвращает отказ от имени хоста, поэтому изучите sudo ufw status verbose, прежде чем делать выводы.
Почему SSH выдает таймаут, если ufw разрешает 22 порт?
Потому что таймаут означает, что ответ не был получен, а ufw — не единственный межсетевой экран на пути пакетов. Большинство панелей управления VPS используют сетевой экран перед инстансом, и операционная система никогда не видит то, что этот экран отбрасывает. Из консоли выполните sudo tcpdump -ni any tcp port 22 и попробуйте подключиться с ноутбука во время работы команды. Если пакеты не приходят, значит, блокировка происходит выше по сети, в панели управления. Если пакеты приходят, но ответ не уходит, значит, блокировка локальная, в ufw или nftables.
Означает ли неудачный ping, что мой VPS не работает?
Нет. Многие провайдеры фильтруют ICMP на границе сети, поэтому сервер, который нормально обрабатывает трафик, может игнорировать все ваши ping-запросы. Успешный ping также не является показателем, так как он ничего не говорит о том, открыт ли 22 порт. Проверьте сам порт с помощью nc -vz -w 5 203.0.113.10 22 с вашего компьютера или с помощью Test-NetConnection 203.0.113.10 -Port 22 в PowerShell на Windows.
Я изменил SSH-порт, и теперь ничего не подключается. Что пошло не так?
К этому приводят две причины, связанные с порядком действий. Если для нового порта не было добавлено правило в межсетевой экран, попытки подключения к новому порту будут приводить к таймауту, а к 22 порту — к отказу, поэтому sudo ufw allow 2222/tcp нужно выполнять до смены порта, а не после. Если система использует systemd socket activation для SSH, параметр Port 2222 в sshd_config игнорируется, и systemd продолжает удерживать старый порт, что можно подтвердить с помощью systemctl is-enabled ssh.socket. Восстановите доступ через консоль провайдера, исправьте соответствующую ошибку, а затем подключитесь с помощью ssh -p 2222 user@203.0.113.10, когда sudo ss -tlnp покажет, что новый сокет активен.