Jeder Linux-Server mit einem offenen SSH-Port wird angegriffen, und zwar permanent. Sobald eine öffentliche IPv4-Adresse erreichbar ist, beginnen automatisierte Botnetze innerhalb von Minuten, Benutzernamen und Passwörter durchzuprobieren. Eine große SSH-Honeypot-Studie protokollierte insgesamt rund 11 Milliarden Angriffsversuche, davon etwa 7,9 Milliarden reine Brute-Force-Versuche auf Passwörter und Schlüssel. Für einen einzelnen, frisch aufgesetzten Root-Server in einem Wiener Rechenzentrum bedeutet das in der Praxis hunderte bis tausende fehlgeschlagene Login-Versuche pro Tag.

Fail2ban ist die seit Jahren etablierte Antwort darauf. Das Open-Source-Werkzeug liest Ihre Logdateien, erkennt Muster fehlgeschlagener Anmeldungen und sperrt die verantwortlichen IP-Adressen automatisch über die Firewall. Diese Anleitung führt Sie in 12 Schritten von der Installation bis zur produktionsreifen Konfiguration. Sie brauchen dafür rund 30 Minuten, einen Linux-Server und grundlegende Kommandozeilen-Kenntnisse. Am Ende läuft auf Ihrem System ein Schutz, der Brute-Force-Angriffe auf SSH, Webserver und Mailserver eigenständig abwehrt.

Wir arbeiten mit der aktuellen stabilen Fail2ban-Version 1.1.0 und zeigen die Konfiguration für Debian 12 und Ubuntu 24.04 LTS. Alle Befehle, Konfigurationsdateien und Ausgabebeispiele sind so gehalten, dass Sie sie direkt übernehmen können. Am Schluss finden Sie ein komplettes, kommentiertes Beispielprojekt zum Kopieren, eine Troubleshooting-Tabelle und einen Vergleich mit den Alternativen CrowdSec und sshguard.

Was ist Fail2ban und wie funktioniert der Brute-Force-Schutz?

Fail2ban ist ein in Python geschriebener Hintergrunddienst, der kontinuierlich Logdateien und Systemd-Journale überwacht. Es funktioniert nach einem einfachen, aber wirksamen Prinzip: Ein Filter beschreibt per regulärem Ausdruck, wie eine verdächtige Zeile aussieht (etwa “Failed password for root from 203.0.113.5”). Ein Jail verknüpft diesen Filter mit einer Logquelle und einer Aktion. Überschreitet eine IP-Adresse innerhalb eines Zeitfensters die erlaubte Anzahl an Fehlversuchen, schreibt Fail2ban eine Sperrregel in die Firewall.

Drei Parameter steuern dieses Verhalten. maxretry legt fest, wie viele Fehlversuche erlaubt sind. findtime bestimmt das Beobachtungsfenster, innerhalb dessen diese Versuche gezählt werden. bantime gibt an, wie lange die Sperre gilt. Ein Beispiel: Bei maxretry 5, findtime 10 Minuten und bantime 1 Stunde wird eine IP gesperrt, sobald sie innerhalb von 10 Minuten fünfmal scheitert, und bleibt eine Stunde ausgesperrt. Genau diese Werte sind die Standardvorgaben in der mitgelieferten jail.conf.

Der entscheidende Punkt: Fail2ban ersetzt keine starken Passwörter und keine SSH-Schlüssel, sondern reduziert die Angriffsfläche und entlastet Ihre Logs. Wer Brute-Force-Angriffe vollständig ausschließen will, deaktiviert die Passwort-Authentifizierung und nutzt ausschließlich Schlüssel. Fail2ban bleibt trotzdem sinnvoll, weil es Bots frühzeitig blockt, Ihre Logdateien sauber hält und auch andere Dienste wie Webserver-Loginformulare schützt. Mehr Hintergrund zu sicheren Passwörtern und Hashing lesen Sie in unserem Leitfaden zur Passwortsicherheit.

BegriffBedeutungBeispiel
FilterRegulärer Ausdruck, der eine verdächtige Logzeile erkenntfilter.d/sshd.conf
JailVerknüpfung aus Filter, Logquelle und Aktion[sshd]
ActionWas bei einer Sperre passiert (Firewall, E-Mail)nftables-multiport
maxretryErlaubte Fehlversuche vor der Sperre5
findtimeBeobachtungsfenster für die Fehlversuche10m
bantimeDauer der Sperre1h
recidiveSpezial-Jail für Wiederholungstäter1 Woche

Voraussetzungen: Diese Versionen und Zugänge brauchen Sie

Bevor Sie loslegen, stellen Sie sicher, dass die folgenden Komponenten bereitstehen. Die Anleitung ist auf Debian- und Ubuntu-Systeme zugeschnitten, funktioniert aber mit minimalen Anpassungen auch unter Fedora, Rocky Linux oder Arch Linux. Wichtig ist vor allem, dass Sie Root-Rechte besitzen und einen zweiten Zugang zum Server haben, falls Sie sich versehentlich selbst aussperren.

