Перейти к содержанию

SSH на сервере с Hiddify рвет соединения при всплеске подключений#

На сервере с Hiddify SSH вдруг начинает капризничать: часть подключений проходит, часть отваливается без понятной причины. Чаще всего это не атака и не сломанный sshd, а его штатный лимит на число одновременных рукопожатий. Касается любого сервера, не только Hiddify.

Симптомы#

  • Подключение то проходит, то рвется на этапе рукопожатия: kex_exchange_identification: Connection closed by remote host.
  • Скрипты и мониторинг, ходящие по SSH, периодически получают Connection refused или "Error reading SSH identification string".
  • Сбои приходят пачками в моменты, когда к серверу идет много сессий разом: несколько админов, cron-скрипты, всплеск проверок доступности, мониторинг.
  • Между всплесками SSH работает нормально - воспроизводится только под нагрузкой.

Почему это происходит#

У OpenSSH есть параметр MaxStartups (по умолчанию 10:30:100). Это лимит на число незавершенных рукопожатий - сессий, которые подключились, но еще не прошли аутентификацию. Читается так: при более чем 10 одновременных рукопожатиях sshd начинает случайно ронять новые подключения с вероятностью 30%, и эта вероятность линейно растет до 100% к 100 одновременным рукопожатиям.

Несколько параллельных SSH-сессий за секунду (типичный burst от мониторинга или одновременной работы админов) легко пробивают порог в 10. Дефолт рассчитан на защиту от исчерпания ресурсов, а не на ваш рабочий профиль, поэтому рано или поздно ловит почти любой нагруженный сервер.

Что делать#

Поднять лимит через drop-in, не трогая основной sshd_config:

cat > /etc/ssh/sshd_config.d/50-maxstartups.conf <<'EOF'
MaxStartups 100:30:200
LoginGraceTime 30
EOF
systemctl reload ssh   # на некоторых дистрибутивах: systemctl reload sshd

Проверить, что значение применилось:

sshd -T | grep -E "^(maxstartups|logingracetime)"
# должно вернуть: maxstartups 100:30:200  и  logingracetime 30

LoginGraceTime 30 дает рукопожатиям успеть завершиться и быстрее освобождает слоты.

Если не помогло#

Параллельно стоит разнести нагрузку по времени: не запускать все cron-скрипты и проверки в одну секунду, добавить им небольшой разброс (jitter). Если burst создает один процесс, открывающий десятки сессий разом, - чините его, а не только лимит.

Если SSH отваливается и в спокойные моменты тоже - смотрите глубже: journalctl -u ssh на предмет других ошибок, нагрузку на сервер, фаервол и fail2ban. MaxStartups лечит именно случайные отказы под всплеском, а не постоянную недоступность.

Источники#

На основе опыта автора hiddify-faq.


Не помогло или есть уточняющий вопрос - заходите в русское сообщество @hiddify_rus.