# ConfiguraciónTodas las palancas expuestas por el daemon — variables de entorno, rutas de fichero y puntos de integració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 a `1` bloquea 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 default `3` es un buen compromiso.
- **`ABUSIVE_SCOPE`** — `referrer` está 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
  configura `ABUSIVE_REFERRER_DOMAINS` como 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:

1. Abrir el script.
2. Ajustar el array `@TOKENS` — añadir patrones, quitar los que
   disparen falsos positivos en tu entorno.
3. 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 IPv6
```

Las 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.php` a
  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:

```sh
# 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_watch
```

Esto 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`

```pf
table <abusive> persist file "/var/www/run/abusive_http_hosts"
block in quick on egress from <abusive>
```

Recarga de la tabla:

```sh
pfctl -t abusive -T replace -f /var/www/run/abusive_http_hosts
```

### Linux `nftables`

```nft
table inet filter {
  set abusive_v4 {
    type ipv4_addr
    elements = { ... }
  }
  chain input {
    ip saddr @abusive_v4 drop
  }
}
```

Recarga del set vía helper:

```sh
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

```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

```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.
