Обзор — что делает эта функция
Автоблокировка — это фоновый конвейер InfraGuard, который обнаруживает, проверяет и блокирует IP-адреса атакующих без участия человека. Это не экран, а поток, проходящий через коллекторы, планировщик и ipset ядра. В этой статье описана вся эта структура.
В конвейере есть два независимых пути блокировки, которые сходятся в единой точке применения (ipset).
| Путь | Где выполняется | Куда пишет | Единица | Источник |
|---|---|---|---|---|
| ① Автоблокировка коллектора | Node-коллекторы на каждом хосте (srct_tx · kts_tx · eve_ingest) |
blacklist_info |
/24 (класс C) | Suricata L7 · Kitsune ML |
| ② Автоблокировка планировщика | Приложение InfraGuard (infr:auto-block → AutoBlockService) |
infr_block |
/32 (отдельный) или /24 | suricata_alert_ct · suricata_tls_ct |
| ③ Применение (общее) | infr_sync_black.mjs (cron на хосте) |
ipset blacklist в ядре |
hash:net | объединение ①+② |
Оба пути непосредственно перед блокировкой выполняют проверку по белому списку и проверку невиновности. Остаётся только подтверждённое злоупотребление; кандидаты, которые с большой вероятностью являются ложными срабатываниями, оправдываются. Путь ② (планировщик) по умолчанию выключен, и его должен включить администратор.
Когда использовать
- Включайте автоматическую защиту, когда ботнеты, сканеры и переборные зондирования идут непрерывно и ручная блокировка перестаёт справляться.
- Когда в разделе Обнаружения ▸ ИИ JA3 видны ботнеты, ротирующие отпечатки, настройте порог так, чтобы они перехватывались автоматически.
- Когда источник многократно порождает оповещение IDS заданной серьёзности (красное/оранжевое) в разделе Угрозы и вы хотите блокировать его автоматически.
- Когда вы разбираете накапливающиеся причины блокировок в разделе Блок-лист и репутация и снимаете излишние блокировки через Белый список.
Устройство
У автоблокировки нет отдельного экрана. Её точки управления и наблюдения таковы:
- Настройка — Операционная политика ▸ вкладка Настройки безопасности ▸ карточка Автоблокировка (главный переключатель, режим, охват, триггеры, невиновность).
- Наблюдение за результатом — Блок-лист и репутация (блокировки /24 от коллектора и /32 от планировщика, причины, снятие).
- Оправдание — Белый список (IP-адреса и CIDR, добавленные вручную либо автоматически оправданные, со сроком действия).
- Источники триггеров — Угрозы (серьёзность IDS), Обнаружения (ротация JA3).
Как пользоваться
1. Путь ② автоблокировка планировщика — включение и настройка
По умолчанию она выключена (autoblock_on=0). Переведите главный переключатель в разделе Операционная политика ▸ Настройки безопасности, а затем скорректируйте политику.
Режим
| Значение | Смысл |
|---|---|
global (по умолчанию) |
Компрометация, замеченная на одном сервере, применяется ко всему парку (server_index=0). |
per_server |
Применяется только к атакованному серверу — целевой dest_ip преобразуется в server_index через infr_server_index. |
Охват
| Значение | Что пишет планировщик | Описание |
|---|---|---|
balanced (рекомендуется, по умолчанию) |
отдельный /32 | Программы IDS используют /24; InfraGuard добавляет отдельные /32 — sync_black пропускает любой /32, уже покрытый некоторым /24. |
broad |
/24 | Блокирует весь класс C — широкий охват, но есть риск задеть невиновные соседние IP. |
granular |
отдельный /32 | По одному IP за раз — точно, но медленно против ротации. |
Триггеры (ИЛИ — кандидату достаточно одного)
① Серьёзность набора правил IDS suricata_alert_ct
WHERE alert_ts >= NOW() - INTERVAL {window_min} MINUTE
AND severity <= {sev_max} -- crit=1, warn=2 (Suricata: 1=критическая … 3=низкая)
GROUP BY src_ip HAVING COUNT(*) >= {sev_count}
② Ботнет с ротацией JA3 suricata_tls_ct
WHERE event_ts >= NOW() - INTERVAL {ja3_window_min} MINUTE
AND ja3_hash IS NOT NULL
GROUP BY src_ip HAVING COUNT(DISTINCT ja3_hash) >= {ja3_rotation}
У триггера по серьёзности столбцом времени служит
alert_ts, а триггер JA3 используетevent_ts(они различаются в зависимости от таблицы). Настраивая пороги, помните, по какому столбцу фильтрует каждое окно.
Значения политики по умолчанию (OpsPolicy::autoBlock())
| Ключ настройки | По умолчанию | Ограничение | Смысл |
|---|---|---|---|
autoblock_on |
0 |
— | Главный переключатель (1=включено). По умолчанию выключено |
autoblock_mode |
global |
global|per_server | Режим блокировки |
autoblock_scope |
balanced |
broad|granular|balanced | Охват блокировки |
autoblock_interval_min |
10 |
≥1 | Фактический интервал прогона (мин.) |
autoblock_window_min |
10 |
≥1 | Окно оценки серьёзности (мин.) |
autoblock_sev_on |
1 |
— | Триггер ① включён |
autoblock_severity |
crit |
crit|warn | crit=sev≤1, warn=sev≤2 |
autoblock_sev_count |
1 |
≥1 | Минимум оповещений в окне |
autoblock_ja3_on |
1 |
— | Триггер ② включён |
autoblock_ja3_rotation |
50 |
≥2 | различных отпечатков JA3 ≥ N |
autoblock_ja3_window_min |
360 |
≥1 | Окно оценки JA3 (мин. · 6 ч) |
autoblock_innocent_on |
1 |
— | Вето по невиновности включено |
autoblock_innocent_days |
30 |
≥1 | Срок автоматического внесения в белый список (дни) |
autoblock_reputation_cap |
25 |
0–200 | Запросов репутации за один прогон |
Настройка ротации JA3 (по замерам): на практике нарушители, ротирующие JA3, обычно достигают пика примерно в 32 различных JA3 на одну сессию /32 (боты из ЦОД и облаков, без GREASE = стабильны и поддаются блокировке). Поэтому значение по умолчанию
ja3_rotation=50не перехватывает ничего. Чтобы триггер действительно срабатывал, снизьте его примерно до 15–20. Сначала выполните--dry, чтобы увидеть число кандидатов.
2. Порядок проверки кандидатов (AutoBlockService::run)
Каждый собранный IP-кандидат должен по очереди пройти следующие фильтры, прежде чем он будет действительно заблокирован.
- Исключение внутренней и собственной сети — пропускается, если
SecurityScope::isInternal($ip)(skipped_internal). Это решение объединяет IP-адреса зарегистрированных инстансов (префикс /24 + точный IP) с белым спискомinternal_networksиз операционной политики. На этапе запроса дополнительно заранее исключаетсяexcludePrefixes()черезNOT LIKE. - Оправдание по белому списку — пропускается, если в
infr_whitelistесть активная и не истёкшая запись /32 или /24 (skipped_wl). - Вето по невиновности — применяется только к кандидатам, полученным исключительно по JA3, без жёсткого сигнала (триггера по серьёзности). В пределах бюджета
reputation_capвыполняется запрос репутации AbuseIPDB; если IP безупречно чист (оценка злоупотреблений 0 И жалоб 0 И не Tor), он вместо блокировки автоматически вносится в белый список наinnocent_days(infr_whitelist(source=auto)) (innocent). Кандидаты по серьёзности этот фильтр пропускают и блокируются сразу. - Разрешение server_index —
global→[0],per_server→разрешение целевогоdest_ipчерезServerIndexResolver::byIp(запасной вариант[0]). - Запись — upsert в
infr_blockчерезInfrBlock::updateOrCreate([server_index, cidr], …)сsource='schedule',is_active=true,reason='[InfraGuard Auto] …'.
сбор кандидатов (ИЛИ) → исключение внутренних → белый список → (только JA3) вето по невиновности → server_index → запись в infr_block
isSpotless()возвращает false (то есть блокировать с осторожностью), если запрос репутации завершился ошибкой, не настроен или остался неразрешённым. Оправдание по невиновности — консервативный фильтр, срабатывающий лишь тогда, когда IP явно чист.
3. Планировщик и команда
infr:auto-block — это однократная команда, которая выполняет одну оценку и завершается; это не демон. Планировщик тикает каждую минуту, однако фактический интервал задаётся параметром autoblock_interval_min.
# Проверить условие запуска (немедленный выход, если политика выключена), затем один раз оценить и записать
php artisan infr:auto-block
# Только подсчитать кандидатов, без записи (для настройки и проверки)
php artisan infr:auto-block --dry
# Принудительно выполнить один прогон в обход условия политики (включение + интервал)
php artisan infr:auto-block --force
# Подавить вывод, если ничего не заблокировано (для запуска по расписанию)
php artisan infr:auto-block --quiet-if-ok
Регистрация в расписании (routes/console.php):
Schedule::command('infr:auto-block --quiet-if-ok')
->everyMinute()
->withoutOverlapping(2)
->onOneServer()
->when($is_leader); // ограничение по ведущему узлу — только один узел на весь парк
Логика условия запуска:
autoblock_on=0→ команда немедленно сообщает «пропущено» (по умолчанию выключено, безопасно).- С момента последнего прогона интервал ещё не истёк → пропуск.
--forceи--dryобходят это условие.
Пример вывода:
infr:auto-block — кандидатов 12 (sev 3 · ja3 9) · заблокировано 7 · wl-skip 1 · internal-skip 2 · innocent 2
4. Путь ① автоблокировка коллектора (Node)
Node-коллекторы на каждом хосте потребляют события Suricata и блокируют напрямую в blacklist_info с гранулярностью /24. Этот путь не зависит от планировщика (путь ②) и работает всегда.
| Коллектор | Уровень | Что обнаруживает |
|---|---|---|
infr_eve_ingest.cjs |
Приём | eve.json от Suricata → загружает suricata_http_ct · suricata_tls_ct · suricata_flow_ct · suricata_alert_ct |
infr_srct_tx.cjs |
Сигнатуры/эвристики | Агрегирует Suricata L7 → обнаружение сканеров и ботов по 5 категориям → blacklist_info /24 |
infr_kts_tx.cjs |
Kitsune ML | conntrack + обнаружение аномалий автокодировщиком (anomaly_score) → blacklist_info /24 |
Пять категорий угроз в srct_tx:
(A) [HTTP] сканер URL .env / .git / wp-login и другие URL с сигнатурой сканера
(B) [HTTP] бот-User-Agent curl / python-requests / sqlmap и другие сигнатуры инструментов
(C) [HTTP] переборное зондирование много ответов 4xx в коротком окне (перебор путей)
(D) [TLS] аномалия JA3 много JA3, отсутствие SNI и другие отпечатки ботнета
(E) [FLOW] аномалия флагов TCP много коротких сканирующих сессий (сканирование портов)
srct_tx также непосредственно перед блокировкой выполняет фильтрацию по белому списку и автоматическое оправдание: запрос репутации AbuseIPDB получают только кандидаты E-only (одиночное короткое сканирование), и если они явно чисты (0 жалоб · оценка злоупотреблений 0 · не Tor), они регистрируются как 30-дневное исключение (infr_whitelist(source=auto)), а блокировка пропускается. При наличии любого жёсткого сигнала (A/A2/B/C/D) блокировка выполняется сразу. Его константы и пороги задаются в разделе Правила и пороги.
5. Путь ③ применение — sync_black → ipset
infr_sync_black.mjs периодически запускается на каждом хосте и синхронизирует оба списка в ipset blacklist ядра.
# Запускать на каждом хосте с его server_index (требуются права root)
node infr_sync_black.mjs sv=4
# crontab (каждые 5 мин., flock предотвращает наложение прогонов)
*/5 * * * * /usr/bin/flock -n /var/run/sync_black.lock \
/usr/bin/node /root/server_monitor/infr_sync_black.mjs sv=4 \
>> /var/log/sync_black.log 2>&1
Поведение:
- Загрузить из
blacklist_info(/24) иinfr_block(/32) записи, гдеserver_index IN (0, <sv>) AND is_active/is_use=1. - Дедупликация balanced — пропустить любой /32, который уже покрыт родительским /24.
- Привести ipset ядра к типу
hash:net(пересоздать, если тип другой), загрузить во временный набор, а затем выполнить атомарную подмену (без простоя). - Убедиться, что правило
iptables -I INPUT -m set --match-set blacklist src -j DROPсуществует (идемпотентно). - Страховочная сетка — приватные (RFC1918), петлевые и собственные сетевые префиксы (
HOME_NET_PREFIX) никогда не загружаются в ipset, даже если они попали в базу данных.
sync_blackтребует прав root и наличия утилит ядраipset/iptables, а ipsetblacklistуже должен существовать на целевом хосте:ipset create blacklist hash:net family inet hashsize 8192 maxelem 65536 iptables -I INPUT -m set --match-set blacklist src -j DROP
Источники данных
Все исходные таблицы и таблицы записей находятся в подключении legacy_glory (база данных, общая для коллекторов и скриптов применения).
| Таблица | Подключение | Роль | Единица |
|---|---|---|---|
suricata_alert_ct |
legacy_glory | Источник триггера по серьёзности (столбцы alert_ts · severity · src_ip · dest_ip · signature) |
— |
suricata_tls_ct |
legacy_glory | Источник триггера ротации JA3 (столбцы event_ts · ja3_hash · src_ip) |
— |
blacklist_info |
legacy_glory | Список автоблокировки коллектора (программы IDS · srct/kts) | /24 |
infr_block |
legacy_glory | Список блокировок, которым владеет планировщик InfraGuard (миграция 000751) | /32·/24 |
infr_whitelist |
legacy_glory | Исключения из блокировки (вручную · автоматическая невиновность · seed) | /32·/24 |
infr_server_index |
default (MAIN) | Разреженное, непоследовательное соответствие server_index ↔ алиас/инстанс (000750) | — |
Схема infr_block (кратко)
| Столбец | Тип | Смысл |
|---|---|---|
server_index |
int | 0=глобально · иначе=сервер, разрешённый через infr_server_index |
cidr |
varchar(43) | отдельный IP (/32) или нормализованный /24 · UNIQUE(server_index,cidr) |
ip |
varchar(45) | исходный IP (для отображения) |
reason |
varchar(500) | обоснование триггера ([InfraGuard Auto] sev1 x3 …) |
source |
varchar(16) | auto · manual · schedule |
is_active |
bool | загружает ли запись sync_black |
expires_at |
datetime | NULL=бессрочно |
last_seen_at |
datetime | последнее повторное обнаружение (решение об очистке) |
Права доступа
У автоблокировки нет пользовательского интерфейса запуска. Соответствующие проверки прав таковы (уровни: demo=1 · staff=5 · admin=10):
| Объект | Требуемый доступ |
|---|---|
| Настройка политики автоблокировки (Операционная политика ▸ Настройки безопасности) | Администратор (Администрирование, уровень ≥5 / admin) |
| Просмотр результатов блокировки (Блок-лист) | Чтение раздела безопасности (staff, уровень ≥2) |
| Ручная блокировка и снятие · запись в Белый список | staff (уровень ≥2) + журнал аудита |
Выполнение планировщиком (infr:auto-block) |
Система (не вошедший пользователь) — с ограничением по ведущему узлу |
Учётные данные, которыми пользуется планировщик, никогда не зашиваются в код — они вынесены в
infr_collector/.env. Учётные данные базы дляsync_blackи префиксы собственной сети точно так же подставляются через переменные окружения или подстановку в мэшапе Инвентарь ▸ Инструменты (без жёсткого зашивания).
Устранение неполадок и FAQ
Я включил её, но ничего не блокируется.
- Проверьте число кандидатов через
--dry:php artisan infr:auto-block --dry. - Скорее всего, порог JA3 слишком высок (по умолчанию 50). Реальные нарушители держатся около 32, поэтому снизьте его до 15–20.
- Триггер по серьёзности:
autoblock_severity=critперехватывает только sev≤1 (красный). Чтобы включить оранжевый, задайтеwarn(sev≤2). - Если все кандидаты попадают в
internal-skip/wl-skip, проверьте внутренний белый список в разделе Операционная политика или Белый список.
Блокировки не доходят до реального межсетевого экрана.
- Запись в
infr_blockне применяется, пока не отработаетsync_black. Проверьте cron на целевом хосте, аргументsv=<server_index>и наличие ipsetblacklist. - При охвате
balanced/32, уже покрытый родительским /24, намеренно дедуплицируется и отдельно не загружается (это нормально).
Заблокирован невиновный IP.
- Внесите его как /32 или /24 в Белый список; со следующего прогона он будет исключён (существующую строку
infr_blockснимите через Блок-лист). - Автоматическое оправдание применяется только к кандидатам, полученным исключительно по JA3. IP-адреса, перехваченные триггером по серьёзности, блокируются независимо от репутации, поэтому им требуется ручное исключение.
Режим per_server, но записи попадают как глобальные (server_index=0).
- Если целевой
dest_ipне удаётся разрешить черезinfr_server_index, выполняется безопасный откат к[0]. Проверьте сопоставление IP у коллекторов и инстансов.
Планировщик выполняется сразу на нескольких серверах.
- Ограничение по ведущему узлу
->onOneServer()->when($is_leader)гарантирует, что его выполняет только один узел. Состояние блокировки ведущего узла смотрите на панели наблюдаемости.
Смежные темы
- Операционная политика — главный переключатель автоблокировки, триггеры, охват (вкладка «Настройки безопасности»)
- Блок-лист и репутация — список результатов автоблокировки, причины, снятие
- Белый список — исключённые IP/CIDR, автоматическое исключение по невиновности
- Обнаружения ▸ ИИ JA3 — источник триггера ротации JA3
- Угрозы — источник триггера по серьёзности IDS
- Репутация IP (AbuseIPDB) — запрос репутации для вето по невиновности

