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

BASH
#!/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:

BASH
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

TXT
[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

TXT
[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.

BASH
# 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:

BASH
# 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:

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

PLAINTEXT
0 3 * * * /usr/local/bin/update-blocklist.sh && fail2ban-client reload blocklist-de >/dev/null