9.3 Динамічні блок-листи — apiban та ipban¶
[!IMPORTANT] Якщо ви стартували зі стокового
kamailio.cfg, ви вже запустили динамічний блок-лист — дефолтний конфіг greylists'ить флудерів без жодного модуля, який ви впізнали б як «той самий блок-лист». Ця глава відкриває цей механізм: self-expiring-бан зі стокового конфіга, потім — як зовнішній reputation-feed розширює його на IP, що вас особисто ще не чіпали.
Антифлуд, який ви вже задеплоїли¶
Стоковий конфіг зв'язує pike з 9.2 з ban-сетом на базі htable кількома рядками. Таблиця:
Іменований htable (8.3 htable) ipban — hash map у shm. Несучий параметр — autoexpire=300: кожен запис видаляє сам себе через 300 с після запису — прибирати нічого не треба, бан забуває. Далі в route[REQINIT] (на самому початку request_route) — дві перевірки одна за одною:
if ($sht(ipban=>$si) != $null) { # вже забанено? drop, не витрачаємо нічого більше
exit;
}
if (!pike_check_req()) { # не забанено — даємо pike порахувати цей пакет
$sht(ipban=>$si) = 1; # вердикт флуд → створюємо ключ
exit;
}
Порядок і є механізм. Lookup $sht(ipban=>$si) іде першим — забанений $si drop'ається до sanity, до парсингу решти, до будь-якої реальної роботи. Лише незабанені джерела доходять до pike_check_req() (9.2: 1 — ок, -1/-2 — флуд); вердикт флуду пише $sht(ipban=>$si) = 1, і це присвоєння і є баном — наступний пакет потрапляє у верхній lookup і вмирає. pike — детектор, ipban — пам'ять, lookup — enforcement, autoexpire — звільнення: htable + pike, скомпоновані у self-expiring блок-лист без зовнішніх залежностей і без БД. Перший пакет понад ліміт платить за pike-перевірку; кожен наступний протягом 300 с — за hash-lookup і drop.
Чому self-expiring, а не перманентний бан¶
Source-IP у публічному інтернеті — це не людина. Це NAT-gateway, CGNAT-пул, корпоративний egress, мобільний APN — спільні для сотень легітимних користувачів поряд із тим, що зачепило ваш rate-ліміт. Перманентний бан врешті залочить реального клієнта за тією самою адресою, що й сканер, без виходу, крім як людина-оператор помітить і відредагує список. autoexpire=300 робить бан cooldown'ом: флудер відрізаний на п'ять хвилин, реальний клієнт за тим самим NAT'ом чекає щонайбільше п'ять, із self-healing'ом і нульовою участю оператора. Чесна ціна: рішучий атакувальник ротує source-IP, і ваша таблиця наповнюється п'ятихвилинними записами, які він уже покинув. Per-source rate-limiting відповідає «чи цей IP поводиться погано просто зараз» — і не має думки про IP, якого ще ніколи не бачив. Саме цю прогалину закриває reputation-feed.
apiban — позичена репутація¶
apiban (apiban.org) — безкоштовний зовнішній REST-сервіс, що роздає курований список IP-адрес, уже пійманих за атаками на інших операторів, зібраних через мережу SIP-honeypot'ів. Ви запитуєте API-ключ і опитуєте його HTTPS-endpoint за JSON. Це не модуль Kamailio — жодного modparam("apiban", ...). Це feed; ви обираєте, де діяти за ним.
- Ядро — standalone-клієнт. apiban постачає клієнти на Go і bash з інтеграціями iptables / nftables /
ipset/ fail2ban, що опитують feed по таймеруcrontabі програмують firewall (iptables-клієнт тримає виділенийAPIBAN-chain). Пакети від адреси зі списку drop'аються ядром ще до того, як Kamailio розпарсить хоч байт — доpike, до lookup'уipban. - In-route — feed, затягнутий у
htable. Kamailio-клієнта для цього не існує; ви будуєте самі: опитуйте той самий JSON черезhttp_clientна годинникуrtimerі пишіть кожен IP уhtable— ту саму таблицюipban, просто наповнену з feed'у замістьpike. Тоді наявна$sht(...)-перевірка вroute[REQINIT]блокує feed-IP і локально задетекчених флудерів одним рядком — тепер після парсингу.
| Шар | Вартість на пакет | Гнучкість | Для чого |
|---|---|---|---|
Ядро — ipset/nftables/iptables (клієнт apiban) |
найнижча — drop до будь-якого SIP-парсингу | низька — чистий IP yes/no, без SIP-контексту | тупий об'єм: reputation-feed'и, очевидні флуд-IP |
Усередині Kamailio — ipban htable + pike |
hash-lookup, після парсингу | висока — логіка per-route, «challenge, не drop», шаринг через dmq |
behaviour-driven greylisting; рішення, що потребують SIP-контексту |
Доповнення, а не суперники: зіштовхуйте високооб'ємний, не-вимагаючий-суджень reputation-список у ядро, де кожен drop майже безкоштовний; тримайте behaviour-driven greylist — бани, що ваш власний трафік заслужив — у Kamailio, де є контекст. Між інстансами ipban — рівно той стан, що реплікує 8.5 dmq: задетекчте флудера на одній ноді, забаньте його по всьому кластеру. А тихі сканери, що зондують по одному well-formed-запиту за раз, несуть payload 9.4 — feed, що вже бачив їх деінде, є вашим найдешевшим захистом від того, щоб вони дісталися сюди.