KomponenteEmpfohlene VersionZweck
Linux-ServerDebian 12 oder Ubuntu 24.04 LTSZielsystem
Fail2ban1.1.0 (oder Distro-Paket 1.0.2)Brute-Force-Schutz
Python3.9 oder neuerLaufzeitumgebung
systemd252+ (Journal als Logquelle)Log-Backend
nftables1.0+ (Standard ab Debian 12)Firewall-Backend
OpenSSH-Server9.xZu schützender Dienst
Root-Zugangsudo oder rootInstallation und Konfiguration

Prüfen Sie zuerst, welche Distribution und welcher Kernel laufen. Das stellt sicher, dass die nachfolgenden Pfade und Befehle zu Ihrem System passen.

# Distribution und Version anzeigen
cat /etc/os-release | grep PRETTY_NAME
# Beispielausgabe:
# PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"

# Pruefen, ob systemd das Journal bereitstellt
systemctl --version | head -n 1
# systemd 252 (252.30-1~deb12u2)

# Aktiven SSH-Dienst kontrollieren
systemctl is-active ssh
# active

Ein zweiter, paralleler SSH-Zugang ist die wichtigste Versicherung dieser Anleitung. Öffnen Sie ein zweites Terminalfenster und melden Sie sich erneut am Server an, bevor Sie Sperrregeln aktivieren. So bleiben Sie handlungsfähig, falls eine Fehlkonfiguration Ihre eigene IP-Adresse aussperrt.

Schritt 1: Fail2ban installieren

Fail2ban liegt in den Standard-Paketquellen aller großen Distributionen. Unter Debian und Ubuntu installieren Sie es mit einem einzigen apt-Befehl. Aktualisieren Sie zuerst die Paketlisten, damit Sie die neueste verfügbare Version erhalten.

# Debian / Ubuntu
sudo apt update
sudo apt install -y fail2ban

# Fedora / Rocky / AlmaLinux
sudo dnf install -y fail2ban

# Arch Linux
sudo pacman -S fail2ban

# Installierte Version pruefen
fail2ban-client --version
# Fail2Ban v1.1.0

Die installierte Version hängt von Ihrer Distribution ab. Debian 12 liefert je nach Aktualisierungsstand 1.0.2 oder über die Backports 1.1.0 aus, Ubuntu 24.04 ebenfalls die 1.0.2-Reihe. Für diese Anleitung spielt der genaue Unterschied keine Rolle, da alle gezeigten Optionen ab Version 0.11 unterstützt werden. Wenn Sie unbedingt die allerneueste Version brauchen, finden Sie die offiziellen Releases auf der GitHub-Releaseseite des Projekts.

Schritt 2: Den Dienst starten und den Status prüfen

Auf Debian und Ubuntu startet und aktiviert der Paketmanager Fail2ban meist automatisch. Stellen Sie sicher, dass der Dienst läuft und beim Systemstart geladen wird. Das Kommando enable --now erledigt beides in einem Schritt.

# Dienst starten und fuer den Bootvorgang aktivieren
sudo systemctl enable --now fail2ban

# Laufstatus kontrollieren
sudo systemctl status fail2ban --no-pager
# fail2ban.service - Fail2Ban Service
#      Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled)
#      Active: active (running) since Thu 2026-06-11 09:14:02 CEST

# Server-Status ueber den Client abfragen
sudo fail2ban-client status
# Status
# |- Number of jail:      1
# `- Jail list:           sshd

Standardmäßig ist auf vielen Systemen bereits das sshd-Jail aktiv, weil Debian eine Datei /etc/fail2ban/jail.d/defaults-debian.conf mitliefert. Lassen Sie sich davon nicht verwirren. In den folgenden Schritten überschreiben wir diese Vorgaben mit einer sauberen, eigenen Konfiguration, die Sie vollständig kontrollieren.

Schritt 3: Eine eigene jail.local statt jail.conf anlegen

Die zentrale Konfigurationsdatei /etc/fail2ban/jail.conf wird bei jedem Paket-Update überschrieben. Wer hier Änderungen einträgt, verliert sie beim nächsten Upgrade. Die richtige Vorgehensweise ist deshalb eine Datei jail.local, die Vorrang vor jail.conf hat und bei Updates unangetastet bleibt. Fail2ban liest beide Dateien und lässt die lokalen Einstellungen gewinnen.

# Niemals direkt jail.conf bearbeiten. Stattdessen eine eigene Datei anlegen:
sudo nano /etc/fail2ban/jail.local

# Die Verzeichnisstruktur im Ueberblick:
# /etc/fail2ban/jail.conf      <- Vorlage, nicht bearbeiten
# /etc/fail2ban/jail.local     <- Ihre Einstellungen (Vorrang)
# /etc/fail2ban/jail.d/        <- Distro-Ergaenzungen
# /etc/fail2ban/filter.d/      <- Filter (Regex-Muster)
# /etc/fail2ban/action.d/      <- Aktionen (Firewall, Mail)

