В блог

Причины ошибок подключения по SSH и способы их исправления

Причины ошибок подключения по SSH и способы их исправления

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

У каждой ошибки свои причины, поэтому начинать диагностику с изменения sshd_config или правил firewall не стоит. Например, исправление прав на authorized_keys не поможет, если клиент вообще не может установить TCP-соединение с сервером

OpenSSH позволяет определить, на каком этапе возникает проблема. Разберём наиболее распространённые ошибки подключения, способы их диагностики и безопасное применение изменений на сервере

С чего начать диагностику SSH

Первым делом проверьте параметры подключения. SSH может использовать не только аргументы командной строки, но и настройки из ~/.ssh/config⁠, включая другой адрес сервера, порт, приватный ключ или промежуточный сервер для подключения

Чтобы увидеть итоговую конфигурацию клиента, выполните

ssh -G -p 2222 user@server.example.com

В выводе обратите внимание на hostname⁠, user⁠, port⁠, identityfile⁠, proxyjump и proxycommand⁠. Если обычно подключаетесь через псевдоним из SSH-конфига, используйте его и для проверки. При прямом обращении по IP могут применяться другие настройки

Во всех примерах используется порт 2222⁠. Если SSH работает на стандартном порту, замените его на 22⁠. Имя пользователя, адрес сервера и пути к ключам также нужно подставить свои

Теперь попробуйте подключиться с подробным журналом

ssh -vvv -o ConnectTimeout=10 -p 2222 user@server.example.com

Параметр -vvv включает подробный вывод, по которому можно проследить установление соединения и аутентификацию

В первую очередь интересуют следующие сообщения

  • Connecting to – адрес и порт, к которым клиент пытается подключиться
  • Connection established – TCP-соединение с сервером установлено
  • Offering public key – клиент предлагает серверу публичный ключ
  • Authenticated to – сервер успешно выполнил аутентификацию

Если соединение прерывается до Connection established⁠, проверять нужно прежде всего сеть, адрес, порт и доступность SSH-сервера. Если TCP-соединение установлено, но вход не выполняется, причина может находиться в аутентификации или согласовании параметров SSH

Дальнейшие команды рассчитаны на OpenSSH и Linux-сервер с systemd. Команды ssh выполняются на клиенте, а действия с sshd⁠, firewall и серверными журналами – на самом сервере. Если SSH недоступен, понадобится консоль хостинг-провайдера или другой административный доступ

Сервер отклоняет соединение

Ошибка Connection refused означает, что попытка установить TCP-соединение получила отказ. Чаще всего это происходит, когда на указанном адресе и порту никто не слушает подключения. Однако отказ может возвращать и сетевой фильтр

Начните с проверки адреса и порта в выводе ssh -vvv⁠. Если они правильные, откройте консоль сервера и проверьте состояние OpenSSH

sudo systemctl status ssh.service
sudo ss -ltnp

Название службы зависит от дистрибутива. Вместо ssh.service может использоваться sshd.service

В выводе ss найдите порт SSH и посмотрите, на каких адресах он слушает. Если сервис привязан только к 127.0.0.1 или ::1⁠, подключения с других машин через этот сокет принимать он не сможет

Если OpenSSH-сервер не установлен, потребуется установить соответствующий пакет дистрибутива. Остановленную службу можно запустить и включить её автозапуск

sudo systemctl start ssh.service
sudo systemctl enable ssh.service

Но сначала убедитесь, что в системе не используется активация через systemd socket

Как работает ssh.socket

В некоторых дистрибутивах, включая современные версии Ubuntu, входящие подключения может принимать ssh.socket⁠. В таком режиме systemd слушает порт и запускает SSH-сервер по мере необходимости

Поэтому неактивный ssh.service сам по себе ещё не означает неисправность

Проверьте сокет

systemctl status ssh.socket
systemctl cat ssh.socket

В Ubuntu 24.04 параметры порта и адреса для socket activation могут формироваться из конфигурации sshd через systemd generator. В других версиях используются иные способы настройки

Поэтому при изменении порта важно проверить не только sshd_config⁠, но и фактический слушающий сокет. Особенности работы описаны в документации Ubuntu по socket activation

Проверка firewall

Если SSH слушает нужный порт, но подключение по-прежнему отклоняется, проверьте сетевые фильтры

Для сервера с UFW можно посмотреть действующие правила

sudo ufw status verbose

Если требуется разрешить доступ с конкретного административного IP-адреса, добавьте соответствующее правило

sudo ufw allow from 198.51.100.20 to any port 2222 proto tcp

Здесь 198.51.100.20 – адрес для примера. Вместо него укажите IP клиента, который видит сервер

