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.