TL;DR — Kurzzusammenfassung
Fail2Ban vollständiger Leitfaden: Installation, SSH-Jails, progressives Sperren, benutzerdefinierte Filter, Nginx/Apache/Mail-Schutz und Cloudflare-Integration.
Jeder Linux-Server, der dem Internet ausgesetzt ist, steht unter konstantem Angriff. Automatisierte Bots scannen den gesamten IPv4-Adressraum innerhalb von Stunden und testen Tausende von Benutzername/Passwort-Kombinationen gegen SSH und andere Dienste. Fail2Ban ist ein protokollbasiertes Intrusion-Prevention-Framework, das diese Angriffe in Echtzeit erkennt und die Firewall anweist, die angreifenden IPs zu blockieren — automatisch, ohne manuellen Eingriff. Dieser Leitfaden behandelt die vollständige Fail2Ban-Einrichtung: Installation, SSH-Jail-Konfiguration, progressives Sperren, benutzerdefinierte Filtererstellung, Schutz für Nginx, Apache und Mail-Server sowie Cloudflare-API-Integration.
Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Sie Folgendes haben:
- Einen Linux-Server mit Ubuntu 20.04/22.04/24.04, Debian 11/12 oder RHEL/Rocky/AlmaLinux 8/9
- Root- oder sudo-Zugang
- SSH-Zugang zum Server
- iptables, nftables oder firewalld zur Verwaltung Ihrer Firewall
- Grundlegende Kenntnisse der systemd-Dienstverwaltung
Funktionsweise von Fail2Ban
Fail2Ban arbeitet in einem Überwachen → Abgleichen → Sperren-Zyklus:
- Protokollüberwachung — Der
logtarget-Daemon von Fail2Ban überwacht Protokolldateien (z.B./var/log/auth.log,/var/log/nginx/error.log) mittels inotify oder Polling. - Regex-Abgleich — Jeder Jail referenziert einen Filter mit einem oder mehreren
failregex-Mustern. Wenn eine Protokollzeile übereinstimmt, erhöht Fail2Ban einen Fehlerzähler für die Quell-IP. - Schwellenwertprüfung — Sobald der Zähler
maxretryinnerhalb desfindtime-Fensters erreicht, gilt die IP als feindlich. - Firewall-Sperre — Fail2Ban ruft eine Aktion auf (typischerweise iptables, nftables oder firewalld), um eine DROP-Regel für die angreifende IP einzufügen. Die Regel wird nach
bantimeSekunden automatisch entfernt.
Installation
Ubuntu / Debian
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
RHEL / Rocky / AlmaLinux
Das EPEL-Repository ist erforderlich:
sudo dnf install epel-release -y
sudo dnf install fail2ban -y
sudo systemctl enable --now fail2ban
Auf RHEL-basierten Systemen ist firewalld das Standard-Backend:
sudo dnf install fail2ban-firewalld -y
SSH-Jail-Konfiguration
Bearbeiten Sie niemals /etc/fail2ban/jail.conf direkt — sie wird bei Paket-Updates überschrieben. Erstellen Sie stattdessen Ihre Überschreibungen in /etc/fail2ban/jail.local:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Ein vollständiger, produktionsbereiter SSH-Jail:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
backend = systemd
maxretry = 4
findtime = 1h
bantime = 24h
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
Wichtige Parameter erklärt:
| Parameter | Wert | Bedeutung |
|---|---|---|
maxretry | 4 | Fehlversuche vor der Sperre |
findtime | 1h | Zeitfenster zum Zählen von Fehlern |
bantime | 24h | Sperrdauer der IP |
ignoreip | CIDR-Liste | IPs, die niemals gesperrt werden |
backend | systemd | Protokolle aus journald lesen |
Warnung: Fügen Sie immer Ihre eigene IP oder Ihr Verwaltungssubnetz zu
ignoreiphinzu, bevor Sie strenge Jails aktivieren. Sich auf einer Cloud-VM auszusperren erfordert Konsolenzugang zur Wiederherstellung.
Nach jeder Konfigurationsänderung Fail2Ban neu laden:
sudo fail2ban-client reload
Progressives Sperren
Fügen Sie diese Einstellungen zu [DEFAULT] in jail.local hinzu:
[DEFAULT]
bantime.increment = true
bantime.multipliers = 1 5 30 60 300 720 1440 2880
bantime.maxtime = 5w
bantime.overalljails = true
Mit der Multiplikatorsequenz 1 5 30 60 300 720 1440 2880 und einer Basis-bantime von 10 Minuten:
-
- Sperre: 10 Minuten
-
- Sperre: 50 Minuten
-
- Sperre: 5 Stunden
-
- Sperre: 10 Stunden
-
- Sperre: ~2 Tage
- …bis zu maximal 5 Wochen
Benutzerdefinierte Filter erstellen
Filter befinden sich in /etc/fail2ban/filter.d/. Beispiel für eine Node.js Express API, die folgendes protokolliert:
2026-03-22 14:05:33 [AUTH FAIL] 203.0.113.42 - Invalid token on /api/v1/login
Erstellen Sie /etc/fail2ban/filter.d/myapp-auth.conf:
[Definition]
failregex = ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \[AUTH FAIL\] <HOST> -
ignoreregex =
Testen Sie Ihren Regex vor der Aktivierung:
sudo fail2ban-regex /var/log/myapp/app.log /etc/fail2ban/filter.d/myapp-auth.conf
Nginx-Schutz
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 1h
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 24h
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 10
bantime = 10m
Apache- und Mail-Server-Jails
Apache
[apache-auth]
enabled = true
port = http,https
logpath = /var/log/apache2/error.log
maxretry = 3
[apache-badbots]
enabled = true
port = http,https
logpath = /var/log/apache2/access.log
bantime = 48h
Postfix / Dovecot
[postfix]
enabled = true
port = smtp,465,submission
logpath = /var/log/mail.log
maxretry = 3
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = /var/log/mail.log
maxretry = 3
bantime = 12h
Sperrverwaltung mit fail2ban-client
# Alle aktiven Jails anzeigen
sudo fail2ban-client status
# Gesperrte IPs in einem bestimmten Jail anzeigen
sudo fail2ban-client status sshd
# Eine IP manuell sperren
sudo fail2ban-client set sshd banip 203.0.113.42
# Eine IP entsperren
sudo fail2ban-client set sshd unbanip 203.0.113.42
# Konfiguration ohne Neustart neu laden
sudo fail2ban-client reload
# Alle gesperrten IPs in allen Jails anzeigen
sudo fail2ban-client banned
Aktionskonfiguration
[DEFAULT]
# iptables (klassisch, am kompatibelsten)
banaction = iptables-multiport
# nftables (empfohlen für moderne Distributionen)
banaction = nftables-multiport
# firewalld (RHEL/Rocky)
banaction = firewallcmd-ipset
# E-Mail-Benachrichtigung beim Sperren senden
action = %(action_mwl)s
Filter testen mit fail2ban-regex
# Gegen eine Protokolldatei testen
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# Mit einer einzelnen Protokollzeile testen
sudo fail2ban-regex "Mar 22 14:05:33 server sshd[12345]: Failed password for root from 203.0.113.42 port 54321 ssh2" sshd
Cloudflare-Integration
Option 1 — Echte IPs wiederherstellen über den CF-Connecting-IP-Header:
set_real_ip_from 103.21.244.0/22;
real_ip_header CF-Connecting-IP;
Option 2 — Am Cloudflare-Edge sperren mit der cloudflare-Aktion:
[DEFAULT]
cftoken = IHR_CLOUDFLARE_API_TOKEN
cfzoneid = IHRE_ZONE_ID
[nginx-botsearch]
enabled = true
action = %(action_)s
cloudflare[cftoken="%(cftoken)s", cfzoneid="%(cfzoneid)s"]
Fail2Ban vs. Alternativen
| Tool | Mechanismus | Sprache | Reichweite | Community |
|---|---|---|---|---|
| Fail2Ban | Log-Regex + lokale Firewall | Python | Lokaler Server | Nein |
| CrowdSec | Verhaltensanalyse + geteilte Listen | Go | Multi-Server | Ja |
| DenyHosts | Nur SSH /etc/hosts.deny | Python | Nur SSH | Optional |
| SSHGuard | C-Daemon, Multi-Backend | C | Begrenzte Dienste | Nein |
Produktionshärtungstipps
- Ändern Sie den SSH-Port von 22 auf einen nicht standardmäßigen Port, um automatisches Scan-Rauschen zu reduzieren
- Setzen Sie
bantimeauf mindestens 24h für SSH - Überwachen Sie das Fail2Ban-Protokoll unter
/var/log/fail2ban.log - Sichern Sie
/var/lib/fail2ban/fail2ban.sqlite3, um den Sperrverlauf zu bewahren - Kombinieren Sie mit UFW-Ratenbegrenzung (
sudo ufw limit ssh) für tiefgreifende Verteidigung - Überprüfen Sie Ihre
ignoreip-Liste regelmäßig auf veraltete Einträge
Zusammenfassung
Fail2Ban bietet robusten und automatisierten Brute-Force-Schutz für jeden Linux-Server, der Dienste dem Internet aussetzt. Wichtige Erkenntnisse:
- Fail2Ban überwacht Protokolle, gleicht Fehlermuster mit Regex ab und fügt Firewall-Regeln hinzu, um angreifende IPs zu blockieren
- Bearbeiten Sie niemals
jail.conf— verwenden Siejail.localoder Drop-in-Dateien injail.d/ - Konfigurieren Sie immer
ignoreipmit Ihrer eigenen IP, bevor Sie strenge Jails aktivieren - Progressives Sperren (
bantime.increment) macht hartnäckige Angreifer effektiv dauerhaft gebannt - Verwenden Sie
fail2ban-regex, um Filtermuster vor der Bereitstellung zu testen und zu validieren