Разрешить подключения со всех адресов можно командой sudo ufw allow 2222/tcp⁠, но делать это стоит только тогда, когда такой доступ действительно необходим

Проверьте также firewall хостинг-провайдера. Даже если UFW разрешает подключения, внешний сетевой фильтр может блокировать порт

Сервер не отвечает вовремя

При Connection timed out клиент не получает ожидаемого ответа за отведённое время

Если ошибка появляется до установления TCP-соединения, возможны проблемы с маршрутизацией, неправильный IP-адрес, недоступность сервера или firewall, который отбрасывает пакеты без ответа

В отличие от Connection refused⁠, при тайм-ауте клиент не получает явного отказа. Поэтому по одной ошибке нельзя определить, на каком именно участке сети теряются пакеты

Сначала проверьте через панель хостинг-провайдера, работает ли сервер и какой IP-адрес ему назначен. Затем сравните этот адрес с тем, который использует SSH-клиент

Если адрес правильный, проверьте входящие правила firewall на сервере и у провайдера. На стороне клиента убедитесь, что сеть или VPN разрешает подключения к нужному адресу и порту

Если доменное имя имеет записи IPv4 и IPv6, попробуйте подключиться отдельно по каждому протоколу

ssh -4 -p 2222 user@server.example.com
ssh -6 -p 2222 user@server.example.com

Разница между результатами поможет определить, с каким семейством адресов связана проблема

Успешный ping не гарантирует доступности SSH. ICMP и TCP обрабатываются разными правилами firewall, поэтому сервер может отвечать на ICMP, но блокировать подключения к порту SSH

Если в журнале уже появилось Connection established⁠, TCP-соединение было установлено. В таком случае тайм-аут может относиться к начальному согласованию SSH и обмену ключами. Проверьте последующие сообщения клиента и журнал службы на сервере

Параметр ConnectTimeout ограничивает ожидание соединения и начального SSH-согласования, но не продолжительность уже открытой рабочей сессии. Подробнее это описано в документации OpenSSH

Сервер отклоняет учётные данные

Ошибка Permission denied появляется, когда сервер отклоняет попытку аутентификации

Это означает, что клиент уже смог связаться с SSH-сервером. Поэтому искать проблему в маршрутизации или открывать дополнительные порты обычно не требуется

При входе по ключу сначала проверьте имя пользователя и явно укажите приватный ключ, который должен использоваться для этой учётной записи

ssh -vvv -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 -p 2222 user@server.example.com

Параметр -i задаёт файл приватного ключа, а IdentitiesOnly=yes ограничивает аутентификацию явно настроенными ключами и предотвращает предложение произвольных дополнительных ключей из SSH-агента

В подробном журнале посмотрите, какой ключ предлагает клиент и как на него отвечает сервер

Запрос Enter passphrase for key означает, что клиент просит пароль для расшифровки локального приватного ключа. Это не пароль от учётной записи на сервере

А список методов после Permission denied⁠, например (publickey,password)⁠, показывает доступные способы аутентификации. Он не объясняет, почему конкретный ключ был отклонён

Проверка authorized_keys

При обычной настройке аутентификации по ключу сервер ищет разрешённые публичные ключи в ~/.ssh/authorized_keys соответствующего пользователя

Проверьте, что публичный ключ действительно находится в файле нужной учётной записи. Один ключ должен занимать одну строку

Затем проверьте владельцев и права доступа. Следующие команды выполняются на сервере под пользователем, в учётную запись которого требуется войти

ls -ld ~ ~/.ssh
ls -l ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Каталог .ssh обычно должен принадлежать владельцу учётной записи, а файл authorized_keys не должен быть доступен для изменения посторонним пользователям. Для них подходят права 700 и 600 соответственно

Также проверьте владельца домашнего каталога и его доступность для записи другими пользователями. Если OpenSSH обнаружит небезопасные права, он может отказаться использовать файл ключей

За такую проверку отвечает StrictModes⁠. Отключать её ради устранения ошибки не нужно

Если ключ присутствует и права корректны, проверьте журнал SSH-сервера

sudo journalctl -u ssh.service -n 100 --no-pager

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

Например, AuthorizedKeysFile меняет путь к файлу, а AuthorizedKeysCommand позволяет получать ключи через внешнюю команду. При использовании сертификатов SSH правила проверки также отличаются от обычного authorized_keys

Итоговые настройки сервера можно проверить через sshd -T -C⁠. Порядок такой проверки приведён в конце статьи, а параметры описаны в руководстве sshd_config

Слишком много попыток входа

Ошибка Too many authentication failures не обязательно означает, что пользователь многократно вводил неправильный пароль

