АйТи Фреш
Главная / Статьи / Безопасность
Безопасность

Почему SSH2_MSG_PING кладёт sshd до входа и как защитить appliance без патча

Автор: Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш» · · ~8 мин чтения
Почему SSH2_MSG_PING кладёт sshd до входа и как защитить appliance без патча

Пароли отключены, MaxSessions уменьшен, доступ выдан только администраторам — а новый SSH-вход всё равно зависает. Для CVE-2025-26466 противоречия здесь нет: ресурсы расходуются ещё до проверки пользователя. Я, Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш», покажу механизм проблемы, результаты локального стенда и схему защиты сетевого appliance на время ожидания прошивки. Мой первый шаг — ограничить сетевую доступность управления. Настройки sshd идут следом.

1. Что происходит раньше проверки пароля

SSH-сервер начинает работать задолго до появления приглашения ввести пароль. Сначала устанавливается TCP-соединение, стороны обмениваются идентификационными строками и согласовывают криптографические параметры. Только затем начинается аутентификация пользователя. SSH2_MSG_PING относится к транспортному расширению SSH: это внутреннее сообщение протокола, а не ICMP Echo Request. Поэтому запрет обычного ping на межсетевом экране к этой проблеме отношения не имеет. Формат расширения описан в [OpenSSH PROTOCOL](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL).

