sshd: error: Protocol major versions differ: 2 vs. 1
Обмен приветствиями — первое, что происходит в соединении: стороны называют версию протокола до всякой проверки подлинности. Это сообщение означает, что собеседник прислал именно приветствие ssh, но версии первой, которой в современном OpenSSH нет вовсе. Отличайте его от жалобы на неверный вид приветствия: там пришли байты, на приветствие не похожие, — обычно проверка порта или чужой протокол.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Порт перебирает сканер старым клиентом
Массовые проверки портов до сих пор представляются первой версией протокола. Соединение обрывается до проверки подлинности, и ничего опасного в самом сообщении нет.
-
Старое устройство умеет только первую версию
Встроенные клиенты в сетевом оборудовании и промышленных контроллерах иногда так и остались на первой версии. Вернуть её на сервере нельзя: настройки выбора версии протокола в нынешнем OpenSSH больше нет.
-
Обращение уходит не на тот порт
Проброс порта или запись балансировщика может вести на устройство, которое здоровается первой версией. Со стороны клиента это выглядит как поломка вашего сервера.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Сколько раз за сутки собеседник представлялся первой версией протокола.
journalctl -u ssh -u sshd --since "-1 day" --no-pager | grep -cE "Protocol major versions differ"Две разные беды рядом: «could not read protocol version» — ssh первой версии, «invalid format» — вообще не ssh.
journalctl -u ssh -u sshd --no-pager | grep -E "banner exchange" | tail -5Воспроизвести на месте: сервер отвечает своим приветствием и закрывает соединение, а в журнале появляется та же запись.
printf 'SSH-1.5-test\r\n' | timeout 5 nc 127.0.0.1 22Версия OpenSSH и число настроек выбора версии протокола: ноль означает, что первой версии тут нет и не будет.
ssh -V; sshd -T 2>/dev/null | grep -ci protocolРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Массовые проверки портов до сих пор представляются первой версией протокола. Соединение обрывается до проверки подлинности, и ничего опасного в самом сообщении нет.
- Как проверить
-
Посмотрите, сколько таких попыток и откуда.
journalctl -u ssh -u sshd --since "-1 day" --no-pager 2>/dev/null | grep -E "Protocol major versions differ" | wc -l
- Как исправить
- Чинить нечего: сервер отвечает правильно. Если записи мешают читать журнал, закройте порт списком адресов или перенесите его; блокировка по числу неудачных попыток сократит и остальной перебор.
- Почему происходит
- Встроенные клиенты в сетевом оборудовании и промышленных контроллерах иногда так и остались на первой версии. Вернуть её на сервере нельзя: настройки выбора версии протокола в нынешнем OpenSSH больше нет.
- Как проверить
-
Посмотрите, что за собеседник обращается, и чем отвечает ваш сервер.
journalctl -u ssh -u sshd --since "-1 day" --no-pager 2>/dev/null | grep -B1 "Protocol major versions differ" | tail -6 sshd -T 2>/dev/null | grep -ci protocol
- Как исправить
- Обновите клиента на устройстве. Если обновления нет, поставьте отдельный переходник рядом с устройством и не понижайте протокол на сервере, куда ходят все остальные.
- Почему происходит
- Проброс порта или запись балансировщика может вести на устройство, которое здоровается первой версией. Со стороны клиента это выглядит как поломка вашего сервера.
- Как проверить
-
Посмотрите, чьё приветствие приходит на самом деле.
timeout 5 nc сервер 22 </dev/null | head -1 ssh -v сервер 2>&1 | grep -i "remote protocol version" | head -2
- Как исправить
- Сверьте приветствие с версией своего сервера и поправьте проброс: несовпадение имени в приветствии сразу показывает, к какой машине вы попали.
Пример вывода
Клиент представился протоколом первой версии. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
$ printf 'SSH-1.5-test\r\n' | nc 127.0.0.1 22
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.19
Protocol major versions differ.
sshd[270092]: error: Protocol major versions differ: 2 vs. 1
sshd[270092]: banner exchange: Connection from 198.51.100.7 port 57954: could not read protocol version
Связанные ошибки
- kex_exchange_identification: Connection closed by remote host Соединение по ssh обрывается до запроса пароля: обрыв на обмене версиями. Разбор со стороны клиента и сервера.
- sshd: отказ в подключении из-за MaxStartups Часть подключений отклоняется под нагрузкой: предел незавершённых аутентификаций. Как считать значение.
- sshd: Bad configuration option и отказ запуска sshd не запускается из-за ошибки в sshd_config: неизвестный параметр, устаревшая настройка, ошибка в include.
- Connection closed by authenticating user: вход обрывается Клиент отключается на этапе проверки подлинности: не тот ключ, перебор или ограничение по адресу.
- Вход по доменной учётной записи не проходит: служба в автономном режиме Доменные пользователи не могут войти: служба не видит каталог и перешла в автономный режим.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Automount: каталог монтируется не вовремя или отваливается Автомонтирование через .automount: как работает TimeoutIdleSec, почему ресурс отваливается и когда лучше обычный .mount.
- Broken pipe в журнале службы Запись в закрытый канал или соединение: клиент отключился, обработчик завершился, конвейер разорван.
Где встречается чаще всего
Источники
-
sshd(8)
Обмен приветствиями с указанием версии протокола в начале соединения. -
Проверено на этой машине: systemd 255 (255.4-1ubuntu8.17), Ubuntu 24.04
Воспроизведено на этой машине, OpenSSH 9.6p1: приветствие «SSH-1.5-test» даёт в журнале «error: Protocol major versions differ: 2 vs. 1» и «banner exchange: … could not read protocol version», а произвольные байты — «banner exchange: … invalid format». Настроек выбора версии протокола у sshd не осталось: `sshd -T | grep -ci protocol` даёт 0.