При подключении SSH-агент может последовательно предлагать серверу несколько ключей. Если подходящий ключ находится в конце списка, сервер способен завершить аутентификацию раньше, чем клиент до него доберётся

Количество допустимых неудачных попыток определяется в том числе настройкой MaxAuthTries на сервере

Посмотрите, какие ключи загружены в агент

ssh-add -l

Затем повторите подключение с нужным ключом и IdentitiesOnly=yes

ssh -vvv -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 -p 2222 user@server.example.com

Если проблема исчезла, проверьте записи IdentityFile в клиентском SSH-конфиге. Там могут быть указаны несколько ключей, которые OpenSSH предлагает последовательно

Команда ssh -G покажет применяемые настройки, а ssh -vvv – какие ключи действительно отправляются серверу

Подробнее поведение IdentitiesOnly описано в документации OpenSSH

Права доступа к приватному ключу

Сообщение UNPROTECTED PRIVATE KEY FILE относится к правам доступа к приватному ключу на стороне клиента. Если файл могут читать посторонние пользователи, клиент может отказаться его использовать

Например, такое случается после копирования ключа с другого компьютера, когда у файла остаются права 0644

Проверьте файл и ограничьте доступ к нему

ls -l ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519

Убедитесь, что ключ принадлежит вашему пользователю и именно этот файл указан в -i или IdentityFile

Исправлять права публичного ключа с расширением .pub для устранения этой ошибки не требуется. OpenSSH проверяет доступ именно к приватному ключу

На Windows права управляются через ACL, поэтому команды chmod для такого окружения не подходят

Не удаётся определить адрес

Если SSH сообщает Could not resolve hostname⁠, клиент не смог преобразовать имя сервера в IP-адрес

Сначала проверьте, нет ли ошибки в имени. Затем посмотрите итоговое значение hostname через ssh -G⁠, поскольку конфигурация может подставлять другой адрес вместо указанного псевдонима

На Linux проверить разрешение имени можно командой

getent ahosts server.example.com

Если имя существует только во внутренней DNS-зоне организации, убедитесь, что клиент подключён к соответствующей сети или VPN и использует нужный DNS-сервер

При известном IP-адресе можно временно проверить SSH-подключение напрямую. Но учитывайте, что при замене доменного имени на IP могут перестать применяться настройки соответствующего блока Host

Кроме того, клиент будет проверять ключ сервера для нового адреса. Не отключайте эту проверку ради диагностики – при необходимости подтвердите отпечаток ключа через доверенный канал

Сервер недоступен по сети

Ошибка No route to host возникает, когда клиент не может доставить трафик до нужного адреса или получает сетевое сообщение о его недоступности

На Linux посмотрите, какой маршрут система выбирает для подключения

ip route get 192.0.2.10

Вместо 192.0.2.10 укажите IP-адрес сервера

Команда покажет, через какой интерфейс и шлюз должны отправляться пакеты. Если сервер находится во внутренней сети, проверьте подключение к VPN и наличие соответствующего маршрута

Даже правильный маршрут не гарантирует доступности сервера. Ошибка может возникнуть из-за недоступного следующего узла, проблем с соседним устройством или сетевого фильтра, который возвращает сообщение о недоступности

Если подключаетесь к виртуальной машине, дополнительно проверьте её виртуальный интерфейс, мост и VLAN. Например, при использовании Open vSwitch неправильный VLAN на порту гостя или внешнем trunk может полностью нарушить связь. Конфигурация такой сети разобрана в статье о подключении KVM к Open vSwitch

Согласование алгоритмов SSH

До аутентификации клиент и сервер должны согласовать криптографические алгоритмы. Если подходящего варианта нет, соединение прерывается с сообщением об ошибке

Например

no matching host key type found
no matching key exchange method found

После Their offer OpenSSH обычно показывает алгоритмы, предлагаемые другой стороной

Это помогает определить, что именно не совпало. В первом случае проблема касается допустимых алгоритмов ключа сервера, во втором – алгоритмов обмена ключами

Посмотреть алгоритмы обмена ключами, которые поддерживает установленный клиент, можно через

ssh -Q kex

А фактически применяемые настройки – через ssh -G

Следует различать поддержку алгоритма программой и разрешение на его использование. OpenSSH может поддерживать старый алгоритм, но не включать его в настройках по умолчанию из-за известных ограничений безопасности

Предпочтительное решение – обновить серверное ПО или прошивку устройства, чтобы обе стороны могли использовать современные алгоритмы

Если обновление пока невозможно, OpenSSH допускает временное разрешение устаревшего алгоритма для конкретного узла. Для этого используются HostKeyAlgorithms и KexAlgorithms в зависимости от типа ошибки

