Jeder Linux-Server mit offenem SSH-Port wird angegriffen. Nicht vielleicht, sondern garantiert, und das innerhalb von Minuten nach dem ersten Start. Automatisierte Bots scannen rund um die Uhr das gesamte IPv4-Netz und probieren Standard-Logins wie root, admin oder ubuntu mit Wörterbuch-Passwörtern durch. Wer in die Logs eines frischen Cloud-Servers schaut, findet dort oft tausende fehlgeschlagene Anmeldeversuche pro Tag. Genau hier setzt Fail2ban an: Das Werkzeug liest Logdateien, erkennt Angriffsmuster und sperrt die angreifende IP-Adresse automatisch über die Firewall.

Diese Anleitung führt Sie in 12 Schritten durch die komplette Einrichtung von Fail2ban auf einem produktiven Linux-Server. Sie lernen, wie Sie Fail2ban installieren, eine sichere jail.local aufbauen, den SSH-Schutz aktivieren, eigene Filter schreiben, wiederholte Angreifer mit der recidive-Jail dauerhaft aussperren und das System mit dem fail2ban-client überwachen. Planen Sie etwa 45 bis 60 Minuten ein. Am Ende läuft ein vollständig funktionierender Brute-Force-Schutz, den Sie auf Debian, Ubuntu, Rocky Linux oder AlmaLinux betreiben können.

Was ist Fail2ban und warum brauchen Sie es 2026?

Fail2ban ist ein in Python geschriebenes Intrusion-Prevention-Framework. Es überwacht Logdateien wie /var/log/auth.log auf verdächtige Muster, etwa wiederholte fehlgeschlagene Logins, und reagiert mit einer konfigurierbaren Aktion. In der Standardkonfiguration ist diese Aktion ein Firewall-Eintrag, der die betreffende IP-Adresse für eine bestimmte Zeit blockiert. Das Prinzip ist simpel und wirkungsvoll: Ein Angreifer, der nach fünf Fehlversuchen für zehn Minuten gesperrt wird, kann pro Stunde nur noch eine Handvoll Passwörter testen statt mehrerer tausend. Ein Brute-Force-Angriff, der ungebremst Stunden dauert, wird dadurch praktisch unmöglich.

Der aktuelle stabile Entwicklungszweig ist Fail2ban 1.1.x, in den Paketquellen der Distributionen finden Sie je nach Version 1.0.x oder 1.1.0. Die 1.x-Reihe brachte gegenüber der lange verbreiteten 0.11-Serie spürbar mehr Leistung beim Verarbeiten großer Logmengen und eine stabilere Anbindung an das systemd-Journal. Fail2ban ist quelloffen, läuft auf praktisch jeder Linux-Distribution und kostet nichts. Genau diese Kombination macht es seit Jahren zum De-facto-Standard für den Schutz einzelner Server und kleiner Flotten.

Warum bleibt das Thema 2026 relevant? Weil sich an der Bedrohungslage nichts entspannt hat. Das BSI dokumentiert in seinem Lagebericht durchschnittlich rund 280.000 neue Schadprogramm-Varianten pro Tag, und automatisierte Angriffe auf exponierte Dienste gehören zum Grundrauschen des Internets. SSH, RDP-Ersatzdienste, Mailserver, Webanwendungen mit Login-Maske: Alles, was eine Authentifizierung hat, wird systematisch attackiert. Fail2ban ersetzt keine ordentliche Härtung wie SSH-Keys oder Zwei-Faktor-Authentifizierung, aber es reduziert die Angriffsfläche drastisch und hält Ihre Logs sauber.

Wie sieht so ein Angriff konkret aus? Ein Blick in /var/log/auth.log eines frisch aufgesetzten Servers zeigt das Muster sofort. Innerhalb weniger Stunden tauchen hunderte Zeilen wie diese auf, jede mit einer anderen Quell-IP, demselben Schema und im Sekundentakt. Genau dieses maschinelle Durchprobieren erkennt Fail2ban anhand der wiederholten Failed password-Einträge und reagiert darauf.

Jun 14 09:12:41 srv sshd[2287]: Failed password for root from 45.148.10.71 port 51234 ssh2
Jun 14 09:12:43 srv sshd[2289]: Failed password for invalid user admin from 193.32.162.143 port 40122 ssh2
Jun 14 09:12:45 srv sshd[2291]: Failed password for invalid user test from 218.92.0.34 port 33890 ssh2
Jun 14 09:12:47 srv sshd[2293]: Failed password for root from 45.148.10.71 port 51240 ssh2

