InfraGuard

Canal de bloqueo automático

El flujo de defensa en segundo plano en el que los recolectores y el planificador listan automáticamente las IP atacantes que cumplen los disparadores configurables y las aplican mediante el ipset del kernel.

Visión general: qué hace

El bloqueo automático es el canal en segundo plano de InfraGuard que detecta, verifica y bloquea IP atacantes sin intervención humana. No es una página: es un flujo que atraviesa los recolectores, el planificador y el ipset del kernel. Este artículo documenta esa estructura completa.

El canal tiene dos rutas de bloqueo independientes que convergen en un único punto de aplicación (ipset).

Ruta Se ejecuta como Escribe en Unidad Origen
① Bloqueo automático del recolector Recolectores Node en cada host (srct_tx · kts_tx · eve_ingest) blacklist_info /24 (clase C) Suricata L7 · Kitsune ML
② Bloqueo automático del planificador Aplicación InfraGuard (infr:auto-block → AutoBlockService) infr_block /32 (individual) o /24 suricata_alert_ct · suricata_tls_ct
③ Aplicación (compartida) infr_sync_black.mjs (cron del host) ipset blacklist del kernel hash:net unión de ①+②

Ambas rutas ejecutan una comprobación de lista blanca y de inocencia justo antes de bloquear. Solo sobrevive el abuso confirmado; los candidatos que probablemente sean falsos positivos quedan exculpados. La ruta ② (planificador) está desactivada de forma predeterminada y debe habilitarla un administrador.

Cuándo usarlo

Disposición

El bloqueo automático no tiene una página propia. Sus puntos de control y observación son:

Cómo se usa

1. Ruta ② bloqueo automático del planificador: activar y ajustar

El valor predeterminado es desactivado (autoblock_on=0). Accione el interruptor principal en Política de operaciones ▸ Ajustes de seguridad y, a continuación, ajuste la política.

Modo

Valor Significado
global (predeterminado) Un compromiso observado en un servidor se aplica a toda la flota (server_index=0).
per_server Se aplica solo al servidor atacado: la dest_ip de destino se resuelve a un server_index mediante infr_server_index.

Alcance

Valor El planificador escribe Descripción
balanced (recomendado, predeterminado) /32 individual Los programas de IDS usan /24; InfraGuard añade /32 individuales, y sync_black omite cualquier /32 ya cubierta por una /24.
broad /24 Bloquea toda la clase C: cobertura amplia, pero con riesgo de afectar a IP vecinas inocentes.
granular /32 individual Una IP cada vez: preciso, pero lento frente a la rotación.

Disparadores (OR: a un candidato le basta con uno)

① Gravedad del conjunto de reglas IDS   suricata_alert_ct
   WHERE alert_ts >= NOW() - INTERVAL {window_min} MINUTE
     AND severity <= {sev_max}          -- crit=1, warn=2 (Suricata: 1=crítica … 3=baja)
   GROUP BY src_ip HAVING COUNT(*) >= {sev_count}

② Botnet con rotación de 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}

La columna de marca de tiempo del disparador de gravedad es alert_ts, mientras que el disparador de JA3 usa event_ts (difieren según la tabla). Al ajustar los umbrales, tenga presente sobre qué columna filtra cada ventana.

Valores predeterminados de la política (OpsPolicy::autoBlock())

Clave de ajuste Predeterminado Límite Significado
autoblock_on 0 — Interruptor principal (1=activo). Desactivado por defecto
autoblock_mode global global|per_server Modo de bloqueo
autoblock_scope balanced broad|granular|balanced Alcance del bloqueo
autoblock_interval_min 10 ≥1 Intervalo efectivo de barrido (min)
autoblock_window_min 10 ≥1 Ventana de evaluación de gravedad (min)
autoblock_sev_on 1 — Disparador ① habilitado
autoblock_severity crit crit|warn crit=sev≤1, warn=sev≤2
autoblock_sev_count 1 ≥1 Mínimo de alertas en la ventana
autoblock_ja3_on 1 — Disparador ② habilitado
autoblock_ja3_rotation 50 ≥2 huellas JA3 distintas ≥ N
autoblock_ja3_window_min 360 ≥1 Ventana de evaluación de JA3 (min · 6 h)
autoblock_innocent_on 1 — Veto por inocencia habilitado
autoblock_innocent_days 30 ≥1 Duración de la lista blanca automática (días)
autoblock_reputation_cap 25 0–200 Consultas de reputación por barrido

Ajuste de la rotación de JA3 (medido): en el mundo real, los infractores que rotan JA3 alcanzan un pico de unos 32 JA3 distintos por sesión /32 (bots de centro de datos o nube, sin GREASE = estables y bloqueables). Por tanto, el valor predeterminado ja3_rotation=50 no captura nada. Para que dispare realmente, bájelo a unos 15–20. Ejecute antes --dry para ver el número de candidatos.