Diese Trennung zwischen Vorlage und lokaler Konfiguration ist das wichtigste Muster im Umgang mit Fail2ban. Sie gilt nicht nur für Jails, sondern auch für Filter und Aktionen: Eigene Filter legen Sie in filter.d mit einem neuen Namen ab, eigene Aktionen analog in action.d. Eine vollständige Referenz aller Parameter findet sich in der offiziellen jail.conf-Manpage von Debian.

Schritt 4: Globale Grundeinstellungen festlegen

Im Abschnitt [DEFAULT] Ihrer jail.local setzen Sie die Werte, die für alle Jails gelten, solange ein Jail sie nicht überschreibt. Tragen Sie hier zuerst die Grundparameter und Ihre eigene IP-Adresse als Ausnahme ein. Die ignoreip-Liste schützt Sie davor, sich selbst auszusperren, und sollte Ihre Heim- oder Büro-IP sowie das lokale Netz enthalten.

[DEFAULT]
# Eigene und vertrauenswuerdige IPs niemals sperren
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 203.0.113.7

# Sperrdauer: 1 Stunde
bantime  = 1h

# Beobachtungsfenster: 10 Minuten
findtime = 10m

# Erlaubte Fehlversuche
maxretry = 5

# Logquelle: systemd-Journal
backend  = systemd

# Firewall-Aktion (modernes Debian/Ubuntu)
banaction = nftables-multiport

Ersetzen Sie 203.0.113.7 durch Ihre tatsächliche öffentliche IP-Adresse. Diese ermitteln Sie an Ihrem eigenen Rechner mit curl ifconfig.me. Wenn Sie eine dynamische IP von Ihrem österreichischen Provider beziehen, tragen Sie stattdessen das lokale Netz ein und verlassen sich auf einen zweiten Zugangsweg, etwa die KVM-Konsole Ihres Hosters. Setzen Sie ignoreip nie zu großzügig, denn jede dort gelistete Adresse umgeht den kompletten Schutz.

Schritt 5: Das sshd-Jail aktivieren

Jetzt aktivieren Sie den eigentlichen Schutz für SSH. Hängen Sie den folgenden Abschnitt an Ihre jail.local an. Mit enabled = true schalten Sie das Jail scharf, port = ssh bezieht sich auf den Standardport 22. Falls Sie SSH auf einen anderen Port verlegt haben, tragen Sie hier die konkrete Portnummer ein.

[sshd]
enabled  = true
port     = ssh
filter   = sshd
backend  = systemd
maxretry = 4
findtime = 10m
bantime  = 1h

Die Werte im Jail überschreiben die globalen Vorgaben aus [DEFAULT]. Hier setzen wir maxretry bewusst auf 4, weil SSH-Logins selten versehentlich viermal scheitern. Wer einen exponierten Server in einem Rechenzentrum betreibt, kann maxretry sogar auf 3 senken. Achten Sie darauf, dass backend = systemd gesetzt ist, wenn Ihr System Logs ausschließlich im Journal führt und keine klassische /var/log/auth.log mehr schreibt. Das ist bei aktuellen Ubuntu- und Debian-Installationen zunehmend der Fall.

Schritt 6: Das richtige Log-Backend wählen

Fail2ban kann seine Informationen aus zwei Quellen beziehen: aus klassischen Logdateien wie /var/log/auth.log oder direkt aus dem systemd-Journal. Auf modernen Systemen ist das Journal die zuverlässigere Wahl, weil viele Distributionen das Schreiben in separate Logdateien standardmäßig abgeschaltet haben. Steht das Backend falsch, findet Fail2ban keine Einträge und sperrt niemanden, obwohl der Dienst scheinbar läuft.

# Pruefen, ob das Journal SSH-Ereignisse enthaelt
journalctl -u ssh --since "10 min ago" | grep -i "failed password"

# Falls die klassische Logdatei existiert, ist auch dieses Backend moeglich:
ls -l /var/log/auth.log

# Im Jail dann entweder:
#   backend = systemd
# oder, bei vorhandener Datei:
#   backend = auto
#   logpath = /var/log/auth.log

Im Zweifel ist backend = systemd die robusteste Einstellung für Debian 12 und Ubuntu 24.04. Sie funktioniert unabhängig davon, ob klassische Logdateien existieren, und kommt mit der Log-Rotation ohne zusätzliche Konfiguration zurecht. Genau deshalb haben wir sie schon in Schritt 4 und 5 gesetzt.

Schritt 7: Konfiguration testen und neu laden

Bevor Sie die neue Konfiguration aktivieren, prüfen Sie sie auf Syntaxfehler. Fail2ban bringt dafür einen Testmodus mit, der die Filter gegen Beispieldaten laufen lässt, ohne den Dienst zu stören. Erst wenn der Test sauber durchläuft, laden Sie die Konfiguration neu.

# Gesamte Konfiguration auf Fehler pruefen
sudo fail2ban-client -t
# OK: configuration test is successful

