Вопрос или проблема
Я настроил SSH-сервер онлайн, который доступен публично для всех. Поэтому, я получаю много соединений от IP-адресов со всего мира. Странно, но никто на самом деле не пытается аутентифицироваться для открытия сессии. Я сам могу подключиться и пройти аутентификацию без каких-либо проблем.
Время от времени я получаю error: kex_exchange_identification: Connection closed by remote host
в логах сервера. Что это вызывает?
Вот 30 минут логов SSH (публичные IP-адреса были скрыты):
# journalctl SYSLOG_IDENTIFIER=sshd -S "03:30:00" -U "04:00:00"
-- Логи начинаются в Пт 2020-01-31 09:26:25 UTC, заканчиваются Пн 2020-04-20 08:01:15 UTC. --
20 апр 03:39:48 myhostname sshd[18438]: Подключение от x.x.x.207 порт 39332 на 10.0.0.11 порт 22 rdomain ""
20 апр 03:39:48 myhostname sshd[18439]: Подключение от x.x.x.207 порт 39334 на 10.0.0.11 порт 22 rdomain ""
20 апр 03:39:48 myhostname sshd[18438]: Подключение закрыто x.x.x.207 порт 39332 [preauth]
20 апр 03:39:48 myhostname sshd[18439]: Подключение закрыто x.x.x.207 порт 39334 [preauth]
20 апр 03:59:36 myhostname sshd[22186]: Подключение от x.x.x.83 порт 34876 на 10.0.0.11 порт 22 rdomain ""
20 апр 03:59:36 myhostname sshd[22186]: error: kex_exchange_identification: Connection closed by remote host
И вот моя конфигурация SSH:
# ssh -V
OpenSSH_8.2p1, OpenSSL 1.1.1d 10 Сен 2019
# cat /etc/ssh/sshd_config
UsePAM yes
AddressFamily any
Port 22
X11Forwarding no
PermitRootLogin prohibit-password
GatewayPorts no
PasswordAuthentication no
ChallengeResponseAuthentication no
PrintMotd no # обработано pam_motd
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 /etc/ssh/authorized_keys.d/%u
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]
LogLevel VERBOSE
UseDNS no
AllowUsers root
AuthenticationMethods publickey
MaxStartups 3:100:60
После поиска в интернете, я видел упоминания о MaxStartups
, указывающие на то, что это может быть причиной этой ошибки, но после изменения значения по умолчанию, как показано в моем sshd_config
, и попытке более 3 соединений, сервер однозначно указывает на проблему
20 апр 07:26:59 myhostname sshd[31468]: отключение соединения #3 от [x.x.x.226]:54986 на [10.0.0.11]:22 после MaxStartups
Итак, что вызывает error: kex_exchange_identification: Connection closed by remote host
?
Странно, но никто на самом деле не пытается аутентифицироваться для открытия сессии.
Некоторые пауки и службы, такие как Shodan, сканируют публичные ipv4 адреса для обнаружения открытых сервисов, например, salt masters, ftp-серверов, RDP и также SSH-сервисов. Эти пауки обычно только подключаются к серверам, не выполняя никаких действительных шагов аутентификации.
Я получаю ошибку:
kex_exchange_identification
: Connection closed by remote host в логах сервера. Что это вызывает?
Я не нашел убедительных ответов на это, поэтому… пора просмотреть исходный код.
В исходном коде OpenSSH, kex_exchange_identification
– это функция для обмена идентификацией сервера и клиента (ну да), и указанная ошибка происходит, если сокетное соединение между сервером OpenSSH и клиентом прерывается (см EPIPE
), т.е. клиент уже закрыл свое соединение.
У меня была точно такая же проблема, и причиной было то, что у меня происходила портовая трансляция внутри балансировщика нагрузки, из-за чего мои ssh
соединения достигали хоста на порту 80
вместо порта 22
.
Хост правильно завершал соединения, и ошибка, возвращенная в мой терминал, была следующей;
~/Documents/Projects$ ssh -vvvvA [email protected]
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Чтение конфигурационных данных /Users/dave/.ssh/config
debug1: Чтение конфигурационных данных /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config строка 47: Применение параметров для *
debug2: resolve_canonicalize: hostname xx.xx.xx.250 is address
debug2: ssh_connect_direct
debug1: Подключение к xx.xx.xx.250 [xx.xx.xx.250] порт 22.
debug1: Соединение установлено.
debug1: файл идентификатора /Users/dave/.ssh/id_rsa тип 0
debug1: файл идентификатора /Users/dave/.ssh/id_rsa-cert тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_dsa тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_dsa-cert тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_ecdsa тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_ecdsa-cert тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_ed25519 тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_ed25519-cert тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_xmss тип -1
debug1: файл идентификатора /Users/dave/.ssh/id_xmss-cert тип -1
debug1: Локальная версия строки SSH-2.0-OpenSSH_8.1
debug1: kex_exchange_identification: строка баннера 0: HTTP/1.1 400 Bad Request
debug1: kex_exchange_identification: строка баннера 1: Сервер: nginx/1.14.0 (Ubuntu)
debug1: kex_exchange_identification: строка баннера 2: Дата: Пт, 20 Ноя 2020 09:30:23 GMT
debug1: kex_exchange_identification: строка баннера 3: Тип содержимого: text/html
debug1: kex_exchange_identification: строка баннера 4: Длина содержимого: 182
debug1: kex_exchange_identification: строка баннера 5: Соединение: close
debug1: kex_exchange_identification: строка баннера 6:
debug1: kex_exchange_identification: строка баннера 7: <html>
debug1: kex_exchange_identification: строка баннера 8: <head><title>400 Bad Request</title></head>
debug1: kex_exchange_identification: строка баннера 9: <body bgcolor="white">
debug1: kex_exchange_identification: строка баннера 10: <center><h1>400 Bad Request</h1></center>
debug1: kex_exchange_identification: строка баннера 11: <hr><center>nginx/1.14.0 (Ubuntu)</center>
debug1: kex_exchange_identification: строка баннера 12: </body>
debug1: kex_exchange_identification: строка баннера 13: </html>
kex_exchange_identification: Connection closed by remote host
Исправил внутреннюю портовую трансляцию, и теперь проблема исчезла.
Я решил свою проблему с ‘kex_exchange_identification: Connection closed by remote host’, когда заметил, что пытался подключиться, используя IP-сервера, когда следовало использовать частный IP.
Моя настройка может отличаться от всех вас, просто хотел поделиться своей находкой.
ИЗМЕНЕНИЕ:
С некоторыми хостинг-провайдерами у вас будет два IP, один публичный, другой частный; частный – это тот, который вы должны использовать в этом случае.
Вы либо знаете это, либо нет; я понимаю, что это не будет применимо ко всем, поэтому говорю, что это может быть другая настройка.
Никакие другие ответы не помогли мне, пока я не использовал закрытый ключ.
В моем случае я пытался сделать SSH на виртуальной машине Ubuntu, работающей на VirtualBox. Я упустил из виду, что нужно установить openssh-server
на виртуальной машине.
sudo apt-get install openssh-server
это исправило проблему.
В моем случае обновление openssh-server, похоже, изменило настройки по умолчанию. Явное указание PermitRootLogin
в /etc/ssh/sshd_config
решило проблему.
Чтобы ответить на первоначальный вопрос, вход в систему как root без ключа (с использованием пароля) может вызвать эту ошибку с вашей конфигурацией.
У меня была эта проблема на выделенном сервере с множеством служб и большим трафиком, с ~100 IP-адресами, прикрепленными к нему.
Из-за слишком многих попыток входа (даже если PasswordAuthentication отключен) эта ошибка появилась случайным образом, что, например, вызывало сбои резервного копирования rsync.
Одно из решений может заключаться в использовании нестандартного порта, но это означало бы изменение всех скриптов, подключающихся к серверу.
Я вместо этого добавил директиву ListenAddress
(2, одну для ipv4 и одну для ipv6), чтобы sshd слушал только на моем основном серверном IP, который не используется ни на одном живом сайте. Это привело к снижению попыток входа более чем на 99%.
Это происходило случайным образом при подключении к нашим серверам. Посмотрев логи SSH-сервера в /var/log/secure
, мы увидели всплеск неполных попыток подключения SSH от некоторых хакеров/сканеров. Около 10 за несколько секунд. Наша ошибка kex_exchange_identification, похоже, произошла в то же время.
Мы используем fail2ban для блокировки недобросовестных IP-адресов, поэтому собираемся добавить еще несколько правил фильтрации, чтобы поймать это поведение и заблокировать их.
Сканирование TCP-портов (сканирование SYN [например, режим сканирования по умолчанию nmap]) создает записи в логах, такие как эта, на OpenSSH версии 8.9p1.
Сканер отправляет TCP-пакет с поднятым флагом SYN, чтобы увидеть, получит ли он ответ SYN/ACK, что будет означать открытый порт с прослушивающим сервисом. Во время нормального соединения клиента клиент завершит TCP-тройное рукопожатие, отправив ACK после получения SYN/ACK от сервера, но типичный портовый сканер не делает этого. Он оставляет соединение полуоткрытым (что генерирует эти ошибки в логе).
Некоторые администраторы игнорируют эту активность, потому что сканирование портов так широко распространено; некоторые выбирают блокировать таких клиентов.
В моем случае я использовал ручные записи /etc/hosts и проксировал через бастион. Бастион не имел таких же записей /etc/hosts, поэтому он отказал в туннеле.
В моем случае возникла проблема с созданием ssh-ключа из защищенной переменной в Gitlab CI, я должен был снять защиту с этой переменной, чтобы это работало.
Вы можете просто подключаться к неправильному порту
.
Проверьте точный порт!
Вы можете указать пользовательский порт с помощью ssh -p port user@host
Я указал нестандартный порт с -p
, добавил ключи на сервер и в менеджер учетных данных, и я получал эту ошибку.
Я выяснил, что в моей конкретной проблеме мне нужно было внести свой IP в белый список в панели управления сервером хостинг-сервиса для моего идентификатора входа SSH.
У меня схожая проблема. Когда я впервые получил ошибку, я отредактировал и удалил свою запись файла ~/.ssh/known_host для этого сервера. Затем все работало нормально, но я вышел и попытался снова войти через 5 минут и снова получил ошибку.
Я видел это и на других серверах, но не думал об этом, так как наш цикл обновлений достаточно частый, и я думал, что это просто новая версия ssh, и ключи нужно обновить.
Так что временное решение – удалить запись в вашем ~/.ssh/known_host, чтобы снова войти, но это произойдет снова, когда вы попробуете войти в систему снова.
В моем случае это происходило спорадически с AWS EC2. Основной причиной было то, что sg был неправильно настроен. Он был настроен на разрешение входящего трафика только с портов 0-65000 без остальных.
Одной из возможных причин этой проблемы является то, что ~/.ssh/authorized_keys
, или что-то связанное с ним, имеет неправильные разрешения.
У меня была эта проблема, пытаясь подключиться по SSH к роутеру MikroTik (RouterOS v7.12). Я не разрешил подсеть в /ip/services
. Как только я это сделал, я смог успешно войти в роутер. В любом случае, это решило ошибку для меня-
Некоторые другие причины:
- Если ваш веб-сервер / сервер приложений слушает на другом порту, это также может вызвать эту проблему.
- Также нужно проверить брандмауэр клиентской системы, установлен ли исходящий соединение или нет.
- Основное решение для этого – TELNET, вы должны проверить с помощью команды telnet, т.е. telnet your-host-server port, т.е.: telnet 192.10.10.1 6594
- Это скажет, не получает ли сервер вообще никаких ответов с порта, тогда вам нужно проверить брандмауэр вашей клиентской системы, иначе проверьте, находится ли он под каким-либо брандмауэром или другой NAC / сетевым контроллером.
- Если вы используете какого-либо провайдера VPN и не подключены к нему.
У меня была та же проблема, и я не мог перезапустить OpenSSH.
Я затем нашел пост, который упоминал, что директория журнала в:
%programdata%/ssh
могла иметь неправильные разрешения, что заставляет OpenSSH не запускаться под Windows.
Я удалил эту директорию, и затем OpenSSH снова смог запуститься как служба Windows.
Ответ или решение
Ошибка SSH: kex_exchange_identification: Connection closed by remote host
может возникать по нескольким причинам, особенно в контексте настройки сервера SSH, который подвергается воздействиям многочисленных внешних соединений. Рассмотрим основные причины и факторы, способствующие возникновению этой ошибки.
1. Природа ошибки
Ошибка kex_exchange_identification
указывает на сбой в процессе обмена ключами, который происходит в начале установления SSH-сессии. В частности, это может происходить, если удалённый хост завершает TCP-соединение до того, как будет выполнен разрешение идентификации (Exchange Identification). Данная ошибка чаще всего возникает из-за того, что клиентский компьютер закрыл соединение до его полного завершения.
2. Проблемы с источниками трафика
Ваша ситуация, при которой сервер SSH доступен публично и единолично принимает большое количество соединений, может привести к различным видам сканирования и атакам с использованием брутфорса. Такие действия могут завершаться некорректными соединениями, что в свою очередь и вызывает сообщение об ошибке kex_exchange_identification
. Например, веб-сканеры, такие как Shodan, подключаются к SSH-портам, не инициируя полноценной аутентификации.
3. Настройки sshd_config
Убедитесь, что конфигурация SSH-сервера не ограничивает количество одновременных подключений, а также позволяет использовать параметры шифрования и аутентификации, совместимые с входящими соединениями. Ваша конфигурация содержит параметр MaxStartups 3:100:60
, который может быть недостаточно гибким для большого количества подключений, особенно если ведётся наблюдение за массивными атаками.
4. Проблемы с сетевыми соединениями
Проблемы с сетевыми соединениями, такие как использование неправильно сконфигурированных брандмауэров или неправильные настройки маршрутизации (например, NAT), также могут вызывать множество проблем с подключением. Например, если обновление сервера или изменение настроек маршрутизации приводит к тому, что пакеты направляются не по тому порту или на неправильный адрес, это может привести к появлению данной ошибки.
5. Ограничения на уровне хоста
Параметры, такие как PermitRootLogin
или PasswordAuthentication
, также могут стать причиной проблем, особенно если сервер настроен для проверки определённого метода аутентификации и этот метод не поддерживается клиентом. Попробуйте упростить процесс аутентификации на время тестирования, чтобы исключить влияние этих ограничений.
6. Внутренние сетевые конфигурации
В ситуации, когда сервер находится за баллансировщиком нагрузки или маршрутизатором, убедитесь, что SSH правильно маршрутизируется. Наличие проблем с NAT, которые приводят к неправильной обработке пакетов, может вызывать эту ошибку. Проблема может заключаться в настройках внутреннего или внешнего IP, которые должны соответствовать правильно открытым портам на сервере.
Заключение
Ошибку kex_exchange_identification: Connection closed by remote host
можно устранить, проверив конфигурацию SSH-сервера, сеть и параметры аутентификации. Рекомендуется вести учёт журнала SSH и анализировать, какие IP пытаются подключиться, чтобы более точно определить причину проблем. Если сервер подвергается множественным несанкционированным попыткам подключения, использование инструментов защиты, таких как fail2ban
, может значительно снизить количество ложных срабатываний и улучшить общую безопасность вашего SSH-сервера.