2. Orden de verificación de candidatos (AutoBlockService::run)

Cada IP candidata recopilada debe superar estas comprobaciones en orden antes de ser bloqueada realmente.

  1. Exclusión de red interna o propia: se omite si SecurityScope::isInternal($ip) (skipped_internal). Esta decisión une las IP de las instancias registradas (prefijo /24 + IP exacta) con la lista blanca internal_networks de la política de operaciones. La fase de consulta también preexcluye excludePrefixes() mediante NOT LIKE.
  2. Exculpación por lista blanca: se omite si infr_whitelist tiene una entrada /32 o /24 activa y no caducada (skipped_wl).
  3. Veto por inocencia: se aplica solo a los candidatos exclusivamente de JA3 sin señal contundente (disparador de gravedad). Dentro del presupuesto de reputation_cap, consulta la reputación de AbuseIPDB; si la IP está totalmente limpia (puntuación de abuso 0 Y denuncias 0 Y no es Tor), se añade automáticamente a la lista blanca durante innocent_days (infr_whitelist(source=auto)) en lugar de bloquearse (innocent). Los candidatos por gravedad se saltan esta comprobación y se bloquean de inmediato.
  4. Resolución de server_index: global→[0], per_server→resolver la dest_ip de destino mediante ServerIndexResolver::byIp (respaldo [0]).
  5. Escritura: upsert en infr_block mediante InfrBlock::updateOrCreate([server_index, cidr], …) con source='schedule', is_active=true y reason='[InfraGuard Auto] …'.
recopilar candidatos (OR) → excluir internos → lista blanca → (solo JA3) veto por inocencia → server_index → escribir infr_block

isSpotless() devuelve false (es decir, bloquear con cautela) si la consulta de reputación falla, no está configurada o queda sin resolver. La exculpación por inocencia es una comprobación conservadora que solo se activa cuando una IP está claramente limpia.

3. Planificador y comando

infr:auto-block es un comando de una sola pasada que evalúa una vez y termina; no es un demonio. El planificador se activa cada minuto, pero el intervalo efectivo es autoblock_interval_min.

# Comprobar la puerta (sin efecto inmediato si la política está desactivada) y luego evaluar y escribir una vez
php artisan infr:auto-block

# Solo contar candidatos, sin escrituras (para ajuste/validación)
php artisan infr:auto-block --dry

# Forzar una ejecución, saltándose la puerta de la política (activación + intervalo)
php artisan infr:auto-block --force

# Suprimir la salida cuando no se ha bloqueado nada (para programación)
php artisan infr:auto-block --quiet-if-ok

Registro en la programación (routes/console.php):

Schedule::command('infr:auto-block --quiet-if-ok')
    ->everyMinute()
    ->withoutOverlapping(2)
    ->onOneServer()
    ->when($is_leader);   // control por nodo líder: un solo nodo en toda la flota

Lógica de la puerta:

Ejemplo de salida:

infr:auto-block — candidatos 12 (sev 3 · ja3 9) · bloqueados 7 · wl-skip 1 · internal-skip 2 · innocent 2

4. Ruta ① bloqueo automático del recolector (Node)

Los recolectores Node de cada host consumen eventos de Suricata y bloquean directamente en blacklist_info con granularidad /24. Esta ruta es independiente del planificador (ruta ②) y se ejecuta siempre.

Recolector Capa Detecta
infr_eve_ingest.cjs Ingesta eve.json de Suricata → carga suricata_http_ct · suricata_tls_ct · suricata_flow_ct · suricata_alert_ct
infr_srct_tx.cjs Firma/heurística Agrega Suricata L7 → detección de escáneres/bots en 5 categorías → blacklist_info /24
infr_kts_tx.cjs Kitsune ML conntrack + detección de anomalías con autoencoder (anomaly_score) → blacklist_info /24

Las cinco categorías de amenaza de srct_tx:

(A) [HTTP] escáner de URL       .env / .git / wp-login y otras URL con firma de escáner
(B) [HTTP] User-Agent de bot    curl / python-requests / sqlmap y otras firmas de herramientas
(C) [HTTP] sondeo por fuerza    muchas respuestas 4xx en una ventana corta (fuerza bruta de rutas)
(D) [TLS]  anomalía de JA3      muchos JA3, SNI ausente y otras huellas de botnet
(E) [FLOW] anomalía de flags TCP  muchas sesiones de escaneo cortas (escaneo de puertos)

