Configuración
El daemon se configura íntegramente mediante variables de entorno y dos ficheros en disco. No se requiere ningún cambio de código para ajustar el comportamiento.
Variables de entorno
| Variable | Tipo | Por defecto | Propósito |
|---|---|---|---|
ABUSIVE_FAMILY | v4 / v6 / any | any | Restringir matching a una familia de IP. |
ABUSIVE_MIN_HITS | entero ≥ 1 | 3 | Hits desde una fuente antes de escribir la IP a la blocklist. |
ABUSIVE_SCOPE | lista coma | request,ua | Campos del log a evaluar. Válidos: request, ua, referrer. |
ABUSIVE_REFERRER_DOMAINS | lista coma/espacio | (vacío) | Hosts referrer permitidos. Solo relevante si referrer está en ABUSIVE_SCOPE. |
ABUSIVE_SYSLOG_TAG | string | abusive_http_watch | Tag de programa syslog. |
ABUSIVE_SYSLOG_FACILITY | string | daemon | Facility de syslog. local0–local7 para rutados personalizados. |
ABUSIVE_SYSLOG_PRIO | info / notice / warn / err | notice | Prioridad syslog para eventos added. |
ABUSIVE_DEBUG | 0 / 1 | 0 | Trace stderr verboso de cada línea. Útil solo durante scoping. |
Notas
ABUSIVE_MIN_HITS— Ponerlo a1bloquea en el primer hit. Más agresivo, pero aumenta el riesgo de falsos positivos por probes one-shot que luego llegan desde una IP cloud benigna. El default3es un buen compromiso.ABUSIVE_SCOPE—referrerestá desactivado por defecto porque un referrer malicioso puede meter la IP de un visitante en la blocklist por drive-by. Solo activarlo si también se configuraABUSIVE_REFERRER_DOMAINScomo allowlist estricta.ABUSIVE_FAMILY— Útil si quieres correr dos daemons en paralelo: uno para IPv4, otro para IPv6, cada uno con su propia blocklist.
Conjunto de tokens
El conjunto de regex de detección está cableado en el script
(@TOKENS) y cubre ocho clases de ataque — explotación PHP,
probes WordPress, path traversal, rutas sensibles, intentos
RCE/CGI, SQL-injection, probes de bucle de login, inyección
null-byte.
Para ajustarlo:
- Abrir el script.
- Ajustar el array
@TOKENS— añadir patrones, quitar los que disparen falsos positivos en tu entorno. - Reiniciar el daemon.
El conjunto es deliberadamente conservador. Añadir tokens como
/admin, /login o phpmyadmin sin scoping causará falsos
positivos sobre tráfico legítimo.
Fichero whitelist
Ruta: /etc/abusive_http_whitelist
Una entrada por línea. Tres formatos soportados:
# Comentarios permitidos
203.0.113.42 # IPv4 individual
2001:db8::abcd # IPv6 individual (completo o abreviado)
203.0.113.0/24 # CIDR IPv4
2001:db8::/32 # CIDR IPv6Las IPs whitelisteadas se ignoran completamente — no incrementan contadores y nunca acaban en la blocklist, aunque sus peticiones toquen todos los tokens.
Usar la whitelist para:
- IPs públicas de oficina y VPN (operadores disparando scanners por accidente).
- Rangos de IPs de crawlers de buscadores documentados como legítimos (Google, Bing). Probar antes — rara vez necesario porque sus peticiones no tocan tokens de ataque.
- Servicios de monitorización que sondean
/wp-login.phpa propósito.
Fichero blocklist
Ruta: /var/www/run/abusive_http_hosts
Formato: una IP por línea, sin comentarios, sin cabeceras, sin
duplicados. El daemon garantiza dedup vía hash en memoria y
flock(LOCK_EX) al escribir.
El fichero es append-only en runtime — el daemon nunca borra entradas antiguas. Para purgar (p. ej. caducar tras 30 días) usar rotación externa:
# En un cron diario
mv /var/www/run/abusive_http_hosts /var/www/run/abusive_http_hosts.old
touch /var/www/run/abusive_http_hosts
chown _www:_www /var/www/run/abusive_http_hosts
doas rcctl restart abusive_http_watchEsto fuerza al daemon a reconstruir su estado en memoria desde un fichero vacío. El firewall cargará la nueva blocklist (vacía) en el siguiente tick de cron.
Consumo por el firewall
El formato del fichero blocklist es intencionadamente plano para que cualquier capa pueda consumirlo. Integraciones comunes:
OpenBSD pf
table <abusive> persist file "/var/www/run/abusive_http_hosts"
block in quick on egress from <abusive>Recarga de la tabla:
pfctl -t abusive -T replace -f /var/www/run/abusive_http_hostsLinux nftables
table inet filter {
set abusive_v4 {
type ipv4_addr
elements = { ... }
}
chain input {
ip saddr @abusive_v4 drop
}
}Recarga del set vía helper:
nft 'flush set inet filter abusive_v4'
awk '/^[0-9]/ {print}' /var/www/run/abusive_http_hosts | \
xargs -I{} nft 'add element inet filter abusive_v4 { {} }'Apache
<RequireAll>
Require all granted
Require not ip 203.0.113.0/24
# … un Require not ip por entrada de blocklist
</RequireAll>Generado por templater (m4, sed) desde el fichero blocklist
en un cron. Reacciona más lento que la integración con el
firewall, pero funciona cuando no se controla la capa firewall.
nginx
geo $abusive {
default 0;
include /var/www/run/abusive_http_nginx.conf;
}
server {
if ($abusive) { return 444; }
}abusive_http_nginx.conf se genera por template desde el fichero
blocklist.