Daemonul este complet configurabil prin variabile de mediu și două fișiere on-disk. Nu e nevoie de modificare de cod pentru a ajusta comportamentul.

Variabile de mediu

VariabilăTipDefaultScop
ABUSIVE_FAMILYv4 / v6 / anyanyRestricționează matching-ul la o familie de IP.
ABUSIVE_MIN_HITSîntreg ≥ 13Hit-uri de la o sursă înainte ca IP-ul să fie scris în blocklistă.
ABUSIVE_SCOPElistă cu virgulărequest,uaCe câmpuri din log sunt evaluate. Valide: request, ua, referrer.
ABUSIVE_REFERRER_DOMAINSlistă whitespace/virgulă(gol)Host-uri de referrer permise. Relevant doar când referrer în ABUSIVE_SCOPE.
ABUSIVE_SYSLOG_TAGstringabusive_http_watchTag program syslog.
ABUSIVE_SYSLOG_FACILITYstringdaemonFacility syslog. local0local7 pentru rutări proprii.
ABUSIVE_SYSLOG_PRIOinfo / notice / warn / errnoticePrioritate syslog pentru evenimente added.
ABUSIVE_DEBUG0 / 10Trace verbose pe stderr pentru fiecare linie. Util doar pentru scoping.

Note

  • ABUSIVE_MIN_HITS — setat la 1 blochează la primul hit. Mai agresiv, dar crește riscul de false positive prin sonde one-shot de la IP-uri cloud benigne care apar apoi regulat. Default-ul 3 este un compromis bun.
  • ABUSIVE_SCOPEreferrer este implicit oprit, pentru că un referrer rău intenționat ar putea împinge prin drive-by IP-ul unuia dintre vizitatorii voștri pe blocklistă. Activează doar dacă ABUSIVE_REFERRER_DOMAINS este setat ca o allowlist strictă.
  • ABUSIVE_FAMILY — util pentru a oglindi daemonul peste două procese: unul pentru IPv4, unul pentru IPv6, fiecare cu propriul fișier de blocklistă.

Setul de tokenuri

Setul de regex-uri de detecție este cablat în script (@TOKENS) și acoperă opt clase de atac — exploatare PHP, sonde WordPress, path traversal, căi sensibile, tentative RCE/CGI, SQL injection, sonde de login loop și null-byte injection.

Pentru a ajusta setul:

  1. Deschide scriptul.
  2. Ajustează array-ul @TOKENS — adaugă sau scoate pattern-uri, dacă apar false positives.
  3. Restartează daemonul.

Setul este deliberat conservator. Adăugarea de tokenuri precum /admin, /login sau phpmyadmin fără scoping duce la false positives pe trafic legitim.

Fișierul de whitelist

Cale: /etc/abusive_http_whitelist

O intrare pe linie. Sunt susținute trei formate:

# comentariile sunt permise
203.0.113.42                    # IPv4 singular
2001:db8::abcd                  # IPv6 singular (complet sau prescurtat)
203.0.113.0/24                  # IPv4 CIDR
2001:db8::/32                   # IPv6 CIDR

IP-urile pe whitelist sunt sărite complet — nu cresc niciun hit counter și nu ajung niciodată în blocklistă, chiar dacă cererile lor lovesc fiecare token din set.

Folosește whitelist-ul pentru:

  • IP-uri publice de birou și VPN (operatori care declanșează din greșeală scannere).
  • Range-uri de IP-uri de crawler de motor de căutare documentate ca legitime (Google, Bing). Testează întâi — rareori necesar, pentru că cererile lor nu lovesc tokenuri de atac.
  • Servicii de monitoring care interoghează intenționat /wp-login.php.

Fișierul de blocklistă

Cale: /var/www/run/abusive_http_hosts

Format: un IP pe linie, fără comentarii, fără header, fără duplicate. Daemonul asigură dedup prin un hash in-memory și flock(LOCK_EX) la scriere.

Fișierul este append-only la runtime — intrările vechi nu sunt niciodată îndepărtate de daemon. Pentru curățenie (de exemplu expirarea intrărilor după 30 de zile) folosește rotație externă:

# Într-un cron zilnic
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

Asta forțează daemonul să-și reconstruiască starea in-memory dintr-un fișier gol. Firewallul încarcă noua (goală) blocklistă la următorul tick de cron.

Consum de către firewall

Formatul fișierului de blocklistă este deliberat plat, ca să poată fi consumat de orice strat. Integrări curente:

OpenBSD pf

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

Reîncarcă tabelul:

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

Linux nftables

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

Set reîncărcat printr-un helper din fișier:

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 per intrare de blocklistă
</RequireAll>

Generat prin templater (m4, sed) din fișierul de blocklistă pe un cron. Reacționează mai lent decât integrarea de firewall, dar funcționează când nu controlezi nivelul firewallului.

nginx

geo $abusive {
  default 0;
  include /var/www/run/abusive_http_nginx.conf;
}
server {
  if ($abusive) { return 444; }
}

abusive_http_nginx.conf este generat prin template din fișierul de blocklistă.