Konfiguracja
Daemon jest konfigurowany w całości przez zmienne środowiskowe i dwa pliki na dysku. Bez konieczności zmian w kodzie, aby dostosować zachowanie.
Zmienne środowiskowe
| Zmienna | Typ | Default | Cel |
|---|---|---|---|
ABUSIVE_FAMILY | v4 / v6 / any | any | Ograniczyć matching do rodziny IP. |
ABUSIVE_MIN_HITS | integer ≥ 1 | 3 | Trafienia ze źródła, zanim IP zostanie zapisane na blocklistę. |
ABUSIVE_SCOPE | lista oddzielona przecinkami | request,ua | Które pola loga są oceniane. Dozwolone: request, ua, referrer. |
ABUSIVE_REFERRER_DOMAINS | lista whitespace/przecinek | (puste) | Dozwolone hosty referrer. Istotne tylko, gdy referrer w ABUSIVE_SCOPE. |
ABUSIVE_SYSLOG_TAG | string | abusive_http_watch | Tag programu syslog. |
ABUSIVE_SYSLOG_FACILITY | string | daemon | Facility syslog. local0–local7 dla własnych routingów. |
ABUSIVE_SYSLOG_PRIO | info / notice / warn / err | notice | Priorytet syslog dla eventów added. |
ABUSIVE_DEBUG | 0 / 1 | 0 | Verbose-stderr-trace każdej linii. Sensowne tylko do scopingu. |
Uwagi
ABUSIVE_MIN_HITS— Ustawienie na1blokuje przy pierwszym trafieniu. Agresywniej, ale podnosi ryzyko false-positive przez sondy one-shot z benignych cloud-IP, które później pojawiają się regularnie. Default3to dobry kompromis.ABUSIVE_SCOPE—referrerjest domyślnie wyłączony, ponieważ złośliwy referrer przez drive-by mógłby wepchnąć IP twojego odwiedzającego na blocklistę. Włączać tylko, gdyABUSIVE_REFERRER_DOMAINSjest ustawiony jako ścisła allowlist.ABUSIVE_FAMILY— Przydatne, gdy chce się odzwierciedlić daemona przez dwa procesy: jeden dla IPv4, jeden dla IPv6, każdy z własnym plikiem blocklisty.
Zestaw tokenów
Zestaw regex wykrywania jest na sztywno wpisany w skrypcie (@TOKENS) i pokrywa osiem klas ataków — eksploatacja PHP, sondy WordPress, path-traversal, ścieżki wrażliwe, próby RCE/CGI, SQL-injection, sondy login-loop i null-byte-injection.
Aby dostosować zestaw:
- Otworzyć skrypt.
- Dostosować tablicę
@TOKENS— dodać lub usunąć wzorce, jeśli występują false-positives. - Zrestartować daemona.
Zestaw jest celowo konserwatywny. Dodawanie tokenów typu /admin, /login czy phpmyadmin bez scopingu prowadzi do false-positives na legalnym ruchu.
Plik whitelist
Ścieżka: /etc/abusive_http_whitelist
Jeden wpis na linię. Wspierane są trzy formaty:
# komentarze dozwolone
203.0.113.42 # pojedyncze IPv4
2001:db8::abcd # pojedyncze IPv6 (pełne lub skrócone)
203.0.113.0/24 # IPv4 CIDR
2001:db8::/32 # IPv6 CIDRIP z whitelist są w całości pomijane — nie zwiększają licznika trafień i nigdy nie lądują na blockliście, nawet jeśli ich requesty trafiają w każdy token z zestawu.
Whitelisty używać dla:
- Publicznych IP biura i VPN (operatorzy, którzy nieumyślnie odpalają skanery).
- Dokumentowanych legalnych ranges crawlerów wyszukiwarek (Google, Bing). Najpierw przetestować — rzadko konieczne, bo ich requesty nie trafiają w tokeny ataków.
- Serwisów monitoringowych, które celowo odpytują
/wp-login.php.
Plik blocklisty
Ścieżka: /var/www/run/abusive_http_hosts
Format: jedno IP na linię, bez komentarzy, bez nagłówków, bez duplikatów. Daemon zapewnia deduplikację przez hash in-memory i flock(LOCK_EX) przy zapisie.
Plik jest w czasie działania append-only — stare wpisy nigdy nie są usuwane przez daemona. Do sprzątania (np. wygaszanie wpisów po 30 dniach) używać rotacji zewnętrznej:
# W cron dziennym
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_watchTo wymusza na daemonie odbudowę stanu in-memory z pustego pliku. Firewall ładuje nową (pustą) blocklistę przy następnym ticku crona.
Konsumpcja przez firewall
Format pliku blocklisty jest celowo płaski, aby każda warstwa mogła go skonsumować. Częste integracje:
OpenBSD pf
table <abusive> persist file "/var/www/run/abusive_http_hosts"
block in quick on egress from <abusive>Przeładować tabelę:
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
}
}Set przeładowywany przez helper z pliku:
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
# … jeden Require not ip per wpis blocklisty
</RequireAll>Generowane przez templater (m4, sed) z pliku blocklisty na cronie. Reaguje wolniej niż integracja firewallowa, ale działa, gdy nie kontrolujesz samej warstwy firewall.
nginx
geo $abusive {
default 0;
include /var/www/run/abusive_http_nginx.conf;
}
server {
if ($abusive) { return 444; }
}abusive_http_nginx.conf jest generowany przez template z pliku blocklisty.