Betrieb
Log-Rotation
Der Daemon handhabt beide gängigen Rotation-Muster:
- Rotate-and-Rename (Access-Log wird umbenannt, eine neue Datei nimmt seinen Platz). Erkannt über Inode-/Device-Wechsel auf dem überwachten Pfad.
- Copytruncate (Datei-Inhalt wird woandershin kopiert, dann das
Original auf Größe Null gestutzt). Erkannt über
tell() > stat().
In beiden Fällen öffnet der Daemon die Datei vom Anfang neu und
schreibt info reopen after rotate dev=… ino=… (Rotate-and-Rename)
oder info truncate file shrank (Copytruncate) auf stderr.
Wenn rund um die Rotation Einträge fehlen, prüfe die Rotation-Tool-Konfiguration:
- Auf OpenBSD
newsyslogist die Standard-Rotation Rotate-and-Rename — keine spezielle Konfiguration nötig. - Auf Linux
logrotatelieber den Default (rotieren + SIGHUP an den Webserver) stattcopytruncate-Modus nehmen. Beides funktioniert, aber Rotate-and-Rename ist günstiger und verliert keine Zeilen.
rc.d-Skript (OpenBSD)
Minimal-Variante /etc/rc.d/abusive_http_watch:
#!/bin/ksh
daemon="/usr/local/sbin/abusive_http_watch"
daemon_flags="/var/www/logs/access.log"
daemon_user="_www"
. /etc/rc.d/rc.subr
rc_bg=YES
rc_reload=NO
rc_cmd $1Dann:
doas rcctl enable abusive_http_watch
doas rcctl start abusive_http_watch
doas rcctl check abusive_http_watchAuf Linux mit systemd siehe die Distributions-Doku; eine einfache
Type=simple-Unit, die auf /usr/local/sbin/abusive_http_watch
mit denselben Argumenten zeigt, reicht.
Syslog-Events
Der Daemon emittiert eine Event-Klasse — added — wenn eine neue
IP die Hit-Schwelle überschreitet. Format:
<syslog-tag>[<pid>]: added ip=<ip> path=<blocklist-pfad>Beispiel:
abusive_http_watch[12345]: added ip=198.51.100.42 path=/var/www/run/abusive_http_hostsPer syslog.conf in eine eigene Datei für Review routen:
local0.notice /var/log/abusive_http.logZusammen mit ABUSIVE_SYSLOG_FACILITY=local0 ergibt das ein
sauberes Audit-Log jeder geblockten IP.
Monitoring-Signale
Für automatisiertes Monitoring sind zwei Indikatoren nützlich:
- Blocklist-Wachstumsrate —
wc -l /var/www/run/abusive_http_hostsüber die Zeit. Auf einem öffentlichen Webserver sollte das stetig wachsen (mehrere IPs pro Tag bis viele pro Stunde, je nach Exposure). Eine 24h-Flatline auf einer Public-Site deutet darauf hin, dass der Daemon nicht läuft oder das falsche Log liest. - Prozess-Health —
pgrep -f abusive_http_watchsollte immer genau eine PID liefern. Alert auf null.
Für Prometheus-Setups reicht ein winziger Exporter, der einfach
die Blocklist-Datei wc -lt und die Zahl als Gauge exponiert.
Kein Metrics-Endpunkt im Daemon selbst — by design, um ihn
dependency-frei zu halten.
Troubleshooting
Die Blocklist-Datei bleibt leer
Mögliche Ursachen, nach Wahrscheinlichkeit:
- Daemon liest die falsche Datei. Im Vordergrund mit
ABUSIVE_DEBUG=1starten. Prüfen, dass erstart following dev=… ino=…für den erwarteten Pfad loggt. Falls nicht, das Argument korrigieren. - Kein echter Angriffstraffic. Unwahrscheinlich auf einem
öffentlichen Webserver, aber bei internem möglich. Mit
ABUSIVE_DEBUG=1laufen lassen und nach[dbg] ip=…-Zeilen ohne entsprechendes[dbg] token matchsuchen. - Whitelist verschluckt alles.
/etc/abusive_http_whitelistprüfen — ein irrtümlicher/0-CIDR-Eintrag whitelisted das ganze Internet. Entfernen und neu starten. - Hit-Schwelle zu hoch.
ABUSIVE_MIN_HITStestweise auf1senken und Verhalten beobachten.
Die Blocklist wächst, aber die Firewall blockt nicht
Der Daemon schreibt die Datei. Die Firewall muss angewiesen werden, sie zu lesen. Prüfen:
- Cron lädt die
pf-Tabelle / dasnftables-Set alle paar Minuten neu (der Daemon ruftpfctlnicht selbst auf). - Die Firewall-Regel, die auf die Tabelle verweist, ist in der
richtigen Chain und
quickgenug, um vor späterenpass-Regeln zu greifen.
Legitime Nutzer werden geblockt
Ihre öffentliche IP oder CIDR-Range zu
/etc/abusive_http_whitelist hinzufügen. Der Daemon liest die
Whitelist bei jeder Zeile neu — Änderungen greifen binnen
Sekunden.
Um eine einzelne IP aus der bestehenden Blocklist zu entfernen, die Datei direkt editieren und die Firewall-Tabelle neu laden. Der Daemon braucht keinen Neustart — er trägt die IP nur dann wieder ein, wenn der Nutzer erneut Token trifft.
Daemon crasht nach Log-Rotation
Sollte mit der oben beschriebenen Rotation-Handhabung nicht
passieren. Wenn doch, im Vordergrund mit ABUSIVE_DEBUG=1 laufen
lassen, eine Rotation auslösen und stderr mitschreiben. Das
mitgeschriebene Log per
Kontakt-Seite schicken —
das ist ein echter Bug, den wir fixen wollen.
Sauberer Shutdown
Der Daemon fängt SIGTERM ab und beendet sich sauber nach der
aktuellen Iteration:
doas rcctl stop abusive_http_watchLoggt [info] TERM received, exiting, schließt das
Logfile-Handle, flusht alle ausstehenden Writes und beendet sich
mit Status 0. Keine State-Korruption, auch bei einem stark
genutzten Log.