Visión general: qué hace
La página Lista blanca gestiona las IP y los rangos que deben quedar exentos del canal de bloqueo automático de InfraGuard. Todo lo que se registra aquí pasa a formar la «lista de exenciones» que los recolectores de detección consultan justo antes de bloquear, lo que evita que fuentes de confianza (CDN, API de socios, líneas de la oficina) acaben bloqueadas por un falso positivo.
El concepto central es la caducidad:
expires_ata NULL → exención permanente (nunca caduca). Para fuentes siempre fiables, como los CDN y las líneas de la oficina.expires_atcon una fecha → exención temporal (decae automáticamente pasado ese instante). Para ventanas de investigación breves o para veredictos automáticos de inocencia.
Las exenciones llegan desde tres orígenes:
| Origen | Valor | Significado |
|---|---|---|
| Manual | manual |
Un operador la añade directamente desde la interfaz |
| Automática (inocente) | auto |
srct_tx consulta la reputación de una IP y, si es claramente inocente, registra automáticamente una exención de 30 días |
| Por defecto | seed |
Rangos de CDN/OFFICE antes codificados a mano y migrados por InfrWhitelistSeeder (permanentes) |
La tabla
infr_whitelistreside en la conexiónlegacy_glory(la misma base de datos queblacklist_infoy las tablassuricata_*), no en la de la aplicación. Eso permite que el recolector Nodesrct_txlea esta tabla directamente justo antes de bloquear y escriba en ella las IP inocentes.
Cuándo usarlo
- Evitar falsos positivos: registre por adelantado el tráfico normal (bots de monitorización, rastreadores de socios, retrollamadas de pago) que podría disparar las heurísticas de escaneo o de tasa.
- Excepción temporal durante una investigación: dé a un rango una fecha de caducidad para eximirlo unos pocos días.
- Confiar siempre en el CDN o en la oficina: exima de forma permanente las IP de entrada de Cloudflare/Google/AWS/Akamai o una IP fija de la oficina.
- Revisar los veredictos automáticos: inspeccione, prolongue o elimine las entradas
autoque ha creadosrct_tx. - Desbloquee en la lista de bloqueo una IP bloqueada por error y evite que vuelva a bloquearse (registrando una exención).
Disposición
KPI superiores (5)
Los calcula WhitelistService::summary() con una caché de 30 segundos. Activa = is_active = 1 Y (expires_at IS NULL O expires_at > now).
| KPI | Significado | Cálculo |
|---|---|---|
| Exenciones activas | Total de exenciones vigentes ahora mismo | número de activas |
| Permanentes | Entradas sin caducidad | activas Y expires_at IS NULL |
| Temporales | Entradas que caducarán | activas − permanentes |
| Exención automática | Entradas automáticas con veredicto de inocencia | activas Y source = 'auto' |
| Caducan pronto | Caducan en 7 días | activas Y expires_at <= now+7d |
Lista de exenciones
Una tabla filtrable (25 filas por página). El orden pone primero las permanentes (expires_at IS NULL DESC) → caducidad ascendente → id descendente.
| Columna | Descripción |
|---|---|
| Rango | cidr normalizado (p. ej. 203.0.113.0/24 o 203.0.113.10/32) |
| Nombre | label (p. ej. «Cloudflare», «Oficina») |
| Origen | Distintivo manual / auto / seed |
| Caducidad | Permanente / YYYY-MM-DD HH:MM / n days left / caducada |
| Añadida | created_at |
| Acción | Quitar (cuando se tiene permiso de escritura) |
Filtros: estado (activa · caducada · todas), origen (manual · automática · por defecto · todas) y búsqueda (IP · CIDR · nombre). La lista sondea actualizaciones cada 30 segundos.
Ventana de adición manual
El botón [Add manually] (Añadir manualmente) abre una ventana modal. Campos: IP o CIDR, nombre (opcional) y fecha/hora de caducidad (opcional; en blanco = permanente).
Cómo se usa
1. Añadir una exención manual
- Pulse
[Add manually](Añadir manualmente). - Introduzca una IP o un CIDR. Una IP suelta se normaliza a
/32; un rango se normaliza a su dirección de red (véanse más abajo las reglas de normalización). - Opcionalmente, indique un nombre y una fecha/hora de caducidad. Deje la caducidad en blanco para una exención permanente.
- Pulse
[Add](Añadir). Si ese mismocidrya existe, la entrada se reactiva (is_active=1) y se actualizan su caducidad y su nombre.
2. Reglas de normalización (normalizeCidr)
WhitelistService::normalizeCidr() reescribe la entrada a una forma canónica (independiente del idioma e idéntica al convenio de coincidencia de srct_tx).
203.0.113.10 → 203.0.113.10/32 (una IP suelta pasa a /32)
203.0.113.0/24 → 203.0.113.0/24 (sin cambios)
203.0.113.55/24 → 203.0.113.0/24 (bits de host enmascarados → dirección de red)
10.0.0.5/8 → 10.0.0.0/8
999.1.1.1 → (no válida → null, 422 invalid_ip)
- Solo IPv4. Longitud de prefijo de 0 a 32.
- Antes de guardar, el controlador valida previamente con la expresión regular
^\d{1,3}\.\d{1,3}\.\d{1,3}(\.\d{1,3})?(/\d{1,2})?$, y el servicio remata confilter_var(... FILTER_FLAG_IPV4)+ip2long.
Al añadir un rango
/24puede dejar los bits de host:203.0.113.55/24se guarda automáticamente como203.0.113.0/24(su dirección de red).
3. Cómo indicar la caducidad
- Vacío → permanente (
expires_at = NULL). YYYY-MM-DDoYYYY-MM-DD HH:MM→ se interpreta conCarbon::parse.- Un fallo de interpretación también se convierte en permanente (
parseExpiry→ null).
4. Quitar
La acción de quitar en una fila de la lista llama a remove tras una confirmación. La fila se borra físicamente (no es un borrado lógico). Incluso una entrada de CDN con origen seed puede quitarse, aunque puede volver a crearse en la siguiente ejecución del sembrador.
5. Inocencia automática de srct_tx (origen auto): cómo se rellena
El recolector srct_tx verifica la inocencia con un procedimiento muy estricto justo antes de bloquear una IP con anomalías de escaneo o de tasa, y solo deja aquí una entrada auto cuando el veredicto es seguro.
- Filtro de la lista blanca: si ya está presente en
infr_whitelist(más la lista de CDN incluida en el código), queda exenta y se omite de inmediato. - Consulta de reputación solo para candidatas «solo E»: únicamente se consultan en AbuseIPDB las IP que presentan la señal propensa a falsos positivos de «escaneo corto aislado» (heurística E) y ninguna de las señales duras (A/A2/B/C/D) (claves en turno rotatorio · caché de 6 h · tope por barrido).
- Veredicto de inocencia total: si
abuse_score=0Yreports=0Y no es Tor (o está en lista blanca con puntuación 0), registra automáticamente una exención de 30 días (ip/32) eninfr_whitelist(source=auto)y omite el bloqueo.
La inocencia automática es exclusiva de
srct_tx.kts_tx(Kitsune ML) solo lee y filtra con la lista blanca: no hace consultas de reputación ni registros automáticos.
6. cidrList(): reutilizado para la generación de código
WhitelistService::cidrList() devuelve los CIDR activos y no caducados sin duplicados (caché de 30 segundos). Esa lista se inyecta como origen de la constante CDN_WHITELIST_CIDRS cuando la página Reglas y umbrales genera los guiones de srct_tx/kts_tx, de modo que las exenciones gestionadas en la interfaz llegan al código real del recolector.
Fuentes de datos
Tabla infr_whitelist (conexión: legacy_glory, migración 000734)
| Columna | Tipo | Descripción |
|---|---|---|
id |
bigint PK | |
cidr |
varchar(43) unique | IP normalizada (/32) o red (/n) |
label |
varchar(120) null | qué o quién es |
source |
varchar(12) | manual / auto / seed |
reason |
varchar(500) null | motivo del veredicto automático (puntuación/categoría de reputación) |
country |
varchar(4) null | código de país |
expires_at |
datetime null | NULL = permanente |
is_active |
tinyint(1) | indicador de actividad |
created_by |
int null | id del usuario que la registró |
created_at / updated_at |
timestamps |
Índices: (is_active, expires_at) y source.
infr_whitelistse crea en la base de datoslegacy_glory(GLORY). Silegacy_gloryno está configurada como mysql/mariadb, la migración y el sembrador están protegidos para no hacer nada: la página se muestra, pero los KPI leen 0. En despliegues reales hay que rellenar la conexión GLORY.
Sembrador InfrWhitelistSeeder (source=seed, permanente)
Migra los rangos de CDN/OFFICE antes codificados a mano (es idempotente gracias a firstOrCreate). Incluye los rangos de entrada de Cloudflare, Google, Meta, AWS y Akamai, además de una IP fija de OFFICE.
php artisan db:seed --class=InfrWhitelistSeeder
Modelo · Servicio
- Modelo:
App\Models\Infr\InfrWhitelist(protected $connection = 'legacy_glory'). - Servicio:
App\Services\Security\WhitelistService:summary()(KPI, caché de 30 s),page()(filtrado/paginación),add()/remove()(escrituras),cidrList()(origen para la generación de código) ynormalizeCidr()(SOT estático). - Controlador:
App\Http\Controllers\Security\WhitelistController:index·live·add·remove.
Acceso
| Acción | Nivel mínimo | Notas |
|---|---|---|
| Entrar y ver el área de Seguridad | min_req 2 del menú Seguridad |
demo(1) no ve el menú Seguridad |
| Añadir o quitar de la lista blanca (escritura) | nivel ≥ 2 | WhitelistController::canWrite() = user_level >= 2 |
Esquema de niveles: demo=1 · staff=5 · admin=10. Así pues, staff y admin pueden tanto leer como escribir; un fallo de escritura devuelve 403 forbidden (aviso «No permitido (nivel 2 o superior)»).
Toda escritura queda registrada en InfrAuditLog:
- Añadir →
sec.whitelist_add(target=ip, conid·reactivateden meta). - Quitar →
sec.whitelist_remove(target=ip, coniden meta).
Véase Niveles de acceso para la política completa de niveles y roles, y Registro de auditoría para revisar las escrituras.
Resolución de problemas y preguntas frecuentes
Todos los KPI están a 0 y la lista está vacía
La conexión legacy_glory no está configurada, o la tabla infr_whitelist todavía no existe. Revise los ajustes de la base de datos GLORY y ejecute la migración y el sembrador. Ante errores de base de datos, el servicio devuelve valores vacíos sin romperse.
«No es una IP / CIDR válida» (422)
La entrada no es IPv4 o la longitud del prefijo queda fuera de 0–32. IPv6 no está admitido. Ejemplos: 203.0.113.10, 203.0.113.0/24.
He introducido un /24 pero el rango guardado es distinto
Es lo esperado. Los bits de host se enmascaran hasta la dirección de red (203.0.113.55/24 → 203.0.113.0/24).
¿Volver a añadir la misma IP crea un duplicado?
No. cidr es único, así que la entrada existente se reactiva y se actualizan su caducidad y su nombre (la respuesta trae reactivated: true). Si la entrada existente era seed, el origen sigue siendo seed.
¿Por qué aparecen entradas auto y puedo quitarlas?
srct_tx registró automáticamente, como exención de 30 días, una IP que juzgó claramente inocente. Puede quitarla, pero si esa IP vuelve a marcarse por error puede registrarse de nuevo.
¿Las entradas caducadas desaparecen solas?
La fila permanece, pero deja de contar como «activa» en cuanto pasa su caducidad. Cambie el filtro de estado a caducada o todas para verlas. Para eliminarlas del todo, quítelas.
He eximido una IP y sigue bloqueándose
Compruebe: (1) si el rango normalizado cubre realmente la IP del tráfico (p. ej. /32 frente a /24); (2) la caché de cidrList() (30 s) y si se regeneró el guion del recolector; (3) si ya existe un registro de bloqueo en blacklist_info. Los bloqueos existentes deben liberarse desde la lista de bloqueo.
Relacionado
- Lista de bloqueo y reputación: gestión de la lista de bloqueo (lo contrario de la exención)
- Bloqueo automático: bloqueo automático del planificador (veto por lista blanca o por inocencia)
- Amenazas: triaje de amenazas IDS, detalle por IP
- Reglas y umbrales: constantes de srct_tx/kts_tx + inyección de cidrList
- Reputación de IP: consulta de AbuseIPDB dentro de la aplicación
- Registro de auditoría: auditoría de las operaciones de escritura