# Den sshd-Filter gegen das Journal testen
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshd.conf
# Beispielausgabe:
# Running tests
# ...
# Lines: 1430 lines, 0 ignored, 58 matched, 1372 missed

# Konfiguration ohne Neustart neu einlesen
sudo fail2ban-client reload

Der Befehl fail2ban-client reload ist dem harten systemctl restart vorzuziehen, weil er bestehende Sperren erhält und keine Lücke öffnet. Schlägt der Test mit einer Fehlermeldung fehl, korrigieren Sie die genannte Zeile in jail.local und wiederholen Sie den Test. Aktivieren Sie nie eine ungetestete Konfiguration auf einem Produktivsystem, vor allem nicht, wenn Sie nur per SSH Zugang haben.

Schritt 8: Sperren prüfen mit fail2ban-client

Sobald Fail2ban läuft, ist fail2ban-client Ihr wichtigstes Werkzeug zur Überwachung. Mit dem Status-Kommando sehen Sie, wie viele IP-Adressen aktuell gesperrt sind und wie viele Fehlversuche insgesamt registriert wurden. Auf einem öffentlich erreichbaren Server füllt sich diese Liste oft schon nach wenigen Minuten.

# Detailstatus des sshd-Jails
sudo fail2ban-client status sshd
# Status for the jail: sshd
# |- Filter
# |  |- Currently failed: 3
# |  |- Total failed:     1847
# |  `- File list:        systemd-journal
# `- Actions
#    |- Currently banned: 12
#    |- Total banned:     143
#    `- Banned IP list:   45.143.200.18 193.32.162.7 218.92.0.34

Die Zeile Total banned zeigt eindrucksvoll, wie viel Datenverkehr ein einzelner Server abwehrt. Werte im Hunderter- oder Tausenderbereich pro Woche sind für eine exponierte IP völlig normal und kein Grund zur Sorge, sondern der Beweis, dass Fail2ban arbeitet. Wie sich diese Bedrohungslage in Österreich entwickelt, ordnen wir in unserer Analyse zur Cyberkriminalität in Österreich ein.

Schritt 9: IP-Adressen entsperren

Früher oder später sperrt Fail2ban eine IP, die Sie eigentlich durchlassen wollten, etwa weil ein Kollege sein Passwort zu oft falsch eingegeben hat. Das manuelle Entsperren ist mit einem einzigen Befehl erledigt. Sie können eine Adresse aus einem bestimmten Jail oder global aus allen Jails entfernen.

# Eine IP aus dem sshd-Jail entsperren
sudo fail2ban-client set sshd unbanip 203.0.113.42

# Dieselbe IP aus allen Jails entsperren (ab Version 0.11)
sudo fail2ban-client unban 203.0.113.42

# Alle Sperren eines Jails auf einen Schlag aufheben
sudo fail2ban-client set sshd unban --all

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

Wollen Sie verhindern, dass eine bestimmte Adresse jemals gesperrt wird, gehört sie in die ignoreip-Liste aus Schritt 4 und nicht in ein wiederholtes manuelles Entsperren. Der banip-Befehl ist nützlich, wenn Sie eine bekannte Angreifer-IP aus einem anderen Report sofort blockieren möchten, ohne auf die nächsten Fehlversuche zu warten.

Schritt 10: Ban-Eskalation mit dem recidive-Jail

Hartnäckige Angreifer kommen nach Ablauf der Sperre einfach wieder. Hier setzt das recidive-Jail an: Es überwacht das Fail2ban-eigene Log und sperrt IP-Adressen, die bereits mehrfach gesperrt wurden, für eine deutlich längere Zeit. So eskalieren Sie von einer Stunde auf eine Woche oder länger, ohne legitime Nutzer dauerhaft auszusperren.

[recidive]
enabled   = true
logpath   = /var/log/fail2ban.log
banaction = nftables-allports
# Wer 5 Sperren in 1 Tag kassiert ...
findtime  = 1d
maxretry  = 5
# ... wird 1 Woche gesperrt
bantime   = 1w

Eine elegante Alternative oder Ergänzung ist die automatische Ban-Eskalation über bantime.increment. Aktiviert verlängert Fail2ban die Sperrdauer bei jedem Rückfall automatisch, etwa mit dem Faktor 2. Tragen Sie dazu im [DEFAULT]-Abschnitt bantime.increment = true und bantime.factor = 2 ein. Beim zweiten Verstoß wird aus einer Stunde dann zwei, beim dritten vier und so weiter. Diese Funktion macht das recidive-Jail in vielen Fällen überflüssig.

Schritt 11: Weitere Dienste wie Nginx und Postfix schützen

Fail2ban schützt längst nicht nur SSH. Jeder Dienst, der Fehlversuche protokolliert, lässt sich absichern. Besonders verbreitet sind Jails für Webserver-Logins (etwa HTTP-Basic-Auth hinter Nginx) und für Mailserver wie Postfix oder Dovecot. Die passenden Filter liegen bereits in filter.d, Sie müssen sie nur über ein Jail aktivieren.

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

