Abusive HTTP Watch

Abusive HTTP Watch es un daemon OpenBSD ligero que sigue en tiempo real el access log del servidor web, detecta probes HTTP maliciosas a partir de un conjunto curado de tokens y escribe las IPs de origen en un fichero que puede ser consumido directamente por el firewall (p. ej. pf). En producción activa protegiendo tiendas online.

PropiedadValor
Versión2.1.2
PlataformaOpenBSD (integración con RC script)
LenguajePerl 5 (solo biblioteca estándar)
Caso de usoEndurecimiento de tiendas online
EstadoEn producción
  flowchart LR
    A[Logs del servidor web] --> B[Coincidencia de patrón]
    B --> C{"¿Umbral alcanzado?"}
    C -->|Sí| D[Regla PF de bloqueo]
    C -->|No| A
    D --> E[(Tabla de bloqueo)]
    E -->|TTL expirado| F[Liberación automática]

De qué se trata

Las tiendas online y los sitios web en producción son sondeados de manera continua en busca de vulnerabilidades — exploits PHP, probes de login de WordPress, lookups de /etc/passwd, traversal, SQLi, inyección de null-byte. Estas probes dejan un patrón claro de tokens en el access log, independientemente del código HTTP devuelto.

Abusive HTTP Watch sigue el log de forma continua, evalúa cada línea contra un conjunto preciso de tokens y escribe las IPs con hits repetidos en una blocklist append-only que encaja directamente en tablas pf de OpenBSD, directivas Require de Apache o listas deny de nginx.

Categorías de detección

El conjunto de tokens apunta a clases de ataques que aparecen demostrablemente en los logs de producción — deliberadamente conservador para evitar falsos positivos.

  • Explotación PHPallow_url_include, auto_prepend_file, php://input, eval(
  • Probes WordPresswp-admin, wp-login.php y variantes
  • Path traversal../.. y codificaciones comunes
  • Rutas sensibles.env, .git, .svn, id_rsa, /etc/passwd
  • Intentos RCE / CGIcgi-bin, ?cmd=, =shell, eval(
  • Inyección SQLor 1=1 y variantes conservadoras
  • Probes de bucle de login — parámetros back= cascadeados, incluyendo URL-encoded
  • Inyección null-byte%00 en URI

Funcionalidades operativas

  • 🔄 Resistente a la rotación de logs — Detecta tanto la rotación (cambio de inodo) como el copytruncate (pos > size) y se recupera sin perder líneas.
  • 🌍 Dual stack — Soporte nativo IPv4 e IPv6 incluyendo whitelisting por CIDR (p. ej. 203.0.113.0/24, 2001:db8::/32).
  • 🛡️ Solo IPs públicas — Las direcciones privadas RFC 1918, link-local, loopback, multicast y espacio compartido se omiten automáticamente.
  • 🎯 Matching con alcance — Por petición, el matching se restringe a request, user-agent y opcionalmente referrer. El scope referrer está desactivado por defecto para evitar bloqueos drive-by vía páginas de terceros.
  • 🔒 Actualizaciones atómicas de la blocklistflock(LOCK_EX) al escribir, dedup en memoria previene duplicados tras reinicios.
  • 📋 Whitelist con prioridad/etc/abusive_http_whitelist acepta IPs sueltas o CIDRs que siempre se dejan pasar.
  • ⏳ Umbral de hits — Una IP solo entra en la blocklist tras MIN_HITS hits (por defecto 3) — protege contra singletons accidentales.
  • 📡 Integración con syslog — Eventos estructurados (tag, facility, prio configurables vía env) para acciones added y diagnóstico.
  • 🛑 Apagado limpio — SIGTERM se captura, el daemon termina su iteración actual y cierra los handles en orden.

Configuración

Totalmente controlable vía variables de entorno — sin cambios de código requeridos.

VariablePropósitoPor defecto
ABUSIVE_FAMILYFiltro de familia de IP (v4/v6/any)any
ABUSIVE_MIN_HITSUmbral de hits antes de bloquear3
ABUSIVE_SCOPECampos a comparar (request,ua,referrer)request,ua
ABUSIVE_REFERRER_DOMAINSHosts referrer permitidos
ABUSIVE_SYSLOG_TAGTag de syslogabusive_http_watch
ABUSIVE_SYSLOG_FACILITYFacility de syslogdaemon
ABUSIVE_SYSLOG_PRIOPrioridad de syslognotice
ABUSIVE_DEBUGActivar salida debug0

Base tecnológica

Deliberadamente minimalista — solo herramientas base de OpenBSD y módulos estándar de Perl.

ComponenteRol
OpenBSD rc.dCiclo de vida del daemon (start/stop/reload)
Perl 5Runtime — solo stdlib (Fcntl, IO::Handle, Sys::Syslog, Socket)
pfConsumidor firewall de la blocklist (tabla <abusive>)
syslogdAgregación central de eventos
newsyslogRotación de logs — manejada de forma transparente por el watcher

Por qué esto es un tema de CEO

  • 🏷️ Huella de cumplimiento mínima — Solo lee los logs existentes del servidor, escribe un único fichero, sin nube, sin telemetría. Conforme con el RGPD desde el primer momento.
  • 💰 Coste operativo ~0 € — Script en un único fichero, sin contenedores, sin dependencias. Mantenimiento limitado al conjunto de tokens, que cambia raramente.
  • 🔐 Reducción de la superficie de ataque — Las IPs repetidas desaparecen del pool en segundos — la mayoría de los atacantes prueban solo 3–10 rutas antes de pasar a la siguiente IP.
  • 📊 Auditable — 381 líneas de Perl, sin dependencias externas, cada regla de token es una regex comentada. Revisión de código en una sola sesión.
  • 🛠️ Nadie queda bloqueado por error — Whitelist con CIDR IPv4/IPv6 y el umbral de 3 hits previenen que bots de motores de búsqueda o probes accidentales causen daño.

Abusive HTTP Watch — Versión 2.1.2 · Daemon OpenBSD rc.d · En producción en tiendas online · ~380 SLOC Pure Perl