Ein wichtiger Punkt vorab zur Einordnung: Fail2ban ist reaktiv. Es analysiert, was bereits passiert ist, und sperrt im Nachhinein. Gegen einen einzelnen, korrekt geratenen Login hilft es nicht. Die Kombination aus deaktiviertem Passwort-Login, einem starken Ed25519-SSH-Key und Fail2ban als zusätzlicher Schicht ist die Verteidigungsstrategie, die sich in der Praxis bewährt hat. Sicherheit funktioniert in Schichten, nie über ein einzelnes Werkzeug.

Voraussetzungen: Server, Versionen und Zugänge

Bevor Sie loslegen, sollten die folgenden Voraussetzungen erfüllt sein. Diese Anleitung wurde auf Debian 12, Ubuntu 24.04 LTS und Rocky Linux 9 getestet, funktioniert aber sinngemäß auf jeder modernen Distribution mit systemd.

  • Linux-Server mit Root-Zugriff oder einem Benutzer mit sudo-Rechten. Getestet auf Debian 12, Ubuntu 22.04/24.04 LTS, Rocky Linux 9, AlmaLinux 9.
  • Python 3.5 oder neuer. Fail2ban 1.x setzt Python 3 voraus; jede aktuell unterstützte Distribution erfüllt das problemlos.
  • Fail2ban 1.0.x oder 1.1.x aus den Paketquellen oder als Build von GitHub.
  • Eine Firewall-Backend-Komponente: nftables (Standard auf Debian 12 und Ubuntu 22.04+) oder firewalld (Standard auf RHEL-Derivaten wie Rocky und AlmaLinux). iptables funktioniert weiterhin als Kompatibilitäts-Layer.
  • SSH-Zugang, der bereits funktioniert. Richten Sie Fail2ban niemals als Erstes ein, ohne einen funktionierenden zweiten Zugang oder eine Konsole beim Hoster.
  • Grundkenntnisse in der Bearbeitung von Textdateien per nano oder vim sowie im Lesen von Logdateien.

Eine dringende Empfehlung vorweg: Tragen Sie schon jetzt Ihre eigene öffentliche IP-Adresse als spätere Ausnahme ein. Nichts ist ärgerlicher, als sich selbst aus dem eigenen Server auszusperren, weil ein Tippfehler im Passwort dreimal hintereinander passiert. Ihre aktuelle öffentliche IP finden Sie mit einem einzigen Befehl heraus.

# Eigene öffentliche IP-Adresse ermitteln
curl -s https://ifconfig.me
# Beispielausgabe:
# 203.0.113.45

Schritt 1: Fail2ban installieren (Debian, Ubuntu, Rocky)

Die Installation unterscheidet sich je nach Paketmanager. Auf Debian und Ubuntu nutzen Sie apt, auf RHEL-Derivaten dnf zusammen mit dem EPEL-Repository, da Fail2ban dort nicht in den Standardquellen liegt.

# --- Debian 12 / Ubuntu 22.04 / 24.04 ---
sudo apt update
sudo apt install -y fail2ban

# --- Rocky Linux 9 / AlmaLinux 9 ---
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalld

# Version pruefen (auf allen Systemen)
fail2ban-client --version

Die Ausgabe von fail2ban-client --version sollte eine 1.x-Version anzeigen, zum Beispiel:

Fail2Ban v1.0.2

Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors
https://github.com/fail2ban/fail2ban

Auf Debian und Ubuntu wird der Dienst nach der Installation in der Regel automatisch gestartet und für den Autostart aktiviert. Auf Rocky und AlmaLinux müssen Sie den Dienst meist selbst aktivieren. Das holen wir in Schritt 6 nach, nachdem die Konfiguration steht. Wichtig: Starten Sie Fail2ban noch nicht mit Ihren Anpassungen, bevor Ihre eigene IP als Ausnahme eingetragen ist.

Schritt 2: jail.conf verstehen und jail.local anlegen

Fail2ban arbeitet mit zwei Ebenen von Konfigurationsdateien. Die mitgelieferten .conf-Dateien enthalten die Standardwerte und werden bei jedem Paket-Update überschrieben. Ihre eigenen Anpassungen gehören deshalb immer in gleichnamige .local-Dateien. Fail2ban liest zuerst die .conf und überschreibt dann die Werte mit dem, was in der .local steht. Diese Trennung ist die wichtigste Regel im Umgang mit Fail2ban: Bearbeiten Sie niemals direkt die jail.conf.

Die zentralen Dateien und Verzeichnisse im Überblick:

PfadFunktionBearbeiten?
/etc/fail2ban/jail.confStandard-Jails und VorgabewerteNein (wird überschrieben)
/etc/fail2ban/jail.localIhre eigenen Jail-EinstellungenJa
/etc/fail2ban/jail.d/Modulare Jail-Schnipsel (.local)Ja
/etc/fail2ban/fail2ban.confDaemon-Einstellungen (Loglevel, Socket)Über fail2ban.local
/etc/fail2ban/filter.d/Regex-Filter pro DienstEigene .conf hinzufügen
/etc/fail2ban/action.d/Bann-Aktionen (Firewall, Mail)Selten