# Schutz gegen Bot-Anfragen auf nicht existente URLs
[nginx-botsearch]
enabled  = true
port     = http,https
filter   = nginx-botsearch
logpath  = /var/log/nginx/access.log
maxretry = 2

# Schutz fuer den Postfix-Mailserver
[postfix]
enabled  = true
port     = smtp,submission
filter   = postfix
backend  = systemd
maxretry = 5

Wenn Sie einen Webserver mit TLS betreiben, gehört der Brute-Force-Schutz zur Grundausstattung, ergänzt aber nie eine saubere Verschlüsselung. Wie HTTPS und TLS technisch funktionieren und warum das Schloss im Browser nur die halbe Miete ist, erklären wir im Beitrag HTTPS und TLS. Für jeden neuen Dienst gilt: Erst den passenden Filter mit fail2ban-regex gegen echte Logs testen, dann das Jail aktivieren.

Schritt 12: E-Mail-Benachrichtigungen einrichten

Im letzten Schritt lassen Sie sich bei jeder Sperre per E-Mail informieren. Das ist optional, aber hilfreich, um die Bedrohungslage im Blick zu behalten. Voraussetzung ist ein funktionierender Mail-Versand auf dem Server, etwa über msmtp oder ein lokales Postfix. Aktivieren Sie dann die Aktion, die Sperre und Benachrichtigung kombiniert.

# Im [DEFAULT]-Abschnitt der jail.local ergaenzen:
destemail = [email protected]
sender    = [email protected]
mta       = sendmail

# Aktion: sperren UND eine kurze Info-Mail senden
action = %(action_mw)s

# Variante mit Logauszug der verdaechtigen Zeilen:
# action = %(action_mwl)s

Die Aktion action_mw sendet eine kurze Mail mit Whois-Informationen zur gesperrten IP, action_mwl hängt zusätzlich die passenden Logzeilen an. Übertreiben Sie es nicht: Auf stark frequentierten Servern kann das hunderte Mails pro Tag bedeuten. In der Praxis genügt es oft, nur das recidive-Jail mit Mailversand zu konfigurieren, damit Sie ausschließlich über hartnäckige Wiederholungstäter informiert werden.

Häufige Fehler und wie Sie sie vermeiden

Die meisten Probleme mit Fail2ban entstehen nicht durch die Software, sondern durch typische Konfigurationsfehler. Diese fünf Stolpersteine sehen wir in der Praxis am häufigsten.

  • jail.conf direkt bearbeiten: Änderungen verschwinden beim nächsten Update spurlos. Nutzen Sie immer jail.local. Das ist der mit Abstand häufigste Anfängerfehler.
  • Falsches Backend: Steht backend = auto, findet Fail2ban auf reinen Journal-Systemen ohne /var/log/auth.log keine Einträge und sperrt niemanden. Setzen Sie backend = systemd.
  • Eigene IP vergessen: Ohne Eintrag in ignoreip sperren Sie sich bei eigenen Tippfehlern selbst aus. Halten Sie immer einen zweiten Zugang bereit.
  • Geänderter SSH-Port nicht angepasst: Läuft SSH auf Port 2222, das Jail aber auf port = ssh (22), greift die Sperre ins Leere. Tragen Sie den echten Port ein.
  • restart statt reload: Ein harter Neustart löscht laufende Sperren und öffnet kurz ein Fenster. Verwenden Sie fail2ban-client reload.

Ein sechster, oft übersehener Fehler betrifft NAT und Reverse-Proxys. Steht ein Cloudflare- oder Nginx-Proxy vor Ihrem Server, sieht Fail2ban nur die IP des Proxys und sperrt im schlimmsten Fall den Proxy selbst. In diesem Fall müssen Sie die echte Client-IP aus den Headern (etwa X-Forwarded-For) auswerten und den Proxy in ignoreip aufnehmen.

Troubleshooting: Die häufigsten Probleme lösen

Wenn Fail2ban nicht wie erwartet arbeitet, liegt die Ursache fast immer in einer der folgenden Kategorien. Diese Tabelle fasst die acht häufigsten Symptome mit ihrer jeweiligen Lösung zusammen.

SymptomWahrscheinliche UrsacheLösung
Niemand wird gesperrtFalsches Backend oder falscher logpathbackend = systemd setzen, Journal mit journalctl -u ssh prüfen
Dienst startet nichtSyntaxfehler in jail.localfail2ban-client -t ausführen und genannte Zeile korrigieren
Eigene IP gesperrtignoreip unvollständigÜber KVM-Konsole entsperren, IP in ignoreip eintragen
Filter findet nichtsLogformat passt nicht zum RegexMit fail2ban-regex gegen echte Logs testen
Sperre wirkt nichtnftables/iptables-Backend passt nichtbanaction auf vorhandene Firewall abstimmen
Sperren verschwindenrestart statt reload genutztImmer fail2ban-client reload verwenden
IPv6 wird nicht gesperrtallowipv6 deaktiviertallowipv6 = auto in fail2ban.local setzen
Hohe CPU-LastZu viele aktive Jails auf großen LogsJournal-Backend nutzen, Jails reduzieren