Изменился ключ SSH-сервера

Предупреждение REMOTE HOST IDENTIFICATION HAS CHANGED возникает, когда сервер предъявляет ключ, который не совпадает с ранее сохранённым в known_hosts

Такое возможно после переустановки ОС, пересоздания виртуальной машины или изменения конфигурации SSH. Но аналогичная ошибка может появиться и при попытке подмены сервера

Сначала нужно подтвердить новый ключ через доверенный канал. Например, откройте консоль сервера у провайдера и получите отпечаток его публичного ключа Ed25519

sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Сравните полученный отпечаток с тем, который предъявляет SSH-клиент. Сравнивать нужно ключи одного типа, иначе результаты будут различаться даже для одного сервера

Если новый ключ подтверждён, удалите устаревшую запись на клиенте

ssh-keygen -R '[server.example.com]:2222'

Для стандартного порта 22 команда выглядит проще

ssh-keygen -R server.example.com

Если SSH использует другой файл известных узлов, укажите его через параметр -f

При следующем подключении повторно проверьте отпечаток перед сохранением нового ключа. Если используется StrictHostKeyChecking=yes⁠, подтверждённый ключ нужно заранее добавить в соответствующий файл

Отключать проверку ключей через StrictHostKeyChecking=no ради устранения ошибки не следует. Эта проверка защищает от подключения к подменённому серверу. Параметры управления known_hosts описаны в руководстве ssh-keygen

Как менять настройки SSH

Диагностика иногда приводит к необходимости изменить sshd_config⁠, правила аутентификации или порт SSH. Ошибка в таких настройках может полностью лишить удалённого доступа к серверу

Прежде чем применять изменения, проверьте конфигурацию SSH-сервера

sudo sshd -t

Команда проверяет корректность конфигурации и ключей сервера. При успешном завершении она возвращает код 0 без вывода

Но синтаксическая проверка ещё не означает, что конкретному пользователю будет разрешён вход

Для анализа итоговых параметров, включая правила Match⁠, используйте расширенную проверку

sudo sshd -T -C user=user,addr=198.51.100.20,host=client.example.com,laddr=192.0.2.10,lport=2222

Подставьте реальные параметры подключения. В user указывается учётная запись на сервере, в addr – видимый серверу IP-адрес клиента, а в host – имя клиентского узла. laddr и lport обозначают локальный адрес и порт SSH-сервера

В выводе можно проверить параметры pubkeyauthentication⁠, authorizedkeysfile⁠, allowusers⁠, denyusers и другие ограничения. Для подключения под root важен также permitrootlogin

Если демон использует нестандартный конфигурационный файл через -f⁠, укажите его и в командах проверки

Проверяя sshd_config⁠, учитывайте порядок применения настроек. Для большинства параметров OpenSSH использует первое найденное значение. Кроме того, через Include могут подключаться файлы из sshd_config.d⁠, а блоки Match изменяют настройки для определённых подключений

Поэтому строка, добавленная в конец файла, не обязательно переопределит прежнее значение. Проверить действующие параметры надёжнее через sshd -T -C⁠, чем только по содержимому конфигурационных файлов

После успешной проверки обычные изменения конфигурации можно применить без полного перезапуска службы

sudo systemctl reload ssh.service

Для sshd.service используйте соответствующее имя службы. Если менялся порт или адрес при socket activation, отдельно проверьте конфигурацию ssh.socket и примените изменение согласно правилам своего дистрибутива

Теперь откройте второй терминал и попробуйте подключиться заново

ssh -o ControlPath=none -p 2222 user@server.example.com

Параметр ControlPath=none предотвращает использование существующего общего SSH-соединения, чтобы проверка действительно установила новое подключение

Если вход работает, проверьте нужный способ аутентификации и только после этого закрывайте старую сессию

Если подключиться не удалось, восстановите прежнюю конфигурацию через оставленное соединение или консоль провайдера. Затем повторно выполните sshd -t и примените настройки

При изменении порта заранее разрешите его в firewall и проверьте фактическое состояние слушающего сокета через ss -ltnp⁠. Иначе даже правильно настроенный SSH-сервер может остаться недоступным извне

Текст ошибки и подробный журнал OpenSSH обычно позволяют быстро сузить область поиска. Главное – определить, на каком этапе прерывается соединение, и проверять соответствующие компоненты, не изменяя остальные настройки без необходимости

Поможем разобраться с доступом к серверу

Если SSH по-прежнему не подключается, можно поручить диагностику нам. Проверим настройки доступа, авторизацию и сетевое соединение, поможем устранить причину сбоя

Обсудить проблему DevOps и техническая поддержка