Выберите продукт

SSH зависает на Connecting и banner exchange: диагностика MTU, DNS, GSSAPI и KEX

Если SSH зависает на Connecting или banner exchange, причина обычно в конкретном шаге: проблемы TCP/фильтрации, MTU/PMTUD, задержки reverse DNS, попытки GSSAPI или несовместимые KEX-алгоритмы. Разберём ssh -vvv, подтвердим поведение tcpdump и дадим точечные правки клиента и sshd.
SSH зависает на Connecting и banner exchange: диагностика MTU, DNS, GSSAPI и KEX

Ситуация из практики: вы запускаете ssh user@host, видите Connecting to ..., потом тишина. Или подключение доходит до banner exchange, после чего зависает на десятки секунд или навсегда. Для админа это особенно неприятно: ping есть, порт 22 «вроде» открыт, но в интерактивную сессию не попасть.

Ниже — пошаговая диагностика «без магии»: где именно может подвиснуть SSH, как это подтвердить, и что править. Разберём четыре частых источника: MTU/PMTUD, прямой/обратный DNS, GSSAPI (Kerberos/SSPI) и обмен ключами KEX. В конце — мини-чеклист.

Где именно «виснет» SSH: Connecting, banner exchange и KEX

SSH-подключение состоит из нескольких этапов. Условно:

  • TCP-соединение (SYN/SYN-ACK/ACK) до порта 22.
  • Обмен «баннерами» — строками вида SSH-2.0-OpenSSH_... (на стороне клиента это часто видно как banner exchange).
  • Согласование алгоритмов: KEX, шифры, MAC, ключи хоста.
  • Аутентификация (ключ/пароль/2FA).
  • Открытие канала/PTY и запуск shell.

Если зависание на Connecting, чаще всего проблема на уровне TCP: маршрутизация, firewall, NAT, асимметрия. Реже — MTU/MSS, когда TCP «поднимается», но большие сегменты не проходят и кажется, что «зависло ещё на подключении».

Если видно banner exchange, то TCP уже установлен, но обмен первыми данными протокола идёт с задержкой или не идёт вообще. Это важная развилка: «порт закрыт» тут уже не подходит как объяснение.

Базовая диагностика: ssh -vvv и ключевые строки

Начинайте с максимальной детализации клиента:

ssh -vvv user@host

Дальше ищите «якоря»:

  • Connecting to ... port 22. — клиент пошёл в TCP.
  • Connection established. — TCP поднялся.
  • Local version string ... и Remote protocol version ... — баннеры обменялись.
  • kex: algorithm: ... — начался этап KEX.

Частая картина: Connection established уже есть, но дальше тишина. Это почти всегда означает, что что-то мешает первому обмену данными (MTU blackhole, фильтрация на пути, DNS на сервере, ожидание GSSAPI на клиенте, конфликт алгоритмов).

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Если у вас это прод-сервер и вы регулярно упираетесь в «непонятные сетевые глюки», на практике помогает вынести сервис на стабильную площадку: например, держать админские узлы и bastion на VDS с предсказуемой сетевой конфигурацией, чтобы исключить влияние локального «зоопарка» NAT/VPN.

Пример вывода ssh -vvv с зависанием после Connection established

Проверка TCP на практике: tcpdump, ss и быстрый «пробой» порта

Когда ssh -vvv не даёт однозначного ответа, подключайте tcpdump. Задача простая: понять, есть ли после TCP-рукопожатия обмен данными в обе стороны и на каком месте всё останавливается.

На клиенте или на сервере (где есть права):

sudo tcpdump -ni any 'tcp port 22'

Если сервер конкретный, удобнее сузить фильтр:

sudo tcpdump -ni any 'host SERVER_IP and tcp port 22'

Что обычно видно по паттернам:

  • SYN уходит, SYN-ACK не приходит — маршрутизация/файрвол/группы безопасности.
  • SYN/SYN-ACK/ACK есть, дальше клиент шлёт данные, а ответа нет — проблема на сервере или по пути (фильтрация, MTU blackhole, перегруз, лимиты).
  • Пакеты ходят в обе стороны, но задержки большие — часто DNS/GSSAPI/таймауты, иногда KEX и криптополитики.

Параллельно проверьте, что на сервере вообще слушается порт 22:

sudo ss -lntp | grep ':22 '

И что до порта можно достучаться как до TCP (без протокола SSH):

nc -vz host 22

MTU и PMTUD: когда SSH «висит», потому что пакеты не проходят

