Кейс
SSH-флуд со спуфингом IP на MikroTik hEX: почему fail2ban тут бессилен
Разбираем реальный инцидент: SYN-флуд на нестандартный SSH-порт с подменой исходного IP на каждом пакете. Показываем профиль CPU, address-list на 7756 адресов и почему помогает не блок-лист, а RPF.
Проценты, шаг реконструкции — от двадцати минут в спокойной части до десяти на всплесках.
Наведите указатель или пройдите стрелками — покажет точку и значение
- 20,08% средняя
- 100% пиковая
- ~1% обычная (до и после)
Реконструкция силуэта по графику мониторинга; средняя, пиковая и обычная — реальные показания за инцидент.
Клиенту с приватным «серым» WAN IP на MikroTik hEX начали прилетать TCP SYN на нестандартный SSH-порт. Обычно такие вещи лечатся стандартным набором: fail2ban, conn-limit, RAW DROP по адресу источника. Здесь этот набор не сработал — и разбор того, почему именно, оказался полезнее самого инцидента.
Почему стандартная защита не сработала
Fail2ban, conn-limit и блок-листы по src-IP решают одну и ту же задачу: считают попытки с конкретного адреса и банят его после порога. Это работает, когда атакующий действительно приходит с одного (или ограниченного набора) IP.
Здесь — не так. Сниффер на роутере показал, что почти каждый пакет приходит с нового исходного адреса:
| Время | SRC | DST | Протокол |
|---|---|---|---|
| 0.638 | 95.161.221.242:50095 | *.*.*.*:22 | tcp |
| 1.722 | 31.162.17.188:2185 | *.*.*.*:22 | tcp |
| 1.995 | 185.177.96.125:38460 | *.*.*.*:22 | tcp |
| 2.430 | 83.69.0.36:16901 | *.*.*.*:22 | tcp |
| 3.637 | 95.161.221.242:50095 | *.*.*.*:22 | tcp |
| 4.352 | 88.236.198.50:61323 | *.*.*.*:22 | tcp |
| 4.905 | 37.73.171.122:25000 | *.*.*.*:22 | tcp |
| 4.993 | 185.177.96.125:38460 | *.*.*.*:22 | tcp |
За 5 секунд захвата — восемь пакетов, шесть разных адресов, и даже повторы (те же
95.161.221.242 и 185.177.96.125) держат тот же src-порт, а не открывают новое
TCP-соединение — то есть это не повторная попытка того же клиента, а тот же
поддельный конверт, отправленный ещё раз. Банить по IP тут бессмысленно: адрес,
который «нужно было бы» заблокировать, атакующий больше не использует.
Как это выглядело на роутере
tool profile показал, что задача ssh держит 21,5% CPU одного ядра — на пустом
роутере это должно быть около нуля:
NAME CPU USAGE
ssh 21.5%
firewall 1.2%
networking 3.7%
...
total 30.2%
system resource monitor в этот момент фиксировал одно ядро на 100% при общей
загрузке 32%. Графики мониторинга за то же окно (12 часов, 10:56–22:56) подтверждают
масштаб: средняя загрузка CPU — 20,08%, пиковая — 100%, обычная для узла
загрузка (до атаки и после) — около 1%.
Системный лог всё это время писал ssh,info auth timeout каждые несколько секунд —
не разовые сканы, а ровный, непрерывный поток попыток подключения.
За время инцидента в address-list fail2ban-1 накопилось 7756 адресов — и это
не значит, что атакующих IP было 7756: часть повторялась, часть просто не успела
зафиксироваться до момента снятия дампа.
Что действительно помогает при спуфинге
Ключевая ошибка — защищаться по идентичности источника (IP), когда атакующий её подделывает бесплатно на каждом пакете. Правильный вопрос не «с какого адреса пришёл пакет», а «мог ли пакет с таким адресом вообще прийти через этот интерфейс».
Это и есть RPF (reverse path filtering) — на MikroTik включается в
/ip settings (rp-filter=strict). В строгом режиме роутер проверяет для каждого
входящего пакета: есть ли у него маршрут обратно к заявленному src-адресу именно
через тот интерфейс, откуда пакет пришёл. Если внешний интерфейс — не тот, через
который в принципе может прийти трафик от 95.161.221.242, пакет отбрасывается
на уровне маршрутизации, до того как достигнет сервиса ssh и до того как его вообще
нужно с кем-то сравнивать. Блок-лист при этом не растёт — фильтруется целый класс
подделанных пакетов, а не конкретные адреса.
Это дополняет, а не заменяет базовую гигиену периметра: сервис на нестандартном порту (здесь уже был), ограничение источников на management-доступ и, где это возможно, вынос административного доступа за VPN — но именно RPF снимает то, для чего fail2ban и conn-limit не были рассчитаны в принципе.
Мониторинг подтвердил результат тем же языком, каким показал проблему: график CPU за тот день возвращается к обычной загрузке в пределах тех же суток. Урок здесь не про конкретный роутер, а про диагностику: прежде чем добавлять правило в блок-лист, стоит проверить, от чего вообще защищает выбранный инструмент — и не окажется ли он, как в этом случае, попросту не про ту атаку.