Für die Fehlersuche ist das Fail2ban-eigene Logfile die erste Anlaufstelle. Es protokolliert jeden Start, jede Sperre und jeden Fehler im Detail.

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

# Oder, auf reinen Journal-Systemen:
sudo journalctl -u fail2ban -f

# Typische erfolgreiche Sperrzeile:
# NOTICE  [sshd] Ban 45.143.200.18

# Den Debug-Loglevel temporaer erhoehen:
sudo fail2ban-client set loglevel DEBUG

Fortgeschrittene Tipps für den produktiven Einsatz

nftables statt iptables nutzen

Auf Debian 12 und Ubuntu 24.04 ist nftables die Standard-Firewall. Setzen Sie deshalb banaction = nftables-multiport statt der älteren iptables-Variante. Fail2ban legt dann eine eigene nftables-Tabelle an und verwaltet die Sperren sauber getrennt von Ihren übrigen Regeln. Mischen Sie iptables- und nftables-Aktionen nicht, sonst können sich Sperren widersprechen oder ins Leere laufen.

IPv6 nicht vergessen

Fail2ban unterstützt IPv6 seit Version 0.10 vollständig. Trotzdem ist der Schutz nur dann wirksam, wenn Ihre Firewall-Aktion auch IPv6 abdeckt. Auf einem Dual-Stack-Server in Österreich mit IPv6-Anbindung greifen Angreifer zunehmend über IPv6 an. Setzen Sie allowipv6 = auto in /etc/fail2ban/fail2ban.local und kontrollieren Sie mit fail2ban-client status sshd, ob auch IPv6-Adressen in der Sperrliste auftauchen.

SSH zusätzlich härten

Fail2ban ist eine Ergänzung, kein Ersatz für eine gehärtete SSH-Konfiguration. Die wirksamste Maßnahme bleibt das Abschalten der Passwort-Authentifizierung zugunsten von SSH-Schlüsseln. Tragen Sie in /etc/ssh/sshd_config die Werte PasswordAuthentication no und PermitRootLogin prohibit-password ein. Kombinieren Sie das mit einem verschlüsselten Schlüsselspeicher, etwa über KeePassXC, und mit einem VPN-Zugang wie in unserer Anleitung zu WireGuard beschrieben. Brute-Force-Angriffe laufen dann komplett ins Leere, weil ohne gültigen Schlüssel gar kein Login möglich ist.

Sicherheit: CVE-2025-45311 und Updates ernst nehmen

Auch ein Sicherheitswerkzeug kann selbst eine Schwachstelle enthalten. Ende 2025 wurde CVE-2025-45311 veröffentlicht, eine Sicherheitslücke in fail2ban-client der Version 0.11.2. Unsichere Berechtigungen konnten es einem Nutzer mit eingeschränkten sudo-Rechten ermöglichen, beliebige Operationen mit Root-Rechten auszuführen. Die Details dokumentiert der offizielle CVE-Eintrag.

Die praktische Konsequenz ist einfach: Halten Sie Fail2ban aktuell und vergeben Sie sudo-Rechte für fail2ban-client nur sehr restriktiv. Auf einem gepflegten Debian- oder Ubuntu-System erhalten Sie Sicherheitsupdates automatisch über die Distributionsquellen. Aktivieren Sie unbeaufsichtigte Sicherheitsupdates mit unattended-upgrades, dann landen auch Fail2ban-Patches zeitnah auf Ihrem System.

# Automatische Sicherheitsupdates aktivieren (Debian/Ubuntu)
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

# Installierte Fail2ban-Version und Sicherheitsstand pruefen
apt list --installed 2>/dev/null | grep fail2ban
fail2ban-client --version

Fail2ban vs. CrowdSec vs. sshguard im Vergleich

Fail2ban ist nicht das einzige Werkzeug seiner Art. Zwei prominente Alternativen sind CrowdSec, das auf eine gemeinschaftliche Bedrohungsdatenbank setzt, und sshguard, ein besonders schlankes, in C geschriebenes Pendant. Welches Werkzeug passt, hängt von Ihren Anforderungen ab.

MerkmalFail2banCrowdSecsshguard
SprachePythonGoC
RessourcenbedarfMittelHöherSehr gering
Gemeinschafts-BlocklistNeinJaNein
Geschützte DiensteSehr viele (Filter)Viele (Szenarien)Vor allem SSH
KonfigurationLogdateien, JailsYAML, zentralMinimal
ReifeSehr hoch, etabliertModern, wachsendHoch, schlank
Ideal fürKlassische EinzelserverFlotten, zentrale SichtMinimalsysteme

Für den klassischen Anwendungsfall, einen oder wenige Linux-Server selbst abzusichern, bleibt Fail2ban die beste Wahl: ausgereift, breit dokumentiert und mit Filtern für praktisch jeden Dienst. CrowdSec spielt seine Stärken aus, sobald Sie viele Server zentral verwalten und von einer geteilten Blocklist profitieren wollen. sshguard ist die richtige Wahl, wenn jedes Megabyte RAM zählt und Sie ausschließlich SSH absichern. Eine ausführliche Projektübersicht zu Fail2ban finden Sie auf der offiziellen Projektseite und im GitHub-Repository.