MTU/PMTUD — одна из самых коварных причин: TCP-соединение устанавливается, но часть пакетов (обычно крупнее) не проходит. Классический сценарий — где-то по пути блокируется ICMP «Fragmentation needed» (IPv4) или ICMPv6 Packet Too Big (IPv6). В итоге возникает MTU blackhole: связь «наполовину работает», а SSH зависает на ранних этапах (вплоть до banner exchange или во время KEX).

Быстрая проверка MTU до узла (IPv4)

Проверьте pmtu через ping с запретом фрагментации. Начинайте с безопасного размера и увеличивайте:

ping -M do -s 1200 host
ping -M do -s 1400 host

Если на каком-то размере появляется «message too long» или потери — реальный MTU на пути ниже. Часто виноваты VPN, GRE, PPPoE, оверлейные сети, «туннели поверх туннелей».

Что делать, если подозрение на MTU подтвердилось

  • Правильно выставить MTU на интерфейсе/туннеле там, где добавляется оверхед (лучший вариант, если вы контролируете участок).
  • Проверить, не блокируются ли нужные ICMP-сообщения на firewall/маршрутизаторе. Полное «запрещаем весь ICMP» — частая причина проблем с PMTUD.
  • Как временная мера: зажать MSS на пограничном устройстве, чтобы TCP не пытался отправлять сегменты, которые не пролезают. Это костыль, но иногда спасает быстро.

На хосте полезно посмотреть текущий MTU по интерфейсам:

ip link show

Если вы подключаетесь к серверу через туннель или overlay, проверяйте MTU именно на логическом интерфейсе туннеля, а не только на eth0.

Если SSH «висит» только из некоторых сетей (например, из офиса через VPN), а из мобильного интернета работает — MTU/PMTUD почти всегда нужно проверить одним из первых пунктов.

DNS и reverse DNS: задержки перед логином и зависания на ранних шагах

Следующий частый сценарий: TCP поднялся, но сервер перед тем как продолжить, пытается сделать reverse lookup IP клиента (PTR). Если у сервера проблемы с резолвером или обратная зона клиента «медленная», SSH-сессия может «стоять» до таймаута DNS — визуально это выглядит как зависание на banner exchange или «после Connection established».

Как проверить, что задержка из-за DNS

На сервере посмотрите последние записи сервиса SSH:

sudo journalctl -u ssh -n 200 --no-pager

Или, если логирование идёт в файл:

sudo tail -n 200 /var/log/auth.log

Затем проверьте, насколько быстро отрабатывает системный резолвер через NSS:

getent hosts CLIENT_IP
getent hosts client-hostname.example

Если getent «думает» заметно долго — проблема на сервере: /etc/resolv.conf, недоступный корпоративный DNS, сломанный маршрут до резолвера, долгие таймауты.

Тактическое решение на SSH-сервере

Если подтверждено, что тормозит именно reverse DNS, а приоритет — быстрый вход:

  • Проверьте параметр UseDNS в /etc/ssh/sshd_config. При UseDNS no сервер не будет делать reverse lookup ради проверки имени.

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

sudo sshd -t
sudo systemctl reload ssh

Если reverse DNS важен по регламентам, правильнее починить PTR-запись и резолвер, а не отключать проверки. В доменных сценариях полезно держать аккуратную DNS-обвязку: при необходимости посмотрите также материал про трансфер домена и настройку DNS.

FastFox VDS
Регистрация доменов от 99 руб.
Каждый проект заслуживает идеального доменного имени, выберите один из сотни, чтобы начать работу!

Если вы как раз приводите в порядок зону и PTR-записи под инфраструктуру, удобнее сразу закрыть вопрос с доменами через регистрацию доменов, чтобы управлять DNS централизованно.

Проверка MTU и PMTUD командой ping с запретом фрагментации

GSSAPI: «зависание», которое на самом деле попытка Kerberos

На некоторых системах (корпоративные Linux/Unix, macOS, окружения с Kerberos) SSH-клиент по умолчанию может пробовать GSSAPI-аутентификацию. Если KDC недоступен, DNS для realm не резолвится или сеть до него закрыта, вы получите длинные паузы, хотя с сетью до сервера «всё нормально».

Как увидеть GSSAPI в ssh -vvv

В логе будут строки про gssapi-with-mic, попытки получить креды и ожидания/откаты.

Быстро отключить для проверки

Одной командой (диагностически):

ssh -o GSSAPIAuthentication=no -o GSSAPIDelegateCredentials=no user@host

Если после этого подключение стало мгновенным — причина найдена.

Чтобы применить постоянно для конкретного хоста, добавьте в ~/.ssh/config (как текст):

Host my-host
  GSSAPIAuthentication no
  GSSAPIDelegateCredentials no

Иногда GSSAPI включён и на сервере (PAM/sshd), но на практике «залипает» чаще именно клиент, пытаясь аутентифицироваться «красиво», пока не сдастся.

