Resumen — qué hace
Security ▸ Detections (/security/detections) es la pantalla insignia de detección de InfraGuard. Reúne tres cosas en una sola vista:
- Narrativa de los algoritmos de detección: ventanas emergentes educativas que explican cómo atrapa las amenazas cada motor (Kitsune ML · heurísticas srct · nginx
is_suspicious· JA3). - Narrativa posterior a la detección: muestra con datos reales las IP anómalas · peticiones web sospechosas · historial de ejecuciones que cada motor capturó en la ventana reciente.
- ★ Conjuntos de reglas de secuencia JA3: una heurística determinista lee la secuencia cronológica de huellas JA3 de una única IP de origen y enumera su «comportamiento anómalo continuo» como conjuntos de reglas profesionales almacenados en
infr_sec_ruleset.
La recolección y el bloqueo automático ya funcionan en el backend (la antigua interfaz de stats-design solo mostraba tablas de cortafuegos y lista negra): el propósito de esta pantalla es sacar a la luz esa telemetría oculta como una narrativa fiable.
Esta pantalla es principalmente de lectura + análisis bajo demanda. Los detectores en sí (kts_tx · srct_tx · eve_ingest) son recolectores Node que se ejecutan bajo pm2 en los hosts de destino; la aplicación solo lee las tablas que ellos rellenan. La aplicación nunca inspecciona tráfico por su cuenta.
La vía de narración por LLM se eliminó el 2026-09-04. Antes, el análisis enviaba el resumen de la secuencia a un adaptador de IA y guardaba su respuesta en texto libre. Lo terminaron tres problemas medidos: la conclusión del LLM («rotación de JA3») era la misma que ya producía un cálculo de proporción de tres líneas, a unos 9.100 tokens por ejecución; el texto libre congelaba el idioma de quien lo escribía, de modo que las sesiones en inglés leían tarjetas en coreano; y el escritor estampaba
provider/modeldesde el adaptador incluso en la ruta de reserva, por lo que 10 de las 13 filas guardadas afirmabanmodel=kimi-k2.6siendo en realidad salida de plantilla. Ahora el análisis es solo heurístico —sin llamadas externas ni coste de tokens— yprovider/modelregistran lo que realmente se ejecutó.
Cuándo usarla
- Para juzgar si una IP concreta es una botnet o un escáner automatizado a partir de su patrón de rotación JA3.
- Para ver de un vistazo qué están capturando ahora mismo los motores IDS / ML / nginx (punto de entrada del triaje).
- Para desplegar recolectores de detección en un host nuevo (copiar el comando pm2 o el código fuente).
- Para convertir a los principales infractores JA3 en conjuntos de reglas con recomendación de bloqueo o denuncia.
- Al llegar desde Overview / Threats mediante un enlace directo para analizar una IP concreta de inmediato (preselección
?ip=).
Disposición
Franja de KPI
| KPI | Significado | Origen |
|---|---|---|
| Anomalías de IA | Anomalías de Kitsune en la ventana seleccionada | recuento de kitsune_detail_log |
| Bloqueos de IA | De esas, is_blocked=1 (umbral + veto cumplidos) |
kitsune_detail_log where is_blocked |
| Web sospechosa | Peticiones nginx is_suspicious=1 en la ventana |
recuento de nginx_meta_ct |
| Conjuntos de reglas | Reglas actualmente activas (status=active) |
infr_sec_ruleset |
Los dos primeros KPI dicen «IA» porque Kitsune es realmente un autocodificador de aprendizaje automático: esa etiqueta es exacta y se mantiene.
Panel de algoritmos de detección (ventanas edu)
Cada tarjeta de motor abre una ventana educativa con principio · qué vigila · consejos. El texto vive en el paquete de idioma estático security.det.edu.*.
- Kitsune: detección de anomalías por conjunto de autocodificadores
- srct: bloqueador automático heurístico de Suricata (5 categorías)
- nginx is_suspicious: marcador de ataque web tras la terminación TLS
- Análisis de secuencias JA3: la estrella de esta pantalla
Guía de despliegue con pm2
Ofrece el comando y el código fuente para desplegar los 5 recolectores de detección como cron de pm2 en un host de destino (véase Orígenes de datos · tabla pm2).
Registro de detección e historial de ejecuciones
- IP anómalas (top de Kitsune): las 50 primeras por
anomaly_score: IP · puntuación · nº de sesiones · marca de bloqueo · run_ts. - Web sospechosa (top de nginx): las 12 primeras coincidencias
is_suspicious: src_ip · hits · última marca de tiempo. - Historial de ejecuciones: las 30 filas más recientes de
kitsune_process_log·srct_process_log(recuentos escaneados/bloqueados · mensaje).
Infractores JA3 y conjuntos de reglas
- Lista de infractores: los 12 principales infractores JA3 en una ventana fija de 6 horas:
ja3_variety·tls_conns·sni_variety· last_ts · país (geo). Se excluye la red propia (IP /24 de instancias registradas). - Tabla de conjuntos de reglas: reglas guardadas (las 60 más recientes): entidad · comportamiento · categoría · gravedad · acción · confianza · origen. Por fila: Activar / Descartar / Eliminar.
Cómo usarla
1) Revisar el estado de detección
El selector de rango (1h / 6h / 24h) superior cambia la ventana de observación (24h por defecto). Los KPI y los registros de detección se recalculan para esa ventana. La página consulta cada ~30 s y el servicio guarda caché durante 30 s.
Solo la lista de infractores corresponde siempre a las últimas 6 horas, sea cual sea el rango. La rotación JA3 se acumula a lo largo de varias horas, así que una ventana corta no revela el patrón (alineado con la ventana JA3 de 360 minutos del bloqueo automático).
2) Ejecutar el análisis de secuencia JA3 (★)
- Elige una IP de la lista de infractores (o llega por enlace directo desde Overview/Threats) y pulsa [Analizar].
- El servidor extrae la secuencia TLS JA3 de esa IP desde
suricata_tls_cten orden cronológico (ventana = política de operaciónsec_ai_window_min, 60 min por defecto · hasta 200 filas). - Si la longitud de la secuencia está por debajo del mínimo (
sec_ai_min_seq, 5 por defecto), se omite coninsufficient_sequence. - La heurística clasifica la secuencia en hallazgos (véase la tabla de reglas más abajo).
- El resultado se guarda como conjuntos de reglas y la lista y el embudo de Overview se actualizan de inmediato.
Ejemplo de respuesta:
{
"ok": true,
"provider": "heuristic",
"model": null,
"saved": 1,
"seq_len": 37,
"findings": [
{ "key": "ja3_rotation",
"params": { "conns": 37, "variety": 34 },
"category": "tls_anomaly",
"severity": "crit", "action": "block", "confidence": 91 }
]
}
El análisis es determinista y gratuito: la misma secuencia produce siempre los mismos conjuntos de reglas, nunca contacta con un servicio externo y funciona sin acceso a la red. Ejecutarlo no cuesta nada, así que puedes volver a analizar con libertad cuando cambien las cifras de un infractor.
Reglas heurísticas
Los hallazgos se construyen a partir de estadísticas de la secuencia (rotation = ja3_variety / seq_len).
| Condición | Conjunto de reglas | Categoría | Gravedad | Acción | Confianza |
|---|---|---|---|---|---|
| variety ≥ 3 Y rotation ≥ 0,5 | Rotación de JA3 (escáner automatizado/botnet) | tls_anomaly | rotation≥0,9 → crit; si no, warn | block | 50 + round(rotation×45), máx. 95 |
| URL sensibles observadas (.env·.git·wp-config…) | Sondeo de credenciales/ficheros de configuración | credential_access | crit | block | 88 |
| variety = 1 Y conns ≥ 10 Y sni_variety ≥ 4 | Escaneo multiobjetivo con un solo JA3 | scan | warn | observe | 72 |
| Ninguna de las anteriores | Actividad TLS de referencia | other | info | observe | 40 |
Las URL sensibles se detectan con la expresión regular .env .git wp-config .aws /actuator phpunit /.. shell.php wp-login xmlrpc (a partir del contexto de nginx is_suspicious + suricata_http).
Categorías, gravedades y acciones se validan contra los enum de las columnas antes de insertar (recon · credential_access · exfil · bruteforce · c2 · tls_anomaly · scan · other / info · warn · crit / observe · block · isolate · report).
Redacción de los conjuntos de reglas e idiomas
Un hallazgo se almacena como identidad, no como frase. heuristicFindings() emite {key, params}; la fila conserva rule_key + params (migración 000783) y la redacción se aplica al leer la fila, en el idioma de quien la lee.
- El texto vive en
resources/lang/<locale>/security.phpbajodet.rule.<key>.{name,behavior}, traducido a los 8 idiomas de la consola. - Las columnas
name/behaviorsiguen guardando la versión en inglés como reserva, de modo que exportaciones, auditorías y filas escritas antes de 000783 siguen siendo legibles. Si faltarule_key, o un idioma no tiene la clave, se usa el texto almacenado: la clave en bruto nunca se muestra. - La caché de Detections está segmentada por idioma (
infr:sec:det:<locale>:<range>). Sin eso, una sesión en coreano que caliente la caché de 30 segundos se la entregaría al siguiente lector en inglés, que es justo lo que ocurría.
Las filas creadas antes de 000783 conservan su texto original. La migración recupera
rule_keyúnicamente cuando la evidencia de la propia fila reproduce exactamente la plantilla antigua (sin conjeturas); las filas en texto libre escritas por la antigua vía LLM permanecen congeladas hasta que esa IP se analiza de nuevo y las reemplaza.
3) Gestionar conjuntos de reglas
| Acción | Efecto |
|---|---|
| Activar | status=active (se refleja en el embudo de Overview / narrativa de bloqueo) |
| Descartar | status=dismissed |
| Eliminar | Borra la fila |
Volver a analizar solo reemplaza los conjuntos de reglas de origen automático de esa IP (borra entity_type=ip, entity_key=ip, source=ai y los recrea): las reglas escritas a mano se conservan.
El campo
actionde un conjunto de reglas es una recomendación, no una instrucción. Nada actúa en función de él: el bloqueo automático calcula la rotación JA3 directamente desdesuricata_tls_cty nunca leeinfr_sec_ruleset. Una regla que digaaction=blockno bloquea nada: el bloqueo se realiza desde Blocklist o mediante el planificador de bloqueo automático.
4) Acumulación programada (opcional)
El comando infr:sec-analyze recorre los principales infractores JA3 y acumula conjuntos de reglas. Es un comando de una sola pasada que termina al ejecutarse, por lo que puede programarse con seguridad (no es un demonio).
# Saltarse el interruptor y ejecutar una vez (depuración)
php artisan infr:sec-analyze --force
# Analizar una sola IP (ignora el interruptor)
php artisan infr:sec-analyze --ip=203.0.113.10
- Interruptor: política de operación
sec_ai_schedule_on(0= desactivado por defecto). Cuando está desactivado no hace nada: actívalo en la pestaña de seguridad de Política de operación. - Una ejecución programada analiza los
sec_ai_top_n(10 por defecto) principales infractores. - La tarea se ejecuta cada 30 minutos y, al ser heurística, no consume tokens ni hace llamadas externas. Sigue desactivada por defecto solo porque los conjuntos de reglas son informativos.
5) Copiar los comandos de despliegue pm2
La tarjeta pm2 ofrece [Copiar comando] (línea de ejecución pm2), [Copiar código fuente] (cuerpo del fragmento) y [Rellenar con valores de la instancia y copiar] (sustitución de los tokens HOSTNAME/IP). El código procede del fragmento sembrado en Inventory ▸ Tools (infr_snippet).
Orígenes de datos
Tablas heredadas que se leen (no modificar)
| Tabla | Uso | Recolector que la alimenta |
|---|---|---|
kitsune_detail_log |
IP anómala · anomaly_score · is_blocked | kts_tx |
kitsune_process_log |
Historial de ejecuciones de Kitsune | kts_tx |
srct_process_log |
Historial de ejecuciones de srct | srct_tx |
nginx_meta_ct |
Peticiones web sospechosas (is_suspicious) |
nginx_shipper/aggregator |
suricata_tls_ct |
Secuencia JA3 (ja3_hash · sni · version) | eve_ingest |
suricata_http_ct |
Contexto HTTP para el análisis | eve_ingest |
blacklist_info |
Resultados del bloqueo automático (referencia) | kts_tx · srct_tx |
ip_info_loop |
Enriquecimiento geo/ASN | — |
Tablas nuevas propiedad de la aplicación
infr_sec_ruleset(migraciones 000730 · 000783): conjuntos de reglas. Columnas:entity_type·entity_key·name·behavior·rule_key·params(json) ·category·severity·action·confidence·ja3·sequence(json) ·evidence(json) ·source(ai=derivado por máquina | manual) ·provider·model·status(draft|active|dismissed). La rellenaSecurityAiService::persist().infr_snippet: cuerpos de código fuente para pm2.infr_audit_log: auditasec.ai_analyze·sec.ruleset_save·sec.ruleset_delete. La primera cadena de acción se mantiene sin cambios para no partir en dos el rastro de auditoría existente.
Recolectores de despliegue pm2
| key | Alimenta | Comando de despliegue (cron-restart) |
|---|---|---|
| eve_ingest | suricata_*_ct |
pm2 start infr_eve_ingest.cjs --name infr-eve --cron-restart="0 0 * * 6" |
| kts_tx | kitsune_*_log · blacklist_info |
pm2 start infr_kts_tx.cjs --name infr-kitsune --cron-restart="0 0 * * 2" |
| srct_tx | srct_process_log · blacklist_info |
pm2 start infr_srct_tx.cjs --name infr-srct --cron-restart="0 0 * * 4" |
| sync_black | ipset · iptables |
pm2 start infr_sync_black.mjs --name infr-syncblack --cron-restart="*/5 * * * *" |
| sync_firewall | firewall_status |
pm2 start infr_sync_firewall.cjs --name infr-firewall --cron-restart="0 0 * * 0" |
Servicios y rutas
- DetectionService: construye KPI, registros de detección, infractores y conjuntos de reglas (caché de 30 s por idioma, solo lectura vía
SecurityRepository);phrase()aplica la redacción al leer. - SecurityAiService: secuencia JA3 → hallazgos heurísticos → upsert del conjunto de reglas. No contiene ninguna llamada a un LLM.
- SecurityScope::excludePrefixes(): exclusión de la red propia (IP /24 de instancias registradas + política de operación; sin valores fijos en el código).
| Método | Ruta |
|---|---|
| GET | /security/detections (index) |
| GET | /security/detections/live (sondeo) |
| POST | /security/detections/analyze (analizar) |
| POST | /security/detections/ruleset/save |
| POST | /security/detections/ruleset/delete |
Acceso
| Operación | Control |
|---|---|
| Ver la pantalla | Acceso al área de rol Security (min_req 2): demo (1) no ve el área de seguridad en absoluto; staff (5) · admin (10) pueden verla |
| Analizar / guardar·eliminar reglas | user_level ≥ 2 (canWrite) + auditoría en infr_audit_log |
- El control de escritura se aplica en el
canWrite()del controlador (sesióninfr_user_level ≥ 2): el nivel demo no puede analizar ni editar reglas. - La IP de entrada se valida con
filter_var(FILTER_VALIDATE_IP)(IP no válida → 422). - Toda operación destructiva se escribe en el registro de auditoría → Auditoría.
Resolución de problemas y preguntas frecuentes
El análisis se omite con
insufficient_sequence: la secuencia de esa IP ensuricata_tls_ctestá por debajo desec_ai_min_seq(5 por defecto). Amplía la ventana (sec_ai_window_min, 60 min por defecto) o elige una IP más activa de la ventana de 6 horas de la lista de infractores.
- Una regla antigua aparece en el idioma equivocado: se escribió antes de 000783 y lleva texto congelado. Vuelve a analizar esa IP; la nueva fila guarda
rule_keyy sigue el idioma del lector. Las filas de IP que ya no aparecen pueden eliminarse de la tabla. - Los KPI o las reglas no cambian: se debe a la caché de 30 s más la cadencia de sondeo. El análisis y el guardado de reglas invalidan la caché de inmediato (
flush, en todas las variantes de idioma), así que al refrescar se reflejan. - La lista de infractores está vacía: no hay actividad JA3 en las últimas 6 horas de
suricata_tls_ct, o todo se excluyó como red propia. Verifica que el recolectoreve_ingestesté en marcha. - La tarea programada no hace nada:
sec_ai_schedule_on=0(por defecto). Actívala en la pestaña de seguridad de Política de operación o ejecútala una vez con--force. - Todos los registros de detección están a cero: puede que el proceso pm2 correspondiente haya muerto. Reinícialo con el comando de despliegue de la tarjeta pm2 y revisa el historial de ejecuciones.
Relacionado
- Resumen de seguridad — embudo de defensa
- Amenazas — triaje de amenazas del IDS
- Conjuntos de reglas — catálogo de reglas de detección
- Bloqueo automático
- Lista de bloqueo y reputación
- Política de operación