Komplettes Beispielprojekt: Eine produktionsreife jail.local

Zum Abschluss fügen wir alle Schritte zu einer vollständigen, kommentierten Konfiguration zusammen. Diese jail.local schützt SSH, einen Nginx-Webserver und eskaliert hartnäckige Angreifer über das recidive-Jail. Kopieren Sie sie nach /etc/fail2ban/jail.local, passen Sie IP-Adresse und E-Mail an und laden Sie Fail2ban neu.

[DEFAULT]
# --- Vertrauenswuerdige Adressen niemals sperren ---
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 203.0.113.7

# --- Globale Schwellenwerte ---
bantime  = 1h
findtime = 10m
maxretry = 5

# --- Progressive Eskalation bei Rueckfall ---
bantime.increment = true
bantime.factor    = 2
bantime.maxtime   = 1w

# --- Log- und Firewall-Backend (Debian 12 / Ubuntu 24.04) ---
backend   = systemd
banaction = nftables-multiport

# --- Benachrichtigung ---
destemail = [email protected]
sender    = [email protected]
mta       = sendmail
action    = %(action_mw)s

[sshd]
enabled  = true
port     = ssh
filter   = sshd
maxretry = 4
bantime  = 2h

[nginx-http-auth]
enabled  = true
port     = http,https
filter   = nginx-http-auth
logpath  = /var/log/nginx/error.log
maxretry = 5

[recidive]
enabled   = true
logpath   = /var/log/fail2ban.log
banaction = nftables-allports
findtime  = 1d
maxretry  = 5
bantime   = 1w
# Konfiguration testen, neu laden und pruefen
sudo fail2ban-client -t
sudo fail2ban-client reload
sudo fail2ban-client status

# Erwartete Ausgabe:
# Status
# |- Number of jail:      3
# `- Jail list:           nginx-http-auth, recidive, sshd

Mit dieser Konfiguration läuft auf Ihrem Server ein mehrstufiger Brute-Force-Schutz: SSH-Angreifer werden nach vier Fehlversuchen für zwei Stunden gesperrt, Nginx-Login-Angriffe nach fünf, und wer wiederholt auffällt, kassiert über das recidive-Jail eine Wochensperre. Die progressive Eskalation verlängert jede weitere Sperre automatisch. Damit ist die Grundabsicherung gegen automatisierte Angriffe abgeschlossen.

Fail2ban in Docker- und Container-Umgebungen

Immer mehr Dienste laufen in Containern, und das verändert die Logik von Fail2ban. Ein im Container laufender Webserver schreibt seine Logs in den Container, nicht auf den Host. Fail2ban gehört in dieser Architektur fast immer auf den Host, nicht in den Container, weil nur der Host die Firewall-Regeln über nftables setzen kann. Der Container stellt seine Logs bereit, der Host wertet sie aus und sperrt.

Die saubere Lösung führt die Container-Logs in das systemd-Journal des Hosts. Docker bietet dafür den Logging-Treiber journald, der die Ausgaben jedes Containers direkt ins Journal schreibt. Fail2ban liest dann wie gewohnt über backend = systemd mit. Achten Sie darauf, dass Docker eigene iptables- beziehungsweise nftables-Ketten anlegt: Sperren müssen vor den Docker-Regeln greifen, sonst leitet Docker den Verkehr trotzdem an den Container weiter.

# Container-Logs in das Host-Journal schreiben
docker run --log-driver=journald --name web nginx

# Auf dem Host pruefen, ob die Logs ankommen
journalctl CONTAINER_NAME=web --since "5 min ago"

# Jail auf dem Host, das die Container-Logs auswertet
[nginx-docker]
enabled  = true
backend  = systemd
filter   = nginx-http-auth
journalmatch = CONTAINER_NAME=web
maxretry = 5

Wer einen vollständig containerisierten Stack betreibt, sollte zusätzlich prüfen, ob nicht ein vorgelagerter Reverse-Proxy ohnehin alle echten Client-IPs maskiert. In dem Fall führt kein Weg an der Auswertung des X-Forwarded-For-Headers vorbei, wie schon im Abschnitt zu den häufigen Fehlern beschrieben. Halten Sie die Zahl der Jails auf containerisierten Hosts bewusst niedrig, denn jede zusätzliche Journal-Abfrage kostet Ressourcen.

Sperren langfristig auswerten und überwachen

Ein produktiver Server liefert über die Zeit ein aussagekräftiges Bild der Angriffslage. Fail2ban bringt mit fail2ban-client bereits eine einfache Statistik mit, doch für die langfristige Auswertung lohnt sich ein Blick in das Logfile. So erkennen Sie, aus welchen Netzen die meisten Angriffe kommen und ob bestimmte Dienste besonders im Visier stehen.

