Как на самом деле выглядит брутфорс SSH
Анатомия трафика, который прилетает на каждый Linux-сервер с открытым портом 22: кто его запускает, что на самом деле пробуют и какие меры меняют объём, а не поглощают его.
Что это такое, если без терминов
Брутфорс SSH направлен не на вас. Это ширпотребная операция: кто-то арендует ботнет, скармливает ему диапазоны IP и заставляет пробовать вход на всём, что отвечает на порту 22. Список имён короткий и скучный — root, admin, ubuntu, test, git, oracle, postgres и те служебные учётки, что популярны в этом году.
Работать без остановки её заставляет экономика. Шелл на Linux-машине стоит денег — для майнинга, как прокси, как точка опоры для всего, до чего машина дотягивается, — а попытка не стоит практически ничего. Поставьте свежий сервер на публичный IP: первый скан обычно приходит в течение часа, а через неделю несколько тысяч отказов в сутки — обычное дело.
Дело именно в объёме. Человек, подбирающий ваш пароль, — это анекдот. Сто тысяч попыток в месяц с постоянно меняющихся адресов — фоновое условие, и меры, рассчитанные на первое, ничего не делают со вторым.
Что именно они пробуют
В одном и том же логе видны три разных поведения, и реагировать на них надо по-разному.
Попытки входа под root — самые шумные и наименее опасные, потому что на любом правильно настроенном сервере PermitRootLogin стоит в no или prohibit-password. Тысячи таких записей в сутки означают, что боты ещё не поняли: root недоступен. Они и не поймут — спрашивать им ничего не стоит.
Дальше идёт перебор имён: прогон по распространённым учётным записям в поисках существующей. В современном OpenSSH различия во времени отклика, которые раньше делали это надёжным, по большей части убраны, но боты всё равно пробуют, а попадание даёт им цель.
Credential stuffing — вот что срабатывает. Пары «логин + пароль» из чужой утечки, воспроизведённые на вашем сервере. Выглядит как небольшое число попыток, а не как поток, и срабатывает, когда разработчик переиспользовал пароль. Ни один рейт-лимит этого не ловит, потому что ловить нечего.
Что даёт SSH, чего нет у других протоколов
У SSH есть выход, которого лишено большинство открытых сервисов: аутентификация по ключу. Отключите парольную аутентификацию полностью — и весь класс атак подбора становится не сложным, а невозможным. Подбирать нечего.
Это действительно самый сильный доступный шаг, и если вы можете его сделать, всё остальное в этой статье вторично. Ему посвящено отдельное руководство.
Но трафик от этого не прекращается. Боты не знают вашей конфигурации: они продолжают подключаться, предлагать пароли и получать отказ. Каждая попытка по-прежнему стоит TCP-соединения, форка sshd, строки в логе и куска процессора, а лог аутентификации по-прежнему ротируется достаточно быстро, чтобы потерять нужные вам события. Ключи убирают риск. Нагрузку они не убирают.
Почему одного рейт-лимита мало
Стандартный первый ответ — fail2ban, и это разумный ответ: он есть в репозиториях любого дистрибутива и он работает. Его границы стоит понимать до того, как полагаться на него как на всю защиту.
Он банит отдельные адреса. Ботнеты перебирают диапазон: забаните 203.0.113.47 — через час начнёт .48. Бан /24 обрывает серию одним движением, а fail2ban «из коробки» так не умеет.
Его баны истекают. По умолчанию — минуты, и тот же ботнет возвращается вечером. Можно выставить дольше, но состояние живёт в памяти и в файле, которые не переживают пересборку.
Он ничему не учится у других. Каждый сервер обнаруживает каждого атакующего самостоятельно, с нуля, ценой поглощения первых N попыток каждый раз.
И отказывает он молча. Регулярка, переставшая совпадать после обновления дистрибутива, jail, отключённый обновлением пакета, служба, не поднявшаяся после перезагрузки, — ни о чём из этого не сообщается, и отказ выглядит ровно как тишина.
Что реально снижает трафик
Объём меняет только одно: отказ разговаривать с источником. Всё остальное с ним договаривается.
Это значит следить за потоком отказов и, когда источник переходит порог, отбрасывать его на фаерволе раньше, чем sshd потратит на него хоть что-то. Три свойства отличают защиту, которая держит, от той, которая протекает:
- Банить подсеть, а не адрес. Атакующий трафик идёт с хостинговых диапазонов, где соседние адреса принадлежат тому же оператору; легитимные пользователи почти никогда не сидят в одной /24 со сканером.
- Банить навсегда и переживать перезагрузку. Правило должно жить в nftables и восстанавливаться при загрузке, а не в памяти демона.
- Внести себя в белый список до того, как что-либо включено. Самый частый способ всё сломать — администратор, заблокировавший собственный адрес на сервере, к которому есть доступ только по SSH.
Как получить это, не обслуживая механику
SSH Protector — эта логика, упакованная в агент. Он читает тот же поток journald или auth.log, который читали бы вы, принимает решение локально — поэтому продолжает работать при обрыве сети — и поддерживает одно сводное множество nftables со всеми забаненными диапазонами.
При установке он определяет реальный порт SSH по конфигурации sshd, а не считает, что это 22, и заносит в белый список адрес, с которого вы подключены, прежде чем что-либо блокировать.
Единственное, что нельзя построить в одиночку, — общая репутация: адрес, атаковавший другого клиента, заблокирован ещё до того, как дойдёт до вас, так что вы никогда не поглощаете его первые N попыток. Один сервер бесплатен навсегда — этого достаточно, чтобы посмотреть на реальный поток атак на своей машине и решить по фактам, а не по статье.
FAQ
- Сколько неудачных входов по SSH в сутки — это норма?
- На сервере, недоступном из интернета, — почти ноль. На сервере с открытым для любых адресов портом 22 несколько тысяч в сутки — обычное дело, и это ничего не говорит лично о вас: таков фоновый уровень сканирования интернета. Значение имеют динамика и распределение источников, а не абсолютное число.
- Спасает ли отключение входа под root от брутфорса SSH?
- Оно не даёт им добиться успеха под root — это стоит сделать, и это одна строка в sshd_config. Но объём попыток оно не снижает вообще: боты не знают, что root недоступен, и будут пробовать бесконечно. Отключайте вход под root и одновременно блокируйте источники, иначе вы продолжаете платить за каждую попытку.
- Достаточно ли одного fail2ban?
- Для одного сервера, который вы регулярно проверяете, это разумная защита и намного лучше, чем ничего. Практические границы: бан отдельных адресов против ботнетов, перебирающих диапазоны; баны, которые истекают и не переживают пересборку; отсутствие обмена знаниями между серверами; и молчаливый отказ — сломанный jail выглядит ровно как спокойная неделя.
- Стоит ли банить целую подсеть /24 при атаках на SSH?
- Для диапазона, который только что выдал вам сотни неудачных входов, — обычно да. Атакующий трафик идёт с хостинговых и VPS-диапазонов, где соседние адреса принадлежат тому же оператору, а домашние пользователи почти никогда не оказываются в одной /24 со сканером. Держите свои офисы и точки выхода VPN в белом списке — и доля ложных срабатываний будет близка к нулю.
