tags:
- linux
- security
- devops
- fail2ban
-
vps
date: 2026-07-02
Fail2Ban: Präventive Sperrung via Blocklist.de
Diese Notiz beschreibt die präventive Sperrung bekannter Angreifer-IPs von [[blocklist.de]] in [[Fail2Ban]]. Da Fail2Ban standardmäßig Logs parst, simulieren wir hierzu ein "Echtzeit-Log", welches atomar befüllt und per polling-Backend effizient eingelesen wird.
1. Das Download- und Formatierungs-Skript
Um die Zehntausenden IPs extrem performant und ohne CPU-Sprengung zu verarbeiten, nutzen wir awk für eine atomare Erstellung des Logfiles. Das verhindert, dass Fail2Ban unvollständige Dateien liest oder Zeilen überspringt.
Datei: /usr/local/bin/update-blocklist.sh
#!/usr/bin/env bash
set -euo pipefail
LOG_FILE="/var/log/blocklist_de.log"
URL="[https://lists.blocklist.de/lists/all.txt](https://lists.blocklist.de/lists/all.txt)"
TMP_FILE="/tmp/blocklist_de.tmp"
# Aktuellen Zeitstempel im Syslog-Format generieren
TIMESTAMP=$(date '+%b %d %H:%M:%S')
# Download und sofortige Formatierung der gesamten Liste via awk
curl -s "$URL" | awk -v ts="$TIMESTAMP" '/^[0-9]/ {print ts " server blocklist-de[script]: Blocked IP: " $1}' > "$TMP_FILE"
# Datei atomar überschreiben, damit Fail2Ban den Wechsel sauber triggert
mv "$TMP_FILE" "$LOG_FILE"
Skript ausführbar machen:
sudo chmod +x /usr/local/bin/update-blocklist.sh
2. Fail2Ban Konfiguration
Filter definieren
Der Filter muss extrem strikt sein und darf keine komplexen Makros wie %(__prefix_line)s enthalten, da der Python-Parser sonst bei der Masse an IPs mit einer Bad value substitution Exception abstürzt.
Datei: /etc/fail2ban/filter.d/blocklist-de.conf
[Definition]
failregex = ^.*server blocklist-de\[script\]: Blocked IP: <HOST>$
ignoreregex =
Jail einrichten
In der jail.local wird die Jail definiert. Wichtig ist hier das backend = polling, um Fail2Ban zu zwingen, die Datei bei Änderungen komplett von vorn zu lesen.
[!warning] Wichtig Keine Kommentare (mit
#oder;) innerhalb des Konfigurations-Blocks verwenden! Dies führt bei manchen Fail2Ban-Versionen ebenfalls zu Interpolationsfehlern (Bad value substitution).
Datei: /etc/fail2ban/jail.local
[blocklist-de]
enabled = true
port = all
filter = blocklist-de
logpath = /var/log/blocklist_de.log
maxretry = 1
bantime = 86400
findtime = 3600
backend = polling
3. Initialisierung & Troubleshooting
Wenn die Jail neu angelegt wird, ignoriert Fail2Ban bestehende Logeinträge oft, da die Datei-Offsets in der SQLite-Datenbank hinterlegt sind. Um den Import von ~23.000 IPs zu erzwingen, muss die interne Datenbank zurückgesetzt werden.
# 1. Fail2Ban stoppen
sudo systemctl stop fail2ban
# 2. Interne Positions-Datenbank leeren
sudo fail2ban-client flushlogs
# 3. Skript ausführen (erzeugt das frische Log mit aktuellem Timestamp)
sudo /usr/local/bin/update-blocklist.sh
# 4. Dienst wieder starten
sudo systemctl start fail2ban
Syntax- und Match-Test
Falls sich der Fehlerteufel einschleicht, lässt sich die Konfiguration und die Trefferquote wie folgt isoliert prüfen:
# Config-Syntax prüfen
sudo fail2ban-server -t
# Regex-Match gegen das Logfile testen
sudo fail2ban-regex /var/log/blocklist_de.log /etc/fail2ban/filter.d/blocklist-de.conf
Status abfragen
Da das Laden von über 20.000 Regeln in die Firewall (nftables / ipset) die CPU kurz fordert, ca. 30–60 Sekunden warten, dann den Status prüfen:
sudo fail2ban-client status blocklist-de
4. Automatisierung via Cronjob
Die Liste wird einmal täglich nachts um 03:00 Uhr aktualisiert. Danach wird die Jail gezielt neu geladen, damit Fail2Ban den Lesezeiger zurücksetzt.
0 3 * * * /usr/local/bin/update-blocklist.sh && fail2ban-client reload blocklist-de >/dev/null