KEX и несовместимые алгоритмы: зависание или обрыв на этапе обмена ключами

Этап KEX (key exchange) — место, где согласуются алгоритмы обмена ключами и криптонабор. Если клиент и сервер сильно разъехались по версиям или политикам, соединение может зависать, обрываться или «тупить» на повторах.

Типовые причины проблем с KEX

  • Сервер ограничил набор KEX/шифров в sshd_config, а клиент старый и не умеет современные алгоритмы.
  • Клиент новый, а сервер очень старый (или наоборот) и пересечения по алгоритмам почти нет.
  • Сеть нестабильна и «ломает» обмен, что особенно заметно во время KEX (включая влияние MTU).

Как посмотреть, что умеет клиент

ssh -Q kex
ssh -Q cipher
ssh -Q mac

Если в ssh -vvv видно несовпадение, можно временно явно указать совместимый набор (пример, подбирайте под ваш случай):

ssh -o KexAlgorithms=curve25519-sha256 -o Ciphers=chacha20-poly1305@openssh.com user@host

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

Ещё 5 причин, которые маскируются под banner exchange

Если MTU, reverse DNS, GSSAPI и KEX не подтвердились, проверьте типовые «подвисания» из практики:

  1. iptables/nftables «разрешает SYN, но режет дальше». Бывает из-за неверных state rules. Проверьте счётчики правил и логи дропов.

  2. Fail2ban/sshguard и лимиты. Соединение принимается, но дальше — задержки/дропы. Проверьте бан-листы и параметр MaxStartups на сервере.

  3. Нагрузка по CPU/RAM на сервере. sshd может не отвечать быстро, особенно на маленьких инстансах под нагрузкой. Проверьте top, vmstat, journalctl.

  4. Сломанный resolver на сервере. Даже без reverse DNS, некоторые этапы PAM/логирования могут ходить в DNS/LDAP и ждать таймауты.

  5. Проблемы с IPv6. Клиент сначала пытается AAAA, маршрут частично не работает, получаются странные таймауты. Для проверки принудительно IPv4: ssh -4 user@host.

Мини-чеклист: как быстро локализовать зависание SSH

  1. Соберите фактологию: ssh -vvv и последняя строка перед зависанием.

  2. Подтвердите TCP: nc -vz host 22, затем tcpdump на клиенте/сервере.

  3. Проверьте MTU/PMTUD: ping -M do -s ... (IPv4) и ICMP-фильтрацию на пути.

  4. Проверьте DNS на сервере: getent hosts CLIENT_IP, при необходимости настройку UseDNS.

  5. Исключите GSSAPI: ssh -o GSSAPIAuthentication=no ....

  6. Если зависание на kex:, сверьте алгоритмы ssh -Q и политики сервера.

Заключение

Когда SSH зависает на Connecting или на этапе banner exchange, самая дорогая ошибка — чинить «всё подряд». Гораздо быстрее: зафиксировать этап по ssh -vvv, подтвердить поведение пакетами через tcpdump, затем точечно проверить четыре самых частых источника: MTU/PMTUD, reverse DNS, GSSAPI, KEX. Обычно один из них даёт чёткий воспроизводимый симптом и понятное действие.

Если вы хотите ускорить диагностику, зафиксируйте последнюю строку из ssh -vvv и уточните, откуда идёт подключение (домашняя сеть, офисный VPN, мобильный интернет). По этому обычно сразу понятно, в какую ветку проверки идти первой.

Поделиться статьей

Вам будет интересно

TLS 1.3 и HTTP/2: что видно в ClientHello/ServerHello и как разбирать ошибки рукопожатия OpenAI Статья написана AI (GPT 5)

TLS 1.3 и HTTP/2: что видно в ClientHello/ServerHello и как разбирать ошибки рукопожатия

Практический разбор TLS 1.3 на уровне ClientHello/ServerHello: где увидеть SNI и ALPN, как сервер выбирает HTTP/2, почему возникае ...
Apache mod_remoteip: real IP клиента за reverse proxy без поломки логов OpenAI Статья написана AI (GPT 5)

Apache mod_remoteip: real IP клиента за reverse proxy без поломки логов

Когда Apache работает за reverse proxy, в логах и REMOTE_ADDR часто виден IP прокси, а не клиента. Разберём mod_remoteip: какой Re ...
Git bisect: как найти «плохой» коммит и быстро остановить regression OpenAI Статья написана AI (GPT 5)

Git bisect: как найти «плохой» коммит и быстро остановить regression

Регрессия в проекте — это часы на угадывание «кто сломал». Git bisect делает бинарный поиск по истории и находит bad commit за 8–1 ...