← Blog

Автоматическая блокировка атакующих с помощью BGP — IDS, объявляющий маршруты черной дыры

DEENESRUUK

Самое чистое место для "сброса" атакующего — это не сервер, а граница сети, до того как пакеты будут стоить вам денег. Suri Defender делает именно это: он превращает "этот IP нас атакует" в объявление BGP, которое черным списком отбрасывает источник на границах, а ядро маршрутизатора при этом никогда не несет ни одного маршрута черного списка.

Идея: обнаружение → маршрут

Блокировка с помощью iptables работает на одной машине. Но когда вы управляете автономной системой (AS 48756 в данном случае), правильный примитив — это RTBH — Remote-Triggered Black Hole (удаленный черный список). Вы объявляете виновный /32 через iBGP с тегом сообщества черного списка (48756:666); каждый граничный маршрутизатор, который его слышит, отбрасывает трафик к этому назначению. Одно объявление, отброшенное везде, на скорости линии.

Таким образом, вся конструкция представляет собой конвейер, заканчивающийся объявлением BGP:

SSH / nginx / syslog / FortiGate logs
        │                    │
   CrowdSec scenarios    fail2ban jails
        │ decisions          │ file-only action
        ▼                    ▼
   source-of-truth DB  +  prefix files
        │  union − whitelist
        ▼
   ExaBGP route-injector  →  FRR (bgpd)  →  borders / MikroTik
        announce /32 · community 48756:666
  • CrowdSec парсит логи и запускает сценарии обнаружения, выдавая поток решений.
  • fail2ban обрабатывает свои собственные тюрьмы (SSH, VPN, nginx, mail) и добавляет забаненные /32 в плоский файл — намеренно глупое действие, только с файлами, без vtysh.
  • Небольшой сервис FastAPI + SQLite хранит источник истины, применяет TTL и регенерирует файл префиксов.
  • ExaBGP читает объединение этих файлов (минус белый список) и испускает announce/withdraw в FRR, который пересылает маршруты дальше.

Почему route-injector лучше reconciler

Первая версия хранила черные списки как статические маршруты плюс prefix-list и redistribute static, с реконсилятором, пытающимся их синхронизировать. В FRR 10.6 это постоянно конфликтовало с демоном управления: рассинхронизация деревьев prefix-list, фантомные маршруты, конфликты блокировки хранилища данных, frr.conf размером 2.6 МБ.

Переход на ExaBGP route-injector полностью устранил локальное состояние маршрутизации — ядро теперь не содержит никаких маршрутов черного списка. "Заблокировано" и "объявлено" стали одним фактом по конструкции, а не двумя состояниями, за которыми должен гнаться реконсилятор. Это тот инвариант, который не дает системе удивлять вас в 3 часа ночи.

Легче, к тому же

Он заменил тяжелый стек Suricata + OpenSearch + Dashboards + Filebeat + EveBox — около 2.7 ГБ ОЗУ — на несколько небольших процессов общим объемом в несколько сотен мегабайт. Та же задача, на порядок меньше веса и единый веб-интерфейс для просмотра того, что сейчас находится в черном списке и почему.

Обнаружение — это уже решенная проблема; интересной частью является реагирование — а для сети самым элегантным реагированием является маршрут.

Прозрачность: большинство постов здесь написаны с помощью ИИ, а неанглийские версии переведены локальной LLM и вычитаны. Заметили ошибку? Напишите мне.