В уязвимой реализации полученный PING порождал ответ PONG. Во время обмена ключами ответы складывались в очередь отдельных буферов, число которых не ограничивалось. Исследователи Qualys показали асимметрию: входное сообщение размером 16 байт могло потребовать 256-байтный буфер ответа, дополнительно к служебным структурам. После завершения обмена ключами возникала другая неприятность: перенос накопленных ответов в выходной буфер сопровождался квадратичным объёмом копирования, O(n²). Получались два способа исчерпать ресурсы: занять память и загрузить CPU. Это описание механизма из [исследования Qualys](https://www.qualys.com/2025/02/18/openssh-mitm-dos.txt), а не наши замеры производительности.

Формулировку «кладёт sshd» я использую осторожно. Она не означает обязательное падение главного процесса или всего устройства. Может перестать нормально работать создание новых подключений; последствия для маршрутизации, VPN и веб-интерфейса зависят от архитектуры appliance и распределения ресурсов. На устройстве с отдельным аппаратным forwarding трафик иногда продолжает идти, хотя администратор уже потерял управление. Поэтому при разборе инцидента я отдельно проверяю доступность управления и прохождение рабочего трафика.

У этой CVE цель — доступность. Сильный пароль и MFA непосредственно на уязвимом sshd не мешают обработать сообщения, которые приходят до аутентификации.

2. Версию прошивки проверяю раньше баннера

CVE-2025-26466 затрагивает upstream OpenSSH 9.5p1–9.9p1 включительно. Исправление выпущено в 9.9p2 18 февраля 2025 года. В исправленном обработчике PING ответ не формируется до завершения аутентификации и во время обмена ключами. Это изменение поведения, а не дополнительная настройка размера очереди. На сентябрь 2026 года 9.9p2 — историческая граница исправления этой CVE; выбирать для эксплуатации нужно поддерживаемую сборку своего поставщика. Основание: [анонс 9.9p2](https://www.openssh.org/txt/release-9.9p2) и [исправленный packet.c](https://raw.githubusercontent.com/openssh/openssh-portable/V_9_9_P2/packet.c).

По строке OpenSSH_9.6p1 нельзя уверенно объявить сервер уязвимым. Дистрибутивы переносят исправления в прежние версии. Например, Ubuntu 24.04 получила исправление в пакете 1:9.6p1-3ubuntu13.8. Для Linux я выясняю полную версию серверного пакета и сверяю её с бюллетенем. Команда ssh -V показывает локальный клиент и не отвечает на вопрос о состоянии удалённого appliance. Конкретный пример бэкпорта приведён в [Ubuntu USN-7270-1](https://ubuntu.com/security/notices/USN-7270-1).

На сетевом устройстве ориентиром становится матрица производителя. Показателен WatchGuard: в бюллетене WGSA-2025-00009, обновлённом 28 июля 2026 года, таблица отмечает Fireware OS до 12.11.3 в указанном диапазоне как затронутую, а начиная с 12.11.3 — как незатронутую. При этом раздел Solution сообщает, что решение не опубликовано. Такая несогласованность — повод запросить подтверждение для своей модели, а не самостоятельно выбрать прошивку по одной строке. Я фиксирую модель, текущую сборку, ответ поддержки и допустимый путь обновления. Вот [сам бюллетень производителя](https://psirt.watchguard.com/WGSA-2025-00009/).

Подменять встроенный sshd самостоятельно я не рекомендую: обновление должно сохранять совместимость с системой управления устройством и поддерживаться производителем.
Почему SSH2_MSG_PING кладёт sshd до входа и как защитить appliance без патча — схема

3. Какие лимиты действительно относятся к pre-auth

MaxSessions ограничивает shell-, login- и subsystem-каналы внутри одного соединения. Ограничение попыток входа MaxAuthTries тоже не управляет ранней очередью PONG. Поэтому снижать эти значения ради данной CVE бессмысленно. Они решают свои задачи, но атакующий ещё не дошёл до соответствующей стадии. Семантика параметров приведена в [sshd_config(5)](https://man.openbsd.org/sshd_config).

MaxStartups, напротив, ограничивает одновременно неаутентифицированные подключения. В записи 3:30:10 число 30 означает начальную вероятность отказа в процентах: отказы начинаются при трёх подключениях, а при десяти становятся полными. Но это ограничение количества соединений, не памяти каждого процесса. Для небольшой группы администраторов я рассматриваю следующий исходный вариант, после проверки реальной параллельности входов: LoginGraceTime 30 MaxStartups 3:30:10 PerSourceMaxStartups 2 Это глобальная часть sshd_config, вне блоков Match. Значения иллюстративные; переносить их на массовую автоматизацию без измерений нельзя.

LoginGraceTime сокращает время до обязательного завершения неудавшегося входа. PerSourceMaxStartups дополнительно ограничивает один адрес. Начиная с OpenSSH 9.8 появился PerSourcePenalties, включённый по умолчанию: штрафы затрудняют последующие подключения проблемного источника, но не обрывают уже работающие. На штатных upstream 9.5–9.7 этой директивы нет. Проверять её поддержку нужно у конкретной сборки. Механизм представлен в [анонсе OpenSSH 9.8](https://www.openssh.org/txt/release-9.8).

За bastion или NAT несколько администраторов выглядят одним источником. Слишком жёсткий адресный лимит способен одновременно остановить ручной вход и резервное копирование конфигурации. Я сначала измеряю обычную параллельность и длительность входа через RADIUS или MFA, затем выбираю ограничения. Если интерфейс appliance позволяет менять только число пользовательских сессий, не пытаюсь считать эту настройку аналогом MaxStartups. Компенсацию выношу на сетевую границу.

LoginGraceTime 0 отключает таймер. Если ноль раньше поставили как обход CVE-2024-6387, возвращать таймер вслепую тоже нельзя: сначала подтвердите исправление той уязвимости. До этого изолируйте SSH. Связь этой меры с ростом риска DoS отмечена на [странице безопасности OpenSSH](https://www.openssh.org/security.html).
Цифры и версии: Какие лимиты действительно относятся к pre-auth — схема
Цифры и версии: Какие лимиты действительно относятся к pre-auth

4. Стенд: три подключения при MaxSessions 1

Для статьи я провёл две отдельные локальные проверки. Это воспроизводимый стенд, а не история вымышленного заказчика. Первая часть — Ubuntu 24.04, x86-64, серверный пакет OpenSSH 1:9.6p1-3ubuntu13.19. Он уже содержит исправление CVE. Отдельный sshd слушал только 127.0.0.1:22222, использовал собственный Ed25519 host key и отдельный конфиг. Существенные параметры опыта: MaxSessions 1, LoginGraceTime 5 и заведомо высокий MaxStartups 100:30:200. Последнее значение выбрано исключительно для лабораторной проверки.

Клиент открыл три обычных TCP-соединения и обменялся с сервером идентификационными строками. Все три получили SSH-баннер и KEXINIT; аутентификации не было. Значение MaxSessions 1 этому не помешало. Таймер закрыл соединения через 5,318, 5,195 и 5,172 секунды от момента подключения. Следующее соединение снова получило баннер. Именно этот результат и требовалось увидеть: ограничение пользовательских каналов не мешает нескольким подключениям дойти до pre-auth, а таймер ограничивает их жизнь.

Во второй части я проверил сетевую компенсацию: Linux 6.8.0-136-generic, nftables 1.0.9 и четыре изолированных network namespace — маршрутизатор, сервер, разрешённый и запрещённый клиенты. Сервер имел адреса 192.0.2.20 и 2001:db8:20::20. Разрешённый источник — 192.0.2.10 и 2001:db8:10::10. На TCP/22 работал простой echo-сервис, чтобы проверить именно доставку данных. До ACL оба клиента подключались по IPv4 и IPv6. После ACL разрешённый продолжил работать, запрещённый перестал получать ответы даже внутри заранее открытых соединений.

Новые подключения запрещённого клиента тоже завершались тайм-аутом. Счётчики зарегистрировали 9 отброшенных IPv4-пакетов и 8 IPv6-пакетов; это результат конкретного короткого прогона с повторными передачами, не показатель мощности защиты. Все тестовые процессы и сетевые пространства после проверки удалены. Поток SSH2_MSG_PING и исчерпание памяти я не воспроизводил: первый опыт проверяет MaxSessions и таймер, второй — ACL. Приписывать этим результатам доказанную устойчивость конкретной модели appliance было бы нечестно.

Практический результат стенда: обычные сессионные ограничения не закрывают ранний доступ, а внешняя ACL отсекает запрещённый источник независимо от состояния его TCP-соединения — если пакеты проходят через фильтр.

5. Мой выбор на время ожидания прошивки

Я оставляю доступ к SSH устройства только с выделенной точки администрирования. Рабочая схема выглядит так: администратор проходит VPN с MFA, подключается к обновляемому bastion, а уже оттуда получает доступ в management-сегмент. Пользовательские VLAN и публичные интерфейсы прямого маршрута к SSH не получают. Разрешать всю корпоративную подсеть мне не нравится: заражённый ноутбук сотрудника тогда становится подходящим источником атаки без каких-либо украденных паролей.

Для интерактивной работы удобно использовать ssh -J admin@bastion admin@192.0.2.20. Клиент сначала аутентифицируется на промежуточном узле, а затем организует соединение с целью через TCP forwarding. Именно предварительный контроль доступа делает bastion полезным здесь. Обычный прозрачный TCP-прокси, который пересылает любого клиента дальше, такой границы не создаёт. Поведение ProxyJump описано в [ssh(1)](https://man.openbsd.org/ssh).

Есть и остаточный риск: скомпрометированный bastion или его авторизованный пользователь всё ещё могут обратиться к уязвимому обработчику. Поэтому я ограничиваю круг учётных записей и допустимых назначений, а автоматизацию учитываю отдельно. Management VLAN должна действительно отделяться маршрутизацией: сосед в одном L2-сегменте способен обойти внешний маршрутизатор. Если устройство само является пограничным шлюзом, нужна его штатная ACL управления или доступ через отдельную внешнюю границу. Политика транзитного трафика не обязательно защищает собственный SSH устройства.

Смена TCP/22 на другой порт уменьшает случайный шум. В качестве компенсации этой CVE я её не учитываю.
Порядок действий: Мой выбор на время ожидания прошивки — схема
Порядок действий: Мой выбор на время ожидания прошивки

6. Проверенный ACL и границы rate limit

Ниже конфигурация из сетевого стенда. Она устанавливается на внешний Linux-маршрутизатор, через который действительно проходит доступ к appliance. Адреса демонстрационные; в рабочей сети нужно перечислить все адреса и SSH-порты управления. Эта таблица дополняет основной firewall: table inet appliance_ssh_guard { chain forward { type filter hook forward priority -10; policy accept; ip daddr 192.0.2.20 tcp dport 22 ip saddr != 192.0.2.10 counter drop ip6 daddr 2001:db8:20::20 tcp dport 22 ip6 saddr != 2001:db8:10::10 counter drop } }

Принципиальная деталь — отсутствие условия ct state new. Запрещённые источники отсекаются и внутри существующих соединений. Разрешение established в другой базовой цепочке этот drop не отменяет. При этом policy accept здесь не обходит запреты основного firewall. Для собственного SSH Linux-узла нужен hook input; показанный forward обслуживает транзит. При DNAT нужно учитывать адрес назначения после преобразования. Семантика цепочек и verdict описана в [nft(8)](https://netfilter.org/projects/nftables/manpage.html).

Отдельно проверяю flow offload. Ускоренные потоки могут обходить обычный forwarding и не попадать в такую цепочку. Management-трафик нужно исключить из ускорения, а уже ускоренные соединения обработать отдельно штатным механизмом платформы. Наш сетевой опыт выполнялся без offload. Кроме того, drop прекращает доставку пакетов, но не освобождает уже занятую sshd память мгновенно. Это важное различие при действующей атаке. Обход сетевых hooks описан в [документации ядра Linux](https://www.kernel.org/doc/html/latest/networking/nf_flowtable.html).

Лимит новых SYN я рассматриваю как дополнение. Он уменьшает частоту создания соединений, но не ограничивает PING внутри уже принятого TCP-потока. Policer всего входящего SSH-трафика затрагивает и существующие подключения, однако может ухудшить SFTP, передачу конфигураций и интерактивную работу. Универсального безопасного значения в пакетах или мегабитах нет: SSH-сообщение не обязано совпадать с TCP-пакетом, а запас CPU и памяти у устройств разный. Возможности ограничения пакетов и байтов описаны в [документации nftables](https://wiki.nftables.org/wiki-nftables/index.php/Rate_limiting_matchings).

До применения обеспечьте консольный или другой независимый доступ и подготовьте откат. Открытое SSH-окно не заменяет резервный канал: новая ACL может остановить и его.

7. Как принимаю работу и закрываю временную меру

Я проверяю не только успешный вход администратора. Нужна отрицательная проверка: с обычной рабочей станции SSH устройства недоступен по обоим семействам адресов. Отдельно проверяю альтернативные интерфейсы, NAT-публикации и сохранение политики после перезагрузки. Распространённая ошибка — оставить прямой маршрут «на всякий случай». Тогда аккуратно настроенный bastion существует, но обязательным путём доступа так и не становится.

В наблюдение включаю успешность служебного входа, время его выполнения, загрузку процессора управления, свободную память и счётчики ACL. Рост отказов до аутентификации сам по себе ещё не доказывает именно PING-атаку. Для этого нужна дополнительная диагностика. Постоянный DEBUG3 на рабочем appliance я не оставляю: подробные журналы пригодились на коротком стендовом опыте, но при интенсивном потоке сами создают лишнюю работу. И стандартный бан по неверным паролям не считаю доказательством защиты стадии, на которой пароль ещё не спрашивали.

У временной меры должны быть ответственный и дата пересмотра. После появления подходящей прошивки я проверяю её совместимость с моделью и кластером, сохраняю конфигурацию, готовлю откат и планирую окно обновления. После установки повторяю проверки доступа и автоматизации. ACL при этом обычно оставляю: даже исправленному SSH не требуется доступ со всех рабочих мест. Задача закрыта, когда подтверждено исправление в конкретной сборке и сохранён управляемый путь администрирования, а не просто исчезла красная строка в сканере.

Памятка: Как принимаю работу и закрываю временную меру — схема
Памятка: Как принимаю работу и закрываю временную меру

Частые вопросы

Достаточно ли отключить парольный вход?

Нет. Обработчик, затронутый этой CVE, доступен до аутентификации. Ключи полезны для защиты входа, но не устраняют ошибку обработки PING.

MaxStartups вообще бесполезен?

Полезен: он ограничивает число одновременных pre-auth-подключений. Но расход ресурсов внутри каждого принятого соединения этим параметром не ограничивается.

Можно ли закрыть проблему одним SYN rate limit?

Нет. Он ограничивает начало новых TCP-соединений. Поток сообщений внутри уже принятого соединения продолжает проходить.

Нужно ли срочно менять любой сервер с баннером OpenSSH_9.6p1?

Сначала проверьте полную версию пакета или прошивки и наличие бэкпорта. Одинаковый upstream-номер встречается как у исправленных, так и у уязвимых сборок.

Проверим защиту доступа к инфраструктуре
Я помогу проверить доступность SSH, подобрать ограничения и подготовить обновление appliance силами «АйТи-Фреш». Если вместе с инфраструктурой нужно наладить бухгалтерское сопровождение, предложу услуги rf-buh отдельно.
Бесплатная консультация →
© ООО «АйТи-Фреш» · Москва · Все статьи