Legen Sie nun eine leere jail.local an. Eine verbreitete Empfehlung lautet, einfach die komplette jail.conf zu kopieren. Das ist unpraktisch, weil Sie dann hunderte Zeilen pflegen, die Sie nie ändern. Besser ist eine schlanke jail.local, die nur die wenigen Werte enthält, die Sie wirklich anpassen.

# jail.local zur Bearbeitung oeffnen (wird neu angelegt)
sudo nano /etc/fail2ban/jail.local

Schritt 3: Globale [DEFAULT]-Werte festlegen

Der Abschnitt [DEFAULT] in der jail.local setzt Werte, die für alle Jails gelten, solange eine einzelne Jail sie nicht überschreibt. Hier definieren Sie die drei wichtigsten Parameter überhaupt: bantime, findtime und maxretry.

  • maxretry: Wie viele Fehlversuche erlaubt sind, bevor gesperrt wird. Standard in der jail.conf ist 5.
  • findtime: Der Zeitraum, in dem diese Fehlversuche zählen. Standard sind 600 Sekunden (10 Minuten). Fünf Fehlversuche innerhalb von zehn Minuten lösen also einen Bann aus.
  • bantime: Wie lange die IP gesperrt bleibt. Standard sind ebenfalls 600 Sekunden. Für produktive Server sind zehn Minuten oft zu kurz; ein Wert von einer Stunde bis zu einem Tag ist gängig.

Tragen Sie folgenden Block in Ihre jail.local ein. Ersetzen Sie 203.0.113.45 durch Ihre eigene öffentliche IP aus den Voraussetzungen. Mehrere IPs trennen Sie mit Leerzeichen, ganze Netze geben Sie in CIDR-Notation an.

[DEFAULT]
# Eigene IPs und localhost niemals sperren
ignoreip = 127.0.0.1/8 ::1 203.0.113.45

# Bann-Logik
bantime  = 1h
findtime = 10m
maxretry = 5

# Auf systemd-Distributionen das Journal lesen
backend = systemd

# Firewall-Backend: nftables (Debian/Ubuntu) oder firewalld (RHEL)
banaction = nftables-multiport
banaction_allports = nftables-allports

Ein Hinweis zu den Zeitangaben: Fail2ban 1.x versteht Suffixe wie m (Minuten), h (Stunden) und d (Tage). Sie müssen also nicht mehr in Sekunden rechnen. bantime = 1h ist deutlich lesbarer als bantime = 3600. Auf Rocky/AlmaLinux setzen Sie statt nftables-multiport die Werte firewalld-multiport beziehungsweise lassen den banaction weg, da fail2ban-firewalld dort die passende Vorgabe mitbringt.

Schritt 4: Die sshd-Jail aktivieren

In Fail2ban 1.x ist die sshd-Jail vorhanden, aber nicht automatisch aktiv. Sie aktivieren sie explizit in der jail.local. Hängen Sie dazu folgenden Abschnitt an Ihre Datei an:

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s
maxretry = 3
bantime  = 1h

Hier überschreiben wir bewusst maxretry für SSH auf 3 statt der globalen 5, weil bei korrekt eingerichteten SSH-Keys ohnehin niemand drei Fehlversuche braucht. Wenn Sie SSH auf einem nicht standardmäßigen Port betreiben, ersetzen Sie port = ssh durch die konkrete Portnummer, etwa port = 2222. Andernfalls greift der Bann zwar logisch, blockiert aber den falschen Port in der Firewall.

Der Platzhalter %(sshd_log)s löst sich je nach Distribution automatisch auf: Auf Debian/Ubuntu zeigt er auf /var/log/auth.log, auf systemd-Systemen ohne klassische Logdatei greift Fail2ban über backend = systemd direkt auf das Journal zu. Auf Rocky und AlmaLinux liegt das SSH-Log üblicherweise im Journal beziehungsweise unter /var/log/secure. Das ist einer der häufigsten Stolpersteine, dazu mehr im Abschnitt zu den Fallstricken.

Schritt 5: Konfiguration testen, bevor Sie starten

Bevor Sie den Dienst neu starten, prüfen Sie die Konfiguration auf Syntaxfehler. Ein fehlerhafter regulärer Ausdruck oder ein Tippfehler in einem Pfad kann den Start verhindern, und ein nicht laufendes Fail2ban schützt nichts. Der eingebaute Test-Modus liest alle Konfigurationen ein und meldet Probleme, ohne etwas zu sperren.

# Komplette Konfiguration testen
sudo fail2ban-client -t