# Die zehn am haeufigsten gesperrten IPs ermitteln
sudo zgrep -h "Ban" /var/log/fail2ban.log* \
  | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" \
  | sort | uniq -c | sort -rn | head -10

# Anzahl aller Sperren pro Tag
sudo grep "Ban" /var/log/fail2ban.log \
  | awk '{print $1}' | sort | uniq -c

Diese einfachen Auswertungen genügen für den Hausgebrauch. Wer mehrere Server betreibt, exportiert die Daten besser an ein zentrales System. Es gibt Prometheus-Exporter, die die Fail2ban-Statistiken als Metriken bereitstellen, sodass Sie Sperren in einem Grafana-Dashboard visualisieren können. Für den Einstieg reicht jedoch die regelmäßige Kontrolle per fail2ban-client status völlig aus. Behalten Sie vor allem das recidive-Jail im Auge: Taucht dort dieselbe IP immer wieder auf, lohnt sich eine dauerhafte Sperre auf Firewall-Ebene.

Fail2ban ist damit ein wichtiger Baustein, aber eben nur einer. Eine wirksame Absicherung kombiniert den reaktiven Brute-Force-Schutz mit präventiven Maßnahmen: starken Zugangsdaten, Schlüssel-Authentifizierung, einer restriktiven Firewall und regelmäßigen Updates. Wie diese Bausteine zusammenspielen, ordnet unser Überblick zur Online-Sicherheit ein.

Häufige Fragen zu Fail2ban

Ersetzt Fail2ban eine Firewall?

Nein. Fail2ban steuert die Firewall, ist aber selbst keine. Es schreibt dynamische Sperrregeln in nftables oder iptables, setzt also eine funktionierende Firewall voraus. Betreiben Sie weiterhin eine Basis-Firewall, die nur benötigte Ports öffnet, und nutzen Sie Fail2ban als zusätzliche, reaktive Schicht darüber.

Verlangsamt Fail2ban meinen Server?

Im Normalbetrieb ist die Last vernachlässigbar. Fail2ban liest Logzeilen und gleicht sie mit regulären Ausdrücken ab. Erst bei dutzenden aktiven Jails auf sehr großen Logdateien kann die CPU-Last steigen. Das systemd-Journal als Backend ist hier effizienter als das Einlesen riesiger Textdateien.

Wie sehe ich, welche IPs aktuell gesperrt sind?

Mit sudo fail2ban-client status sshd sehen Sie die komplette Liste der aktuell gesperrten Adressen für ein Jail, inklusive der Gesamtzahl aller jemals registrierten Fehlversuche und Sperren.

Funktioniert Fail2ban mit IPv6?

Ja, seit Version 0.10. Wichtig ist, dass die gewählte banaction IPv6 abdeckt und allowipv6 = auto gesetzt ist. Auf Dual-Stack-Servern sollten Sie unbedingt prüfen, ob auch IPv6-Adressen in der Sperrliste erscheinen.

Ich habe mich selbst ausgesperrt. Was tun?

Verbinden Sie sich über die KVM- oder Webkonsole Ihres Hosters mit dem Server und führen Sie sudo fail2ban-client unban IHRE-IP aus. Tragen Sie Ihre Adresse danach in ignoreip ein, damit sich der Fehler nicht wiederholt. Genau dafür sollten Sie immer einen zweiten Zugangsweg bereithalten.

Brauche ich Fail2ban, wenn ich nur SSH-Schlüssel nutze?

Streng genommen verhindert die reine Schlüssel-Authentifizierung Brute-Force-Logins bereits vollständig. Fail2ban bleibt trotzdem nützlich, weil es Bots frühzeitig blockt, Ihre Logs sauber hält und andere Dienste wie Webserver oder Mailserver schützt, bei denen Passwörter im Spiel sind.

Wie unterscheidet sich bantime.increment vom recidive-Jail?

bantime.increment verlängert die Sperrdauer derselben IP bei jedem Rückfall automatisch. Das recidive-Jail überwacht dagegen das Fail2ban-Log und sperrt IPs, die in mehreren Jails oder mehrfach auffällig wurden, gebündelt für eine lange Zeit. Beide lassen sich kombinieren, in der Praxis genügt oft schon die Eskalation über bantime.increment.

Auf welchen Distributionen läuft Fail2ban?

Auf praktisch allen. Debian, Ubuntu, Fedora, Rocky Linux, AlmaLinux und Arch Linux liefern Fail2ban in ihren Paketquellen. Die Konfiguration ist identisch, lediglich Installationsbefehl und einzelne Logpfade unterscheiden sich. Diese Anleitung verwendet Debian 12 und Ubuntu 24.04 LTS als Referenz.

Stand: Juni 2026. Die gezeigten Befehle und Konfigurationen wurden für Debian 12 und Ubuntu 24.04 LTS mit Fail2ban 1.1.0 als Referenz beschrieben. Prüfen Sie Versionsnummern und Pfade immer gegen Ihr konkretes System.