srct_tx también ejecuta el filtrado por lista blanca + la exculpación automática por inocencia justo antes de bloquear: solo los candidatos E-only (escaneo corto en solitario) reciben una consulta de reputación en AbuseIPDB y, si están claramente limpios (0 denuncias · puntuación de abuso 0 · no Tor), se registran como exención de 30 días (infr_whitelist(source=auto)) y se omite el bloqueo. Si hay cualquier señal contundente (A/A2/B/C/D), se bloquea de inmediato. Sus constantes y umbrales se gestionan en Reglas y umbrales.

5. Ruta ③ aplicación: sync_black → ipset

infr_sync_black.mjs se ejecuta periódicamente en cada host y sincroniza ambas listas en el ipset blacklist del kernel.

# Ejecutar por host con su server_index (requiere root)
node infr_sync_black.mjs sv=4

# crontab (cada 5 min, con flock para evitar solapamientos)
*/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

Comportamiento:

  1. Cargar desde blacklist_info (/24) + infr_block (/32) donde server_index IN (0, <sv>) AND is_active/is_use=1.
  2. Deduplicación balanced: omitir cualquier /32 cuya /24 padre ya la cubra.
  3. Forzar el ipset del kernel a hash:net (recrearlo si es de otro tipo), cargar en un conjunto temporal y luego hacer un intercambio atómico (sin cortes).
  4. Asegurar que existe iptables -I INPUT -m set --match-set blacklist src -j DROP (idempotente).
  5. Red de seguridad: los prefijos privados (RFC1918), de bucle invertido y de la red propia (HOME_NET_PREFIX) nunca se cargan en el ipset, aunque se cuelen en la base de datos.

sync_black necesita root además de las herramientas del kernel ipset/iptables, y el ipset blacklist debe existir ya en el host de destino:

ipset create blacklist hash:net family inet hashsize 8192 maxelem 65536
iptables -I INPUT -m set --match-set blacklist src -j DROP

Fuentes de datos

Todas las tablas de origen y de registro residen en la conexión legacy_glory (la base de datos compartida por los recolectores y los scripts de aplicación).

Tabla Conexión Función Unidad
suricata_alert_ct legacy_glory Origen del disparador de gravedad (columnas alert_ts · severity · src_ip · dest_ip · signature) —
suricata_tls_ct legacy_glory Origen del disparador de rotación de JA3 (columnas event_ts · ja3_hash · src_ip) —
blacklist_info legacy_glory Lista de bloqueo automático del recolector (programas IDS · srct/kts) /24
infr_block legacy_glory Lista de bloqueo propiedad del planificador de InfraGuard (migración 000751) /32·/24
infr_whitelist legacy_glory Exenciones de bloqueo (manual · inocencia automática · semilla) /32·/24
infr_server_index default (MAIN) Correspondencia dispersa y no secuencial entre server_index y alias/instancia (000750) —

Esquema de infr_block (resumen)

Columna Tipo Significado
server_index int 0=global · otro=servidor resuelto mediante infr_server_index
cidr varchar(43) IP individual (/32) o /24 normalizada · UNIQUE(server_index,cidr)
ip varchar(45) IP original (visualización)
reason varchar(500) evidencia del disparador ([InfraGuard Auto] sev1 x3 …)
source varchar(16) auto · manual · schedule
is_active bool si sync_black la carga
expires_at datetime NULL=permanente
last_seen_at datetime última redetección (decisión de purga)

Acceso

El bloqueo automático no tiene interfaz de ejecución para el usuario. Las comprobaciones de permisos relevantes son (niveles: demo=1 · staff=5 · admin=10):

Objetivo Acceso requerido
Configuración de la política de bloqueo automático (Política de operaciones ▸ Ajustes de seguridad) Administrador (Administración, nivel ≥5 / admin)
Consulta de los resultados de bloqueo (Lista de bloqueo) Lectura de seguridad (staff, nivel ≥2)
Bloqueo/liberación manual · escrituras en la Lista blanca staff (nivel ≥2) + registro de auditoría
Ejecución del planificador (infr:auto-block) Sistema (no un usuario con sesión iniciada): con control por nodo líder

Las credenciales que usa el planificador nunca están codificadas en el código: se externalizan a infr_collector / .env. Las credenciales de base de datos de sync_black y los prefijos de la red propia se inyectan igualmente mediante variables de entorno o la sustitución de mezcla de Inventario ▸ Herramientas (sin codificarlas en el código).

Resolución de problemas y preguntas frecuentes

Lo he activado, pero no se bloquea nada.

Los bloqueos no llegan al cortafuegos real.

Se ha bloqueado una IP inocente.

Está en per_server, pero los registros aparecen como globales (server_index=0).

El planificador se ejecuta en varios servidores a la vez.

Relacionado

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