# Erwartete Ausgabe bei korrekter Konfiguration:
# OK: configuration test is successful

Erscheint stattdessen eine Fehlermeldung mit ERROR, lesen Sie genau, welche Datei und welche Zeile genannt werden. Häufig ist es ein doppelt definierter Abschnitt oder ein ungültiger Wert bei bantime. Beheben Sie den Fehler und führen Sie den Test erneut aus, bis OK erscheint. Erst dann geht es weiter.

Schritt 6: Dienst starten und Status prüfen

Jetzt aktivieren Sie den Dienst und sorgen dafür, dass er nach einem Neustart automatisch wieder hochfährt. Anschließend prüfen Sie mit dem fail2ban-client, ob die SSH-Jail tatsächlich geladen wurde.

# Dienst aktivieren und starten
sudo systemctl enable --now fail2ban

# Status des Dienstes pruefen
sudo systemctl status fail2ban --no-pager

# Aktive Jails auflisten
sudo fail2ban-client status

Die letzte Zeile gibt Ihnen die Liste der aktiven Jails. Die Ausgabe sollte etwa so aussehen:

Status
|- Number of jail:      1
`- Jail list:   sshd

Für Details zu einer einzelnen Jail hängen Sie deren Namen an. Dieser Befehl ist Ihr wichtigstes Diagnosewerkzeug im Alltag und zeigt, wie viele Versuche erkannt und wie viele IPs aktuell gesperrt sind.

sudo fail2ban-client status sshd

# Beispielausgabe:
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     147
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 3
   |- Total banned:     19
   `- Banned IP list:   45.148.10.71 193.32.162.143 218.92.0.34

Schritt 7: Einen Bann live testen

Vertrauen ist gut, ein Funktionstest ist besser. Sie können einen Bann manuell auslösen, um zu sehen, dass die Firewall-Aktion greift. Verwenden Sie dafür eine harmlose Test-IP aus dem Dokumentationsbereich, niemals Ihre eigene.

# Test-IP manuell sperren
sudo fail2ban-client set sshd banip 198.51.100.23

# Pruefen, ob sie in der Bann-Liste auftaucht
sudo fail2ban-client status sshd

# Test-IP wieder entsperren
sudo fail2ban-client set sshd unbanip 198.51.100.23

Erscheint die IP nach banip in der Bann-Liste und verschwindet nach unbanip wieder, funktioniert die Kette aus Erkennung und Firewall-Aktion einwandfrei. Wer ganz sicher gehen will, prüft mit sudo nft list ruleset (nftables) beziehungsweise sudo firewall-cmd --list-rich-rules (firewalld), ob der Eintrag tatsächlich in der Firewall landet. Diese manuelle Probe ist der schnellste Weg, ein falsch konfiguriertes Backend zu entlarven.

Schritt 8: Inkrementelle Bann-Zeiten aktivieren

Ein fester Bann von einer Stunde hält Gelegenheits-Bots auf, aber hartnäckige Angreifer kommen nach Ablauf einfach wieder. Fail2ban kann die Bann-Dauer bei jedem erneuten Verstoß automatisch verlängern. Diese Funktion heißt bantime.increment und ist eines der nützlichsten Features der 1.x-Reihe. Wer dreimal gesperrt wurde, bleibt beim vierten Mal eben deutlich länger draußen.

Ergänzen Sie Ihren [DEFAULT]-Abschnitt um folgende Zeilen:

[DEFAULT]
# ... vorhandene Werte ...

# Bann-Zeit bei Wiederholung erhoehen
bantime.increment = true

# Multiplikator-Formel fuer die Verlaengerung
bantime.factor    = 2

# Obergrenze: maximal eine Woche Sperre
bantime.maxtime   = 1w

Mit diesen Werten verdoppelt sich die Bann-Zeit bei jedem erneuten Verstoß derselben IP, beginnend bei Ihrem bantime von einer Stunde: 1h, 2h, 4h, 8h und so weiter, gedeckelt bei einer Woche. Fail2ban merkt sich die Verstöße in einer kleinen SQLite-Datenbank unter /var/lib/fail2ban/fail2ban.sqlite3, sodass die Historie auch einen Neustart des Dienstes übersteht. Das ist genau das Verhalten, das echte Angreifer frustriert, ohne legitime Nutzer mit einem vergessenen Passwort dauerhaft auszusperren.

Schritt 9: Die recidive-Jail gegen Wiederholungstäter

Die recidive-Jail ist eine elegante Meta-Jail. Sie überwacht nicht den SSH-Dienst, sondern das eigene Fail2ban-Log /var/log/fail2ban.log. Wird eine IP von einer beliebigen anderen Jail mehrfach gesperrt, greift recidive und verhängt einen sehr langen Bann über alle Ports hinweg. So fangen Sie Angreifer ab, die hartnäckig über verschiedene Dienste hinweg probieren.

