InfraGuard

Конвейер автоблокировки

Фоновый процесс защиты, в котором коллекторы и планировщик автоматически вносят в списки IP-адреса атакующих, удовлетворяющие настраиваемым триггерам, и применяют блокировку через ipset ядра.

Обзор — что делает эта функция

Автоблокировка — это фоновый конвейер 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 объединение ①+②

Оба пути непосредственно перед блокировкой выполняют проверку по белому списку и проверку невиновности. Остаётся только подтверждённое злоупотребление; кандидаты, которые с большой вероятностью являются ложными срабатываниями, оправдываются. Путь ② (планировщик) по умолчанию выключен, и его должен включить администратор.

Когда использовать

Устройство

У автоблокировки нет отдельного экрана. Её точки управления и наблюдения таковы:

Как пользоваться

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-кандидат должен по очереди пройти следующие фильтры, прежде чем он будет действительно заблокирован.

  1. Исключение внутренней и собственной сети — пропускается, если SecurityScope::isInternal($ip) (skipped_internal). Это решение объединяет IP-адреса зарегистрированных инстансов (префикс /24 + точный IP) с белым списком internal_networks из операционной политики. На этапе запроса дополнительно заранее исключается excludePrefixes() через NOT LIKE.
  2. Оправдание по белому списку — пропускается, если в infr_whitelist есть активная и не истёкшая запись /32 или /24 (skipped_wl).
  3. Вето по невиновности — применяется только к кандидатам, полученным исключительно по JA3, без жёсткого сигнала (триггера по серьёзности). В пределах бюджета reputation_cap выполняется запрос репутации AbuseIPDB; если IP безупречно чист (оценка злоупотреблений 0 И жалоб 0 И не Tor), он вместо блокировки автоматически вносится в белый список на innocent_days (infr_whitelist(source=auto)) (innocent). Кандидаты по серьёзности этот фильтр пропускают и блокируются сразу.
  4. Разрешение server_index — global→[0], per_server→разрешение целевого dest_ip через ServerIndexResolver::byIp (запасной вариант [0]).
  5. Запись — 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);   // ограничение по ведущему узлу — только один узел на весь парк

Логика условия запуска:

Пример вывода:

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

Поведение:

  1. Загрузить из blacklist_info (/24) и infr_block (/32) записи, где server_index IN (0, <sv>) AND is_active/is_use=1.
  2. Дедупликация balanced — пропустить любой /32, который уже покрыт родительским /24.
  3. Привести ipset ядра к типу hash:net (пересоздать, если тип другой), загрузить во временный набор, а затем выполнить атомарную подмену (без простоя).
  4. Убедиться, что правило iptables -I INPUT -m set --match-set blacklist src -j DROP существует (идемпотентно).
  5. Страховочная сетка — приватные (RFC1918), петлевые и собственные сетевые префиксы (HOME_NET_PREFIX) никогда не загружаются в ipset, даже если они попали в базу данных.

sync_black требует прав root и наличия утилит ядра ipset/iptables, а ipset blacklist уже должен существовать на целевом хосте:

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

Я включил её, но ничего не блокируется.

Блокировки не доходят до реального межсетевого экрана.

Заблокирован невиновный IP.

Режим per_server, но записи попадают как глобальные (server_index=0).

Планировщик выполняется сразу на нескольких серверах.

Смежные темы

자동 차단 스위치가 있는 운영 정책 보안 탭
자동 차단 스위치가 있는 운영 정책 보안 탭
자동 차단 결과가 쌓이는 차단 목록
자동 차단 결과가 쌓이는 차단 목록