[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
banaction = %(banaction_allports)s
# Wer innerhalb eines Tages 5-mal gesperrt wurde ...
findtime = 1d
maxretry = 5
# ... fliegt fuer eine Woche komplett raus
bantime  = 1w

Wichtig: Damit recidive überhaupt etwas zu lesen hat, muss Fail2ban in eine echte Logdatei schreiben. Auf reinen systemd-Setups, die nur ins Journal loggen, müssen Sie entweder das Dateilogging in fail2ban.local aktivieren (logtarget = /var/log/fail2ban.log) oder die recidive-Jail auf backend = systemd umstellen. Prüfen Sie nach dem Aktivieren mit sudo fail2ban-client status recidive, ob die Jail sauber geladen wurde. Auf Debian und Ubuntu existiert die Datei standardmäßig, dort funktioniert die obige Konfiguration ohne weitere Anpassung.

Schritt 10: Weitere Dienste schützen (Nginx, Postfix)

SSH ist der wichtigste, aber nicht der einzige angreifbare Dienst. Fail2ban bringt fertige Filter für dutzende Anwendungen mit. Besonders verbreitet sind Jails für Webserver und Mailserver. Wenn Sie einen Nginx Reverse Proxy oder eine Login-geschützte Webanwendung betreiben, lohnt sich der Schutz der Authentifizierung gegen automatisiertes Durchprobieren.

# Schutz fuer HTTP-Basic-Auth hinter Nginx
[nginx-http-auth]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log

# Schutz gegen Bad Bots, die nach Login-Seiten scannen
[nginx-botsearch]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 2

# Mailserver-Schutz gegen SASL-Login-Angriffe
[postfix-sasl]
enabled  = true
port     = smtp,submission,imap,imaps,pop3,pop3s
logpath  = %(postfix_log)s

Aktivieren Sie nur Jails für Dienste, die tatsächlich laufen. Eine Jail, deren Logdatei nicht existiert, führt beim Start zu einer Fehlermeldung. Nach jeder Änderung gilt: testen mit fail2ban-client -t, dann neu laden. Das Neuladen erfolgt im laufenden Betrieb, ohne bestehende Banns zu verlieren.

# Konfiguration neu laden, ohne den Dienst komplett neu zu starten
sudo fail2ban-client reload

# Eine einzelne Jail gezielt neu laden
sudo fail2ban-client reload sshd

Schritt 11: Einen eigenen Filter schreiben

Manchmal gibt es für Ihren Dienst keinen fertigen Filter, etwa für eine selbst geschriebene Anwendung oder ein Nischen-Tool. Dann schreiben Sie einen eigenen. Ein Filter besteht im Kern aus einem regulären Ausdruck mit dem Platzhalter <HOST>, der Fail2ban zeigt, wo in der Logzeile die zu sperrende IP-Adresse steht.

Angenommen, Ihre Anwendung schreibt bei einem fehlgeschlagenen Login eine Zeile wie diese ins Log:

2026-06-14 09:31:02 WARN  Login failed for user admin from 45.148.10.71

Legen Sie eine neue Filterdatei unter /etc/fail2ban/filter.d/meineapp.conf an:

[Definition]
# <HOST> markiert die Position der angreifenden IP
failregex = ^.*Login failed for user .* from <HOST>$
ignoreregex =

Bevor Sie eine Jail dafür anlegen, testen Sie den Filter gegen Ihre echte Logdatei. Das Werkzeug fail2ban-regex zeigt Ihnen genau, wie viele Zeilen der Ausdruck trifft. Das erspart stundenlanges Rätselraten und ist Pflicht bei jedem selbst geschriebenen Filter.

# Filter gegen ein Log testen
sudo fail2ban-regex /var/log/meineapp.log /etc/fail2ban/filter.d/meineapp.conf

# Beispielausgabe (Ausschnitt):
# Results
# =======
# Failregex: 42 total
# |-  #) [# of hits] regular expression
# |   1) [42] ^.*Login failed for user .* from <HOST>$
# `-
# Lines: 1500 lines, 0 ignored, 42 matched, 1458 missed

Trifft der Filter wie erwartet, ergänzen Sie eine passende Jail in der jail.local, die auf den Filter meineapp und Ihre Logdatei verweist. Damit schützen Sie auch Anwendungen, die niemand sonst kennt.

Schritt 12: Monitoring, Benachrichtigungen und Pflege

Ein laufendes Fail2ban will man im Blick behalten. Für den schnellen Überblick reicht der fail2ban-client, für die Langzeitbeobachtung lohnt sich ein Blick ins Log und optional eine E-Mail-Benachrichtigung bei jedem Bann. Letztere richten Sie über die Aktion action_mw ein, die zusätzlich zum Firewall-Bann eine Mail mit Whois-Informationen verschickt.

# Im [DEFAULT]-Abschnitt: E-Mail bei jedem Bann
destemail = [email protected]
sender    = [email protected]
mta       = sendmail
action    = %(action_mw)s

Für die tägliche Pflege haben sich einige Befehle bewährt. Die folgende Tabelle fasst die wichtigsten fail2ban-client-Kommandos zusammen, die Sie im Betrieb immer wieder brauchen.

BefehlWirkung
fail2ban-client statusAlle aktiven Jails auflisten
fail2ban-client status sshdDetails und Bann-Liste einer Jail
fail2ban-client set sshd banip IPIP manuell sperren
fail2ban-client set sshd unbanip IPIP wieder entsperren
fail2ban-client unban --allAlle Banns über alle Jails aufheben
fail2ban-client reloadKonfiguration neu laden
fail2ban-client get sshd bantimeAktuellen Wert einer Einstellung abfragen

Für eine schnelle Auswertung, welche IPs am häufigsten zuschlagen, hilft ein kurzer Einzeiler auf dem Fail2ban-Log. So erkennen Sie Muster und können bei Bedarf ganze Netzbereiche dauerhaft über die ignoreip-Logik oder eine externe Firewall behandeln.

# Top 10 der gesperrten IPs aus dem Log ziehen
sudo zgrep "Ban " /var/log/fail2ban.log* | \
  grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | \
  sort | uniq -c | sort -rn | head -10

Die 6 häufigsten Fehler bei der Fail2ban-Einrichtung

Aus der Praxis kristallisieren sich immer wieder dieselben Stolpersteine heraus. Wer sie kennt, spart sich viel Frust und vermeidet den Klassiker, sich selbst auszusperren.

  • Die eigene IP nicht in ignoreip eingetragen. Der häufigste und ärgerlichste Fehler. Tragen Sie immer zuerst Ihre eigene IP ein und halten Sie einen zweiten Zugang (Hoster-Konsole) bereit.
  • jail.conf direkt bearbeitet. Beim nächsten Paket-Update sind alle Änderungen weg. Nutzen Sie ausschließlich jail.local oder Dateien in jail.d/.
  • Falscher Logpfad oder Backend. Auf reinen systemd-Systemen existiert /var/log/auth.log oft gar nicht. Dann muss backend = systemd gesetzt sein, sonst findet Fail2ban nichts und sperrt nie.
  • SSH läuft auf einem anderen Port, aber die Jail kennt ihn nicht. Der Bann greift dann am falschen Port. Setzen Sie port in der Jail auf Ihren tatsächlichen SSH-Port.
  • Jail für einen nicht installierten Dienst aktiviert. Fehlende Logdateien führen zu Startfehlern. Aktivieren Sie nur Jails für laufende Dienste.
  • bantime zu kurz oder maxretry zu hoch. Wer 600 Sekunden Bann mit zehn Versuchen kombiniert, bremst Angreifer kaum. Drei Versuche und mindestens eine Stunde sind ein vernünftiger Startwert.

Troubleshooting: 8 typische Probleme und ihre Lösung

Wenn etwas nicht funktioniert, hilft systematisches Vorgehen. Die folgende Tabelle deckt die häufigsten Symptome ab und nennt die jeweils erste Maßnahme.

SymptomWahrscheinliche UrsacheLösung
Dienst startet nichtSyntaxfehler in jail.localfail2ban-client -t ausführen, Fehlerzeile lesen
Keine IPs werden gesperrtFalsches Backend oder Logpfadbackend = systemd setzen, Logpfad prüfen
Jail fehlt in der Listeenabled = true vergessenIn jail.local ergänzen, reload
Selbst ausgesperrtEigene IP nicht in ignoreipÜber Hoster-Konsole unbanip
Bann greift, aber Zugriff bleibtFirewall-Backend passt nichtnftables/firewalld-Backend angleichen
recidive findet nichtsKein Dateilog vorhandenlogtarget auf Datei setzen
Filter trifft nichtRegex passt nicht zur LogzeileMit fail2ban-regex testen
Banns nach Neustart wegPersistenz nicht aktivSQLite-DB unter /var/lib/fail2ban prüfen

Wenn gar nichts hilft, ist das Fail2ban-Log selbst die beste Informationsquelle. Setzen Sie in fail2ban.local testweise loglevel = DEBUG und beobachten Sie live mit, was der Daemon tut. So sehen Sie genau, welche Logzeilen gelesen, welche Treffer erkannt und welche Aktionen ausgelöst werden.

# Live ins Fail2ban-Log schauen
sudo tail -f /var/log/fail2ban.log

# Oder, bei reinem systemd-Logging, direkt ins Journal
sudo journalctl -u fail2ban -f

Fortgeschrittene Tipps für den produktiven Einsatz

Hat das Grundgerüst einmal Bestand, lohnt sich der Blick auf einige weiterführende Techniken, die Fail2ban von einem reinen SSH-Schutz zu einer ernsthaften Verteidigungsschicht machen.

Geoblocking und allports-Banns kombinieren

Wer einen Server nur aus Deutschland oder der EU administriert, kann mit banaction_allports arbeitende Jails so konfigurieren, dass wiederholte Angreifer auf allen Ports gesperrt werden. In Kombination mit der recidive-Jail entsteht so ein gestuftes System: kurzer Bann pro Dienst, langer Allports-Bann bei Wiederholung. Echtes Geoblocking gehört in die vorgelagerte Firewall (etwa OPNsense oder pfSense), Fail2ban ergänzt es auf Anwendungsebene.

Anbindung an AbuseIPDB

Fail2ban kann gesperrte IPs automatisch an Reputationsdienste wie AbuseIPDB melden. Dazu legen Sie eine Aktion an, die beim Bann zusätzlich einen API-Aufruf absetzt. Das hilft der gesamten Community, weil andere Betreiber diese IPs dann präventiv blockieren können. Umgekehrt lassen sich AbuseIPDB-Blocklisten über die ignorecommand-Logik einbinden. Achten Sie dabei auf Datenschutz: IP-Adressen sind nach DSGVO personenbezogene Daten, eine Meldung an Dritte braucht eine saubere rechtliche Grundlage, etwa das berechtigte Interesse am Schutz des Systems.

Performance bei großen Logmengen

Auf stark frequentierten Webservern können die Logdateien riesig werden. Das systemd-Backend ist hier in der Regel effizienter als das Pollen klassischer Dateien, weil es Ereignisse direkt aus dem Journal bezieht. Halten Sie zudem maxlines und die Anzahl aktiver Jails im Blick. Jede Jail prüft jede neue Logzeile gegen ihre Regex, viele komplexe Filter kosten CPU. Im Zweifel lieber wenige, präzise Filter als ein Dutzend, das alles abdecken soll.

Sicherheit: CVE-2025-45311 und realistische Erwartungen

Auch ein Sicherheitswerkzeug ist Software und kann Schwachstellen haben. 2025 wurde unter der Kennung CVE-2025-45311 eine mögliche lokale Rechteausweitung über den fail2ban-client in Version 0.11.2 diskutiert. Die Fail2ban-Maintainer bestreiten allerdings, dass es sich um eine echte Code-Schwachstelle handelt, und haben keinen darauf bezogenen Patch veröffentlicht. Die praktische Konsequenz bleibt dieselbe wie immer: Betreiben Sie eine aktuelle Version aus den gepflegten Paketquellen, vermeiden Sie uralte 0.11-Stände und halten Sie das System auf dem Patch-Level Ihrer Distribution.

Wichtiger als jede einzelne CVE ist die richtige Erwartungshaltung. Fail2ban ist kein Allheilmittel. Es schützt nicht gegen verteilte Angriffe von tausenden verschiedenen IPs, gegen die ein einzelner Bann pro Adresse wenig ausrichtet. Es schützt nicht gegen ein schwaches Passwort, das beim ersten Versuch erraten wird. Und es ist kein Ersatz für eine ordentliche Transportverschlüsselung oder eine durchdachte Rechtevergabe. Sehen Sie es als das, was es ist: eine sehr effektive, kostenlose Schicht gegen das automatisierte Grundrauschen, die Ihre Logs sauber hält und die Latte für Angreifer spürbar höher legt.

Komplettes Projekt: Die fertige jail.local

Zum Abschluss hier die vollständige, kommentierte jail.local, wie sie nach allen Schritten dieser Anleitung aussieht. Sie deckt SSH, die recidive-Jail und inkrementelle Banns ab und eignet sich als sofort einsetzbare Vorlage für einen Debian- oder Ubuntu-Server. Passen Sie ignoreip, den SSH-Port und die E-Mail-Adresse an Ihre Umgebung an.

# /etc/fail2ban/jail.local
# Getestet mit Fail2ban 1.x auf Debian 12 / Ubuntu 24.04

[DEFAULT]
# Niemals sperren: localhost und eigene Admin-IP
ignoreip = 127.0.0.1/8 ::1 203.0.113.45

# Grund-Logik
bantime  = 1h
findtime = 10m
maxretry = 5

# Inkrementelle Banns gegen Wiederholungstaeter
bantime.increment = true
bantime.factor    = 2
bantime.maxtime   = 1w

# Journal als Logquelle, nftables als Firewall
backend            = systemd
banaction          = nftables-multiport
banaction_allports = nftables-allports

# Optional: E-Mail bei jedem Bann
# destemail = [email protected]
# action    = %(action_mw)s

[sshd]
enabled  = true
port     = ssh
maxretry = 3
bantime  = 1h

[recidive]
enabled   = true
logpath   = /var/log/fail2ban.log
banaction = %(banaction_allports)s
findtime  = 1d
maxretry  = 5
bantime   = 1w

Speichern, testen, neu laden, fertig: sudo fail2ban-client -t && sudo fail2ban-client reload. Mit dieser Konfiguration ist Ihr Server gegen die übergroße Mehrheit automatisierter Brute-Force-Angriffe geschützt. Wer noch einen Schritt weiter gehen will, deaktiviert den SSH-Passwort-Login vollständig und setzt ganz auf Schlüssel.

Häufig gestellte Fragen (FAQ)

Verlangsamt Fail2ban meinen Server?

In der Praxis kaum spürbar. Fail2ban liest Logzeilen und prüft sie gegen reguläre Ausdrücke, das kostet auf normalen Servern nur Bruchteile der CPU. Erst bei sehr vielen aktiven Jails mit komplexen Filtern und extrem hohem Logaufkommen kann die Last steigen. Das systemd-Backend ist dann die effizientere Wahl gegenüber dem Pollen klassischer Dateien.

Brauche ich Fail2ban, wenn ich nur SSH-Keys nutze?

Es ist weiterhin sinnvoll. Auch mit deaktiviertem Passwort-Login hämmern Bots permanent gegen Ihren SSH-Port und füllen die Logs. Fail2ban sperrt diese Quellen weg, hält die Logs lesbar und reduziert die Angriffsfläche. Die Kombination aus Key-Only-Login und Fail2ban ist der empfohlene Standard.

Wie hebe ich einen versehentlichen Selbst-Bann auf?

Wenn Sie sich ausgesperrt haben, brauchen Sie einen zweiten Weg auf den Server, meist die Web-Konsole Ihres Hosters. Dort führen Sie sudo fail2ban-client set sshd unbanip IHRE_IP aus. Tragen Sie Ihre IP danach unbedingt in ignoreip ein, damit es nicht wieder passiert.

Funktioniert Fail2ban mit nftables oder nur mit iptables?

Beides. Moderne Distributionen wie Debian 12 und Ubuntu 22.04+ nutzen nftables als Standard, RHEL-Derivate setzen auf firewalld. Fail2ban bringt passende Aktionen für alle Backends mit. Wichtig ist nur, dass banaction zum tatsächlich aktiven Firewall-System passt, sonst greift der Bann ins Leere.

Wo speichert Fail2ban die gesperrten IPs?

In einer SQLite-Datenbank unter /var/lib/fail2ban/fail2ban.sqlite3. Dadurch überleben aktive Banns einen Neustart des Dienstes oder des Servers. Die eigentliche Sperre selbst sitzt in der Firewall und wird beim Start aus dieser Datenbank wiederhergestellt.

Kann Fail2ban auch Windows oder Anwendungen ohne Log schützen?

Fail2ban ist für Linux und logbasierte Dienste gebaut. Es braucht eine Logdatei oder das systemd-Journal als Datenquelle. Anwendungen, die gar nichts loggen, lassen sich nicht direkt schützen. Für Windows gibt es eigene Werkzeuge; Fail2ban selbst läuft dort nicht nativ.

Wie viele Fehlversuche sind ein guter maxretry-Wert?

Für SSH mit Key-Login sind 3 ein guter Wert, weil legitime Nutzer praktisch nie scheitern. Für Webanwendungen mit menschlichen Logins können 5 sinnvoller sein, um Tippfehler zu tolerieren. Kombinieren Sie einen niedrigen maxretry immer mit einem ausreichend langen bantime von mindestens einer Stunde.

Ist das Sperren fremder IP-Adressen datenschutzkonform?

Das Sperren zur Abwehr von Angriffen stützt sich in der Regel auf das berechtigte Interesse nach DSGVO am Schutz des eigenen Systems. Heikler wird es beim Melden von IPs an externe Dienste oder beim langen Speichern. Dokumentieren Sie Ihre Logik und Speicherdauer, dann sind Sie auf der sicheren Seite. Im Zweifel klären Sie es mit Ihrem Datenschutzbeauftragten.

Weiterführende Quellen: das offizielle Fail2ban-Projekt auf GitHub, die Fail2ban-Wiki-Dokumentation, die Debian-Manpage zu jail.conf, die offiziellen Release-Hinweise sowie der Lagebericht des BSI zur aktuellen Bedrohungslage in Deutschland.