{"id":131,"date":"2026-06-14T20:14:46","date_gmt":"2026-06-14T20:14:46","guid":{"rendered":"https:\/\/shattered.io\/de\/2026\/06\/14\/fail2ban-einrichten-ssh-schutz\/"},"modified":"2026-06-14T20:16:07","modified_gmt":"2026-06-14T20:16:07","slug":"fail2ban-einrichten-ssh-schutz","status":"publish","type":"post","link":"https:\/\/shattered.io\/de\/2026\/06\/14\/fail2ban-einrichten-ssh-schutz\/","title":{"rendered":"Fail2ban einrichten: SSH-Schutz in 12 Schritten [2026]"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">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 <code>root<\/code>, <code>admin<\/code> oder <code>ubuntu<\/code> mit W\u00f6rterbuch-Passw\u00f6rtern 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 \u00fcber die Firewall.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Anleitung f\u00fchrt Sie in 12 Schritten durch die komplette Einrichtung von Fail2ban auf einem produktiven Linux-Server. Sie lernen, wie Sie Fail2ban installieren, eine sichere <code>jail.local<\/code> aufbauen, den SSH-Schutz aktivieren, eigene Filter schreiben, wiederholte Angreifer mit der <code>recidive<\/code>-Jail dauerhaft aussperren und das System mit dem <code>fail2ban-client<\/code> \u00fcberwachen. Planen Sie etwa 45 bis 60 Minuten ein. Am Ende l\u00e4uft ein vollst\u00e4ndig funktionierender Brute-Force-Schutz, den Sie auf Debian, Ubuntu, Rocky Linux oder AlmaLinux betreiben k\u00f6nnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"was-ist-fail2ban-und-warum-brauchen-sie-es-2026\">Was ist Fail2ban und warum brauchen Sie es 2026?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban ist ein in Python geschriebenes Intrusion-Prevention-Framework. Es \u00fcberwacht Logdateien wie <code>\/var\/log\/auth.log<\/code> auf verd\u00e4chtige 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\u00fcr eine bestimmte Zeit blockiert. Das Prinzip ist simpel und wirkungsvoll: Ein Angreifer, der nach f\u00fcnf Fehlversuchen f\u00fcr zehn Minuten gesperrt wird, kann pro Stunde nur noch eine Handvoll Passw\u00f6rter testen statt mehrerer tausend. Ein Brute-Force-Angriff, der ungebremst Stunden dauert, wird dadurch praktisch unm\u00f6glich.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">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\u00fcber der lange verbreiteten 0.11-Serie sp\u00fcrbar mehr Leistung beim Verarbeiten gro\u00dfer Logmengen und eine stabilere Anbindung an das systemd-Journal. Fail2ban ist quelloffen, l\u00e4uft auf praktisch jeder Linux-Distribution und kostet nichts. Genau diese Kombination macht es seit Jahren zum De-facto-Standard f\u00fcr den Schutz einzelner Server und kleiner Flotten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">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\u00f6ren 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\u00e4rtung wie SSH-Keys oder Zwei-Faktor-Authentifizierung, aber es reduziert die Angriffsfl\u00e4che drastisch und h\u00e4lt Ihre Logs sauber.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wie sieht so ein Angriff konkret aus? Ein Blick in <code>\/var\/log\/auth.log<\/code> 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 <code>Failed password<\/code>-Eintr\u00e4ge und reagiert darauf.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Jun 14 09:12:41 srv sshd[2287]: Failed password for root from 45.148.10.71 port 51234 ssh2\nJun 14 09:12:43 srv sshd[2289]: Failed password for invalid user admin from 193.32.162.143 port 40122 ssh2\nJun 14 09:12:45 srv sshd[2291]: Failed password for invalid user test from 218.92.0.34 port 33890 ssh2\nJun 14 09:12:47 srv sshd[2293]: Failed password for root from 45.148.10.71 port 51240 ssh2<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">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 <a href=\"\/ssh-key-erstellen-ed25519-2026\/\">Ed25519-SSH-Key<\/a> und Fail2ban als zus\u00e4tzlicher Schicht ist die Verteidigungsstrategie, die sich in der Praxis bew\u00e4hrt hat. Sicherheit funktioniert in Schichten, nie \u00fcber ein einzelnes Werkzeug.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"voraussetzungen-server-versionen-und-zugaenge\">Voraussetzungen: Server, Versionen und Zug\u00e4nge<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor Sie loslegen, sollten die folgenden Voraussetzungen erf\u00fcllt sein. Diese Anleitung wurde auf Debian 12, Ubuntu 24.04 LTS und Rocky Linux 9 getestet, funktioniert aber sinngem\u00e4\u00df auf jeder modernen Distribution mit systemd.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Linux-Server<\/strong> mit Root-Zugriff oder einem Benutzer mit <code>sudo<\/code>-Rechten. Getestet auf Debian 12, Ubuntu 22.04\/24.04 LTS, Rocky Linux 9, AlmaLinux 9.<\/li>\n<li><strong>Python 3.5 oder neuer.<\/strong> Fail2ban 1.x setzt Python 3 voraus; jede aktuell unterst\u00fctzte Distribution erf\u00fcllt das problemlos.<\/li>\n<li><strong>Fail2ban 1.0.x oder 1.1.x<\/strong> aus den Paketquellen oder als Build von GitHub.<\/li>\n<li><strong>Eine Firewall-Backend-Komponente:<\/strong> <code>nftables<\/code> (Standard auf Debian 12 und Ubuntu 22.04+) oder <code>firewalld<\/code> (Standard auf RHEL-Derivaten wie Rocky und AlmaLinux). <code>iptables<\/code> funktioniert weiterhin als Kompatibilit\u00e4ts-Layer.<\/li>\n<li><strong>SSH-Zugang<\/strong>, der bereits funktioniert. Richten Sie Fail2ban niemals als Erstes ein, ohne einen funktionierenden zweiten Zugang oder eine Konsole beim Hoster.<\/li>\n<li><strong>Grundkenntnisse<\/strong> in der Bearbeitung von Textdateien per <code>nano<\/code> oder <code>vim<\/code> sowie im Lesen von Logdateien.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Eine dringende Empfehlung vorweg: Tragen Sie schon jetzt Ihre eigene \u00f6ffentliche IP-Adresse als sp\u00e4tere Ausnahme ein. Nichts ist \u00e4rgerlicher, als sich selbst aus dem eigenen Server auszusperren, weil ein Tippfehler im Passwort dreimal hintereinander passiert. Ihre aktuelle \u00f6ffentliche IP finden Sie mit einem einzigen Befehl heraus.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Eigene \u00f6ffentliche IP-Adresse ermitteln\ncurl -s https:\/\/ifconfig.me\n# Beispielausgabe:\n# 203.0.113.45<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-1-fail2ban-installieren-debian-ubuntu-rocky\">Schritt 1: Fail2ban installieren (Debian, Ubuntu, Rocky)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Die Installation unterscheidet sich je nach Paketmanager. Auf Debian und Ubuntu nutzen Sie <code>apt<\/code>, auf RHEL-Derivaten <code>dnf<\/code> zusammen mit dem EPEL-Repository, da Fail2ban dort nicht in den Standardquellen liegt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># --- Debian 12 \/ Ubuntu 22.04 \/ 24.04 ---\nsudo apt update\nsudo apt install -y fail2ban\n\n# --- Rocky Linux 9 \/ AlmaLinux 9 ---\nsudo dnf install -y epel-release\nsudo dnf install -y fail2ban fail2ban-firewalld\n\n# Version pruefen (auf allen Systemen)\nfail2ban-client --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Ausgabe von <code>fail2ban-client --version<\/code> sollte eine 1.x-Version anzeigen, zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Fail2Ban v1.0.2\n\nCopyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors\nhttps:\/\/github.com\/fail2ban\/fail2ban<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Auf Debian und Ubuntu wird der Dienst nach der Installation in der Regel automatisch gestartet und f\u00fcr den Autostart aktiviert. Auf Rocky und AlmaLinux m\u00fcssen 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-2-jail-conf-verstehen-und-jail-local-anlegen\">Schritt 2: jail.conf verstehen und jail.local anlegen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban arbeitet mit zwei Ebenen von Konfigurationsdateien. Die mitgelieferten <code>.conf<\/code>-Dateien enthalten die Standardwerte und werden bei jedem Paket-Update \u00fcberschrieben. Ihre eigenen Anpassungen geh\u00f6ren deshalb immer in gleichnamige <code>.local<\/code>-Dateien. Fail2ban liest zuerst die <code>.conf<\/code> und \u00fcberschreibt dann die Werte mit dem, was in der <code>.local<\/code> steht. Diese Trennung ist die wichtigste Regel im Umgang mit Fail2ban: Bearbeiten Sie niemals direkt die <code>jail.conf<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die zentralen Dateien und Verzeichnisse im \u00dcberblick:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Pfad<\/th><th>Funktion<\/th><th>Bearbeiten?<\/th><\/tr><\/thead><tbody>\n<tr><td><code>\/etc\/fail2ban\/jail.conf<\/code><\/td><td>Standard-Jails und Vorgabewerte<\/td><td>Nein (wird \u00fcberschrieben)<\/td><\/tr>\n<tr><td><code>\/etc\/fail2ban\/jail.local<\/code><\/td><td>Ihre eigenen Jail-Einstellungen<\/td><td>Ja<\/td><\/tr>\n<tr><td><code>\/etc\/fail2ban\/jail.d\/<\/code><\/td><td>Modulare Jail-Schnipsel (.local)<\/td><td>Ja<\/td><\/tr>\n<tr><td><code>\/etc\/fail2ban\/fail2ban.conf<\/code><\/td><td>Daemon-Einstellungen (Loglevel, Socket)<\/td><td>\u00dcber fail2ban.local<\/td><\/tr>\n<tr><td><code>\/etc\/fail2ban\/filter.d\/<\/code><\/td><td>Regex-Filter pro Dienst<\/td><td>Eigene .conf hinzuf\u00fcgen<\/td><\/tr>\n<tr><td><code>\/etc\/fail2ban\/action.d\/<\/code><\/td><td>Bann-Aktionen (Firewall, Mail)<\/td><td>Selten<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Legen Sie nun eine leere <code>jail.local<\/code> an. Eine verbreitete Empfehlung lautet, einfach die komplette <code>jail.conf<\/code> zu kopieren. Das ist unpraktisch, weil Sie dann hunderte Zeilen pflegen, die Sie nie \u00e4ndern. Besser ist eine schlanke <code>jail.local<\/code>, die nur die wenigen Werte enth\u00e4lt, die Sie wirklich anpassen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># jail.local zur Bearbeitung oeffnen (wird neu angelegt)\nsudo nano \/etc\/fail2ban\/jail.local<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-3-globale-default-werte-festlegen\">Schritt 3: Globale [DEFAULT]-Werte festlegen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Der Abschnitt <code>[DEFAULT]<\/code> in der <code>jail.local<\/code> setzt Werte, die f\u00fcr alle Jails gelten, solange eine einzelne Jail sie nicht \u00fcberschreibt. Hier definieren Sie die drei wichtigsten Parameter \u00fcberhaupt: <code>bantime<\/code>, <code>findtime<\/code> und <code>maxretry<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>maxretry<\/strong>: Wie viele Fehlversuche erlaubt sind, bevor gesperrt wird. Standard in der <code>jail.conf<\/code> ist 5.<\/li>\n<li><strong>findtime<\/strong>: Der Zeitraum, in dem diese Fehlversuche z\u00e4hlen. Standard sind 600 Sekunden (10 Minuten). F\u00fcnf Fehlversuche innerhalb von zehn Minuten l\u00f6sen also einen Bann aus.<\/li>\n<li><strong>bantime<\/strong>: Wie lange die IP gesperrt bleibt. Standard sind ebenfalls 600 Sekunden. F\u00fcr produktive Server sind zehn Minuten oft zu kurz; ein Wert von einer Stunde bis zu einem Tag ist g\u00e4ngig.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Tragen Sie folgenden Block in Ihre <code>jail.local<\/code> ein. Ersetzen Sie <code>203.0.113.45<\/code> durch Ihre eigene \u00f6ffentliche IP aus den Voraussetzungen. Mehrere IPs trennen Sie mit Leerzeichen, ganze Netze geben Sie in CIDR-Notation an.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[DEFAULT]\n# Eigene IPs und localhost niemals sperren\nignoreip = 127.0.0.1\/8 ::1 203.0.113.45\n\n# Bann-Logik\nbantime  = 1h\nfindtime = 10m\nmaxretry = 5\n\n# Auf systemd-Distributionen das Journal lesen\nbackend = systemd\n\n# Firewall-Backend: nftables (Debian\/Ubuntu) oder firewalld (RHEL)\nbanaction = nftables-multiport\nbanaction_allports = nftables-allports<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Hinweis zu den Zeitangaben: Fail2ban 1.x versteht Suffixe wie <code>m<\/code> (Minuten), <code>h<\/code> (Stunden) und <code>d<\/code> (Tage). Sie m\u00fcssen also nicht mehr in Sekunden rechnen. <code>bantime = 1h<\/code> ist deutlich lesbarer als <code>bantime = 3600<\/code>. Auf Rocky\/AlmaLinux setzen Sie statt <code>nftables-multiport<\/code> die Werte <code>firewalld-multiport<\/code> beziehungsweise lassen den <code>banaction<\/code> weg, da <code>fail2ban-firewalld<\/code> dort die passende Vorgabe mitbringt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-4-die-sshd-jail-aktivieren\">Schritt 4: Die sshd-Jail aktivieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In Fail2ban 1.x ist die <code>sshd<\/code>-Jail vorhanden, aber nicht automatisch aktiv. Sie aktivieren sie explizit in der <code>jail.local<\/code>. H\u00e4ngen Sie dazu folgenden Abschnitt an Ihre Datei an:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[sshd]\nenabled  = true\nport     = ssh\nlogpath  = %(sshd_log)s\nbackend  = %(sshd_backend)s\nmaxretry = 3\nbantime  = 1h<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hier \u00fcberschreiben wir bewusst <code>maxretry<\/code> f\u00fcr 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\u00e4\u00dfigen Port betreiben, ersetzen Sie <code>port = ssh<\/code> durch die konkrete Portnummer, etwa <code>port = 2222<\/code>. Andernfalls greift der Bann zwar logisch, blockiert aber den falschen Port in der Firewall.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der Platzhalter <code>%(sshd_log)s<\/code> l\u00f6st sich je nach Distribution automatisch auf: Auf Debian\/Ubuntu zeigt er auf <code>\/var\/log\/auth.log<\/code>, auf systemd-Systemen ohne klassische Logdatei greift Fail2ban \u00fcber <code>backend = systemd<\/code> direkt auf das Journal zu. Auf Rocky und AlmaLinux liegt das SSH-Log \u00fcblicherweise im Journal beziehungsweise unter <code>\/var\/log\/secure<\/code>. Das ist einer der h\u00e4ufigsten Stolpersteine, dazu mehr im Abschnitt zu den Fallstricken.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-5-konfiguration-testen-bevor-sie-starten\">Schritt 5: Konfiguration testen, bevor Sie starten<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor Sie den Dienst neu starten, pr\u00fcfen Sie die Konfiguration auf Syntaxfehler. Ein fehlerhafter regul\u00e4rer Ausdruck oder ein Tippfehler in einem Pfad kann den Start verhindern, und ein nicht laufendes Fail2ban sch\u00fctzt nichts. Der eingebaute Test-Modus liest alle Konfigurationen ein und meldet Probleme, ohne etwas zu sperren.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Komplette Konfiguration testen\nsudo fail2ban-client -t\n\n# Erwartete Ausgabe bei korrekter Konfiguration:\n# OK: configuration test is successful<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Erscheint stattdessen eine Fehlermeldung mit <code>ERROR<\/code>, lesen Sie genau, welche Datei und welche Zeile genannt werden. H\u00e4ufig ist es ein doppelt definierter Abschnitt oder ein ung\u00fcltiger Wert bei <code>bantime<\/code>. Beheben Sie den Fehler und f\u00fchren Sie den Test erneut aus, bis <code>OK<\/code> erscheint. Erst dann geht es weiter.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-6-dienst-starten-und-status-pruefen\">Schritt 6: Dienst starten und Status pr\u00fcfen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt aktivieren Sie den Dienst und sorgen daf\u00fcr, dass er nach einem Neustart automatisch wieder hochf\u00e4hrt. Anschlie\u00dfend pr\u00fcfen Sie mit dem <code>fail2ban-client<\/code>, ob die SSH-Jail tats\u00e4chlich geladen wurde.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Dienst aktivieren und starten\nsudo systemctl enable --now fail2ban\n\n# Status des Dienstes pruefen\nsudo systemctl status fail2ban --no-pager\n\n# Aktive Jails auflisten\nsudo fail2ban-client status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die letzte Zeile gibt Ihnen die Liste der aktiven Jails. Die Ausgabe sollte etwa so aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Status\n|- Number of jail:      1\n`- Jail list:   sshd<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr Details zu einer einzelnen Jail h\u00e4ngen 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.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo fail2ban-client status sshd\n\n# Beispielausgabe:\nStatus for the jail: sshd\n|- Filter\n|  |- Currently failed: 2\n|  |- Total failed:     147\n|  `- File list:        \/var\/log\/auth.log\n`- Actions\n   |- Currently banned: 3\n   |- Total banned:     19\n   `- Banned IP list:   45.148.10.71 193.32.162.143 218.92.0.34<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-7-einen-bann-live-testen\">Schritt 7: Einen Bann live testen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Vertrauen ist gut, ein Funktionstest ist besser. Sie k\u00f6nnen einen Bann manuell ausl\u00f6sen, um zu sehen, dass die Firewall-Aktion greift. Verwenden Sie daf\u00fcr eine harmlose Test-IP aus dem Dokumentationsbereich, niemals Ihre eigene.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Test-IP manuell sperren\nsudo fail2ban-client set sshd banip 198.51.100.23\n\n# Pruefen, ob sie in der Bann-Liste auftaucht\nsudo fail2ban-client status sshd\n\n# Test-IP wieder entsperren\nsudo fail2ban-client set sshd unbanip 198.51.100.23<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Erscheint die IP nach <code>banip<\/code> in der Bann-Liste und verschwindet nach <code>unbanip<\/code> wieder, funktioniert die Kette aus Erkennung und Firewall-Aktion einwandfrei. Wer ganz sicher gehen will, pr\u00fcft mit <code>sudo nft list ruleset<\/code> (nftables) beziehungsweise <code>sudo firewall-cmd --list-rich-rules<\/code> (firewalld), ob der Eintrag tats\u00e4chlich in der Firewall landet. Diese manuelle Probe ist der schnellste Weg, ein falsch konfiguriertes Backend zu entlarven.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-8-inkrementelle-bann-zeiten-aktivieren\">Schritt 8: Inkrementelle Bann-Zeiten aktivieren<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ein fester Bann von einer Stunde h\u00e4lt Gelegenheits-Bots auf, aber hartn\u00e4ckige Angreifer kommen nach Ablauf einfach wieder. Fail2ban kann die Bann-Dauer bei jedem erneuten Versto\u00df automatisch verl\u00e4ngern. Diese Funktion hei\u00dft <code>bantime.increment<\/code> und ist eines der n\u00fctzlichsten Features der 1.x-Reihe. Wer dreimal gesperrt wurde, bleibt beim vierten Mal eben deutlich l\u00e4nger drau\u00dfen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Erg\u00e4nzen Sie Ihren <code>[DEFAULT]<\/code>-Abschnitt um folgende Zeilen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[DEFAULT]\n# ... vorhandene Werte ...\n\n# Bann-Zeit bei Wiederholung erhoehen\nbantime.increment = true\n\n# Multiplikator-Formel fuer die Verlaengerung\nbantime.factor    = 2\n\n# Obergrenze: maximal eine Woche Sperre\nbantime.maxtime   = 1w<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Mit diesen Werten verdoppelt sich die Bann-Zeit bei jedem erneuten Versto\u00df derselben IP, beginnend bei Ihrem <code>bantime<\/code> von einer Stunde: 1h, 2h, 4h, 8h und so weiter, gedeckelt bei einer Woche. Fail2ban merkt sich die Verst\u00f6\u00dfe in einer kleinen SQLite-Datenbank unter <code>\/var\/lib\/fail2ban\/fail2ban.sqlite3<\/code>, sodass die Historie auch einen Neustart des Dienstes \u00fcbersteht. Das ist genau das Verhalten, das echte Angreifer frustriert, ohne legitime Nutzer mit einem vergessenen Passwort dauerhaft auszusperren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-9-die-recidive-jail-gegen-wiederholungstaeter\">Schritt 9: Die recidive-Jail gegen Wiederholungst\u00e4ter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Die <code>recidive<\/code>-Jail ist eine elegante Meta-Jail. Sie \u00fcberwacht nicht den SSH-Dienst, sondern das eigene Fail2ban-Log <code>\/var\/log\/fail2ban.log<\/code>. Wird eine IP von einer beliebigen anderen Jail mehrfach gesperrt, greift <code>recidive<\/code> und verh\u00e4ngt einen sehr langen Bann \u00fcber alle Ports hinweg. So fangen Sie Angreifer ab, die hartn\u00e4ckig \u00fcber verschiedene Dienste hinweg probieren.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[recidive]\nenabled  = true\nlogpath  = \/var\/log\/fail2ban.log\nbanaction = %(banaction_allports)s\n# Wer innerhalb eines Tages 5-mal gesperrt wurde ...\nfindtime = 1d\nmaxretry = 5\n# ... fliegt fuer eine Woche komplett raus\nbantime  = 1w<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wichtig: Damit <code>recidive<\/code> \u00fcberhaupt etwas zu lesen hat, muss Fail2ban in eine echte Logdatei schreiben. Auf reinen systemd-Setups, die nur ins Journal loggen, m\u00fcssen Sie entweder das Dateilogging in <code>fail2ban.local<\/code> aktivieren (<code>logtarget = \/var\/log\/fail2ban.log<\/code>) oder die <code>recidive<\/code>-Jail auf <code>backend = systemd<\/code> umstellen. Pr\u00fcfen Sie nach dem Aktivieren mit <code>sudo fail2ban-client status recidive<\/code>, ob die Jail sauber geladen wurde. Auf Debian und Ubuntu existiert die Datei standardm\u00e4\u00dfig, dort funktioniert die obige Konfiguration ohne weitere Anpassung.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-10-weitere-dienste-schuetzen-nginx-postfix\">Schritt 10: Weitere Dienste sch\u00fctzen (Nginx, Postfix)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">SSH ist der wichtigste, aber nicht der einzige angreifbare Dienst. Fail2ban bringt fertige Filter f\u00fcr dutzende Anwendungen mit. Besonders verbreitet sind Jails f\u00fcr Webserver und Mailserver. Wenn Sie einen <a href=\"\/nginx-reverse-proxy-https-einrichten\/\">Nginx Reverse Proxy<\/a> oder eine Login-gesch\u00fctzte Webanwendung betreiben, lohnt sich der Schutz der Authentifizierung gegen automatisiertes Durchprobieren.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Schutz fuer HTTP-Basic-Auth hinter Nginx\n[nginx-http-auth]\nenabled  = true\nport     = http,https\nlogpath  = \/var\/log\/nginx\/error.log\n\n# Schutz gegen Bad Bots, die nach Login-Seiten scannen\n[nginx-botsearch]\nenabled  = true\nport     = http,https\nlogpath  = \/var\/log\/nginx\/access.log\nmaxretry = 2\n\n# Mailserver-Schutz gegen SASL-Login-Angriffe\n[postfix-sasl]\nenabled  = true\nport     = smtp,submission,imap,imaps,pop3,pop3s\nlogpath  = %(postfix_log)s<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aktivieren Sie nur Jails f\u00fcr Dienste, die tats\u00e4chlich laufen. Eine Jail, deren Logdatei nicht existiert, f\u00fchrt beim Start zu einer Fehlermeldung. Nach jeder \u00c4nderung gilt: testen mit <code>fail2ban-client -t<\/code>, dann neu laden. Das Neuladen erfolgt im laufenden Betrieb, ohne bestehende Banns zu verlieren.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfiguration neu laden, ohne den Dienst komplett neu zu starten\nsudo fail2ban-client reload\n\n# Eine einzelne Jail gezielt neu laden\nsudo fail2ban-client reload sshd<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-11-einen-eigenen-filter-schreiben\">Schritt 11: Einen eigenen Filter schreiben<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Manchmal gibt es f\u00fcr Ihren Dienst keinen fertigen Filter, etwa f\u00fcr eine selbst geschriebene Anwendung oder ein Nischen-Tool. Dann schreiben Sie einen eigenen. Ein Filter besteht im Kern aus einem regul\u00e4ren Ausdruck mit dem Platzhalter <code>&lt;HOST&gt;<\/code>, der Fail2ban zeigt, wo in der Logzeile die zu sperrende IP-Adresse steht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Angenommen, Ihre Anwendung schreibt bei einem fehlgeschlagenen Login eine Zeile wie diese ins Log:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>2026-06-14 09:31:02 WARN  Login failed for user admin from 45.148.10.71<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Legen Sie eine neue Filterdatei unter <code>\/etc\/fail2ban\/filter.d\/meineapp.conf<\/code> an:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[Definition]\n# &lt;HOST&gt; markiert die Position der angreifenden IP\nfailregex = ^.*Login failed for user .* from &lt;HOST&gt;$\nignoreregex =<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Bevor Sie eine Jail daf\u00fcr anlegen, testen Sie den Filter gegen Ihre echte Logdatei. Das Werkzeug <code>fail2ban-regex<\/code> zeigt Ihnen genau, wie viele Zeilen der Ausdruck trifft. Das erspart stundenlanges R\u00e4tselraten und ist Pflicht bei jedem selbst geschriebenen Filter.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Filter gegen ein Log testen\nsudo fail2ban-regex \/var\/log\/meineapp.log \/etc\/fail2ban\/filter.d\/meineapp.conf\n\n# Beispielausgabe (Ausschnitt):\n# Results\n# =======\n# Failregex: 42 total\n# |-  #) [# of hits] regular expression\n# |   1) [42] ^.*Login failed for user .* from &lt;HOST&gt;$\n# `-\n# Lines: 1500 lines, 0 ignored, 42 matched, 1458 missed<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Trifft der Filter wie erwartet, erg\u00e4nzen Sie eine passende Jail in der <code>jail.local<\/code>, die auf den Filter <code>meineapp<\/code> und Ihre Logdatei verweist. Damit sch\u00fctzen Sie auch Anwendungen, die niemand sonst kennt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"schritt-12-monitoring-benachrichtigungen-und-pflege\">Schritt 12: Monitoring, Benachrichtigungen und Pflege<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ein laufendes Fail2ban will man im Blick behalten. F\u00fcr den schnellen \u00dcberblick reicht der <code>fail2ban-client<\/code>, f\u00fcr die Langzeitbeobachtung lohnt sich ein Blick ins Log und optional eine E-Mail-Benachrichtigung bei jedem Bann. Letztere richten Sie \u00fcber die Aktion <code>action_mw<\/code> ein, die zus\u00e4tzlich zum Firewall-Bann eine Mail mit Whois-Informationen verschickt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Im [DEFAULT]-Abschnitt: E-Mail bei jedem Bann\ndestemail = admin@example.com\nsender    = fail2ban@example.com\nmta       = sendmail\naction    = %(action_mw)s<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr die t\u00e4gliche Pflege haben sich einige Befehle bew\u00e4hrt. Die folgende Tabelle fasst die wichtigsten <code>fail2ban-client<\/code>-Kommandos zusammen, die Sie im Betrieb immer wieder brauchen.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Befehl<\/th><th>Wirkung<\/th><\/tr><\/thead><tbody>\n<tr><td><code>fail2ban-client status<\/code><\/td><td>Alle aktiven Jails auflisten<\/td><\/tr>\n<tr><td><code>fail2ban-client status sshd<\/code><\/td><td>Details und Bann-Liste einer Jail<\/td><\/tr>\n<tr><td><code>fail2ban-client set sshd banip IP<\/code><\/td><td>IP manuell sperren<\/td><\/tr>\n<tr><td><code>fail2ban-client set sshd unbanip IP<\/code><\/td><td>IP wieder entsperren<\/td><\/tr>\n<tr><td><code>fail2ban-client unban --all<\/code><\/td><td>Alle Banns \u00fcber alle Jails aufheben<\/td><\/tr>\n<tr><td><code>fail2ban-client reload<\/code><\/td><td>Konfiguration neu laden<\/td><\/tr>\n<tr><td><code>fail2ban-client get sshd bantime<\/code><\/td><td>Aktuellen Wert einer Einstellung abfragen<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr eine schnelle Auswertung, welche IPs am h\u00e4ufigsten zuschlagen, hilft ein kurzer Einzeiler auf dem Fail2ban-Log. So erkennen Sie Muster und k\u00f6nnen bei Bedarf ganze Netzbereiche dauerhaft \u00fcber die <code>ignoreip<\/code>-Logik oder eine externe Firewall behandeln.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Top 10 der gesperrten IPs aus dem Log ziehen\nsudo zgrep \"Ban \" \/var\/log\/fail2ban.log* | \\\n  grep -oE \"[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\" | \\\n  sort | uniq -c | sort -rn | head -10<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"die-6-haeufigsten-fehler-bei-der-fail2ban-einrichtung\">Die 6 h\u00e4ufigsten Fehler bei der Fail2ban-Einrichtung<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Aus der Praxis kristallisieren sich immer wieder dieselben Stolpersteine heraus. Wer sie kennt, spart sich viel Frust und vermeidet den Klassiker, sich selbst auszusperren.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Die eigene IP nicht in ignoreip eingetragen.<\/strong> Der h\u00e4ufigste und \u00e4rgerlichste Fehler. Tragen Sie immer zuerst Ihre eigene IP ein und halten Sie einen zweiten Zugang (Hoster-Konsole) bereit.<\/li>\n<li><strong>jail.conf direkt bearbeitet.<\/strong> Beim n\u00e4chsten Paket-Update sind alle \u00c4nderungen weg. Nutzen Sie ausschlie\u00dflich <code>jail.local<\/code> oder Dateien in <code>jail.d\/<\/code>.<\/li>\n<li><strong>Falscher Logpfad oder Backend.<\/strong> Auf reinen systemd-Systemen existiert <code>\/var\/log\/auth.log<\/code> oft gar nicht. Dann muss <code>backend = systemd<\/code> gesetzt sein, sonst findet Fail2ban nichts und sperrt nie.<\/li>\n<li><strong>SSH l\u00e4uft auf einem anderen Port, aber die Jail kennt ihn nicht.<\/strong> Der Bann greift dann am falschen Port. Setzen Sie <code>port<\/code> in der Jail auf Ihren tats\u00e4chlichen SSH-Port.<\/li>\n<li><strong>Jail f\u00fcr einen nicht installierten Dienst aktiviert.<\/strong> Fehlende Logdateien f\u00fchren zu Startfehlern. Aktivieren Sie nur Jails f\u00fcr laufende Dienste.<\/li>\n<li><strong>bantime zu kurz oder maxretry zu hoch.<\/strong> Wer 600 Sekunden Bann mit zehn Versuchen kombiniert, bremst Angreifer kaum. Drei Versuche und mindestens eine Stunde sind ein vern\u00fcnftiger Startwert.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"troubleshooting-8-typische-probleme-und-ihre-loesung\">Troubleshooting: 8 typische Probleme und ihre L\u00f6sung<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn etwas nicht funktioniert, hilft systematisches Vorgehen. Die folgende Tabelle deckt die h\u00e4ufigsten Symptome ab und nennt die jeweils erste Ma\u00dfnahme.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Symptom<\/th><th>Wahrscheinliche Ursache<\/th><th>L\u00f6sung<\/th><\/tr><\/thead><tbody>\n<tr><td>Dienst startet nicht<\/td><td>Syntaxfehler in jail.local<\/td><td><code>fail2ban-client -t<\/code> ausf\u00fchren, Fehlerzeile lesen<\/td><\/tr>\n<tr><td>Keine IPs werden gesperrt<\/td><td>Falsches Backend oder Logpfad<\/td><td><code>backend = systemd<\/code> setzen, Logpfad pr\u00fcfen<\/td><\/tr>\n<tr><td>Jail fehlt in der Liste<\/td><td><code>enabled = true<\/code> vergessen<\/td><td>In jail.local erg\u00e4nzen, reload<\/td><\/tr>\n<tr><td>Selbst ausgesperrt<\/td><td>Eigene IP nicht in ignoreip<\/td><td>\u00dcber Hoster-Konsole <code>unbanip<\/code><\/td><\/tr>\n<tr><td>Bann greift, aber Zugriff bleibt<\/td><td>Firewall-Backend passt nicht<\/td><td>nftables\/firewalld-Backend angleichen<\/td><\/tr>\n<tr><td>recidive findet nichts<\/td><td>Kein Dateilog vorhanden<\/td><td><code>logtarget<\/code> auf Datei setzen<\/td><\/tr>\n<tr><td>Filter trifft nicht<\/td><td>Regex passt nicht zur Logzeile<\/td><td>Mit <code>fail2ban-regex<\/code> testen<\/td><\/tr>\n<tr><td>Banns nach Neustart weg<\/td><td>Persistenz nicht aktiv<\/td><td>SQLite-DB unter \/var\/lib\/fail2ban pr\u00fcfen<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn gar nichts hilft, ist das Fail2ban-Log selbst die beste Informationsquelle. Setzen Sie in <code>fail2ban.local<\/code> testweise <code>loglevel = DEBUG<\/code> und beobachten Sie live mit, was der Daemon tut. So sehen Sie genau, welche Logzeilen gelesen, welche Treffer erkannt und welche Aktionen ausgel\u00f6st werden.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Live ins Fail2ban-Log schauen\nsudo tail -f \/var\/log\/fail2ban.log\n\n# Oder, bei reinem systemd-Logging, direkt ins Journal\nsudo journalctl -u fail2ban -f<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fortgeschrittene-tipps-fuer-den-produktiven-einsatz\">Fortgeschrittene Tipps f\u00fcr den produktiven Einsatz<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Hat das Grundger\u00fcst einmal Bestand, lohnt sich der Blick auf einige weiterf\u00fchrende Techniken, die Fail2ban von einem reinen SSH-Schutz zu einer ernsthaften Verteidigungsschicht machen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"geoblocking-und-allports-banns-kombinieren\">Geoblocking und allports-Banns kombinieren<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wer einen Server nur aus Deutschland oder der EU administriert, kann mit <code>banaction_allports<\/code> arbeitende Jails so konfigurieren, dass wiederholte Angreifer auf allen Ports gesperrt werden. In Kombination mit der <code>recidive<\/code>-Jail entsteht so ein gestuftes System: kurzer Bann pro Dienst, langer Allports-Bann bei Wiederholung. Echtes Geoblocking geh\u00f6rt in die vorgelagerte Firewall (etwa <a href=\"\/opnsense-vs-pfsense\/\">OPNsense oder pfSense<\/a>), Fail2ban erg\u00e4nzt es auf Anwendungsebene.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"anbindung-an-abuseipdb\">Anbindung an AbuseIPDB<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban kann gesperrte IPs automatisch an Reputationsdienste wie AbuseIPDB melden. Dazu legen Sie eine Aktion an, die beim Bann zus\u00e4tzlich einen API-Aufruf absetzt. Das hilft der gesamten Community, weil andere Betreiber diese IPs dann pr\u00e4ventiv blockieren k\u00f6nnen. Umgekehrt lassen sich AbuseIPDB-Blocklisten \u00fcber die <code>ignorecommand<\/code>-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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"performance-bei-grossen-logmengen\">Performance bei gro\u00dfen Logmengen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Auf stark frequentierten Webservern k\u00f6nnen die Logdateien riesig werden. Das <code>systemd<\/code>-Backend ist hier in der Regel effizienter als das Pollen klassischer Dateien, weil es Ereignisse direkt aus dem Journal bezieht. Halten Sie zudem <code>maxlines<\/code> und die Anzahl aktiver Jails im Blick. Jede Jail pr\u00fcft jede neue Logzeile gegen ihre Regex, viele komplexe Filter kosten CPU. Im Zweifel lieber wenige, pr\u00e4zise Filter als ein Dutzend, das alles abdecken soll.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"sicherheit-cve-2025-45311-und-realistische-erwartungen\">Sicherheit: CVE-2025-45311 und realistische Erwartungen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Auch ein Sicherheitswerkzeug ist Software und kann Schwachstellen haben. 2025 wurde unter der Kennung CVE-2025-45311 eine m\u00f6gliche lokale Rechteausweitung \u00fcber den <code>fail2ban-client<\/code> 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\u00f6ffentlicht. Die praktische Konsequenz bleibt dieselbe wie immer: Betreiben Sie eine aktuelle Version aus den gepflegten Paketquellen, vermeiden Sie uralte 0.11-St\u00e4nde und halten Sie das System auf dem Patch-Level Ihrer Distribution.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wichtiger als jede einzelne CVE ist die richtige Erwartungshaltung. Fail2ban ist kein Allheilmittel. Es sch\u00fctzt nicht gegen verteilte Angriffe von tausenden verschiedenen IPs, gegen die ein einzelner Bann pro Adresse wenig ausrichtet. Es sch\u00fctzt nicht gegen ein schwaches Passwort, das beim ersten Versuch erraten wird. Und es ist kein Ersatz f\u00fcr eine ordentliche <a href=\"\/https-und-tls\/\">Transportverschl\u00fcsselung<\/a> 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\u00e4lt und die Latte f\u00fcr Angreifer sp\u00fcrbar h\u00f6her legt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"komplettes-projekt-die-fertige-jail-local\">Komplettes Projekt: Die fertige jail.local<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Abschluss hier die vollst\u00e4ndige, kommentierte <code>jail.local<\/code>, wie sie nach allen Schritten dieser Anleitung aussieht. Sie deckt SSH, die <code>recidive<\/code>-Jail und inkrementelle Banns ab und eignet sich als sofort einsetzbare Vorlage f\u00fcr einen Debian- oder Ubuntu-Server. Passen Sie <code>ignoreip<\/code>, den SSH-Port und die E-Mail-Adresse an Ihre Umgebung an.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \/etc\/fail2ban\/jail.local\n# Getestet mit Fail2ban 1.x auf Debian 12 \/ Ubuntu 24.04\n\n[DEFAULT]\n# Niemals sperren: localhost und eigene Admin-IP\nignoreip = 127.0.0.1\/8 ::1 203.0.113.45\n\n# Grund-Logik\nbantime  = 1h\nfindtime = 10m\nmaxretry = 5\n\n# Inkrementelle Banns gegen Wiederholungstaeter\nbantime.increment = true\nbantime.factor    = 2\nbantime.maxtime   = 1w\n\n# Journal als Logquelle, nftables als Firewall\nbackend            = systemd\nbanaction          = nftables-multiport\nbanaction_allports = nftables-allports\n\n# Optional: E-Mail bei jedem Bann\n# destemail = admin@example.com\n# action    = %(action_mw)s\n\n[sshd]\nenabled  = true\nport     = ssh\nmaxretry = 3\nbantime  = 1h\n\n[recidive]\nenabled   = true\nlogpath   = \/var\/log\/fail2ban.log\nbanaction = %(banaction_allports)s\nfindtime  = 1d\nmaxretry  = 5\nbantime   = 1w<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Speichern, testen, neu laden, fertig: <code>sudo fail2ban-client -t &amp;&amp; sudo fail2ban-client reload<\/code>. Mit dieser Konfiguration ist Ihr Server gegen die \u00fcbergro\u00dfe Mehrheit automatisierter Brute-Force-Angriffe gesch\u00fctzt. Wer noch einen Schritt weiter gehen will, deaktiviert den SSH-Passwort-Login vollst\u00e4ndig und setzt ganz auf Schl\u00fcssel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"haeufig-gestellte-fragen-faq\">H\u00e4ufig gestellte Fragen (FAQ)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"verlangsamt-fail2ban-meinen-server\">Verlangsamt Fail2ban meinen Server?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In der Praxis kaum sp\u00fcrbar. Fail2ban liest Logzeilen und pr\u00fcft sie gegen regul\u00e4re Ausdr\u00fccke, 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 <code>systemd<\/code>-Backend ist dann die effizientere Wahl gegen\u00fcber dem Pollen klassischer Dateien.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"brauche-ich-fail2ban-wenn-ich-nur-ssh-keys-nutze\">Brauche ich Fail2ban, wenn ich nur SSH-Keys nutze?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Es ist weiterhin sinnvoll. Auch mit deaktiviertem Passwort-Login h\u00e4mmern Bots permanent gegen Ihren SSH-Port und f\u00fcllen die Logs. Fail2ban sperrt diese Quellen weg, h\u00e4lt die Logs lesbar und reduziert die Angriffsfl\u00e4che. Die Kombination aus Key-Only-Login und Fail2ban ist der empfohlene Standard.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wie-hebe-ich-einen-versehentlichen-selbst-bann-auf\">Wie hebe ich einen versehentlichen Selbst-Bann auf?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn Sie sich ausgesperrt haben, brauchen Sie einen zweiten Weg auf den Server, meist die Web-Konsole Ihres Hosters. Dort f\u00fchren Sie <code>sudo fail2ban-client set sshd unbanip IHRE_IP<\/code> aus. Tragen Sie Ihre IP danach unbedingt in <code>ignoreip<\/code> ein, damit es nicht wieder passiert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"funktioniert-fail2ban-mit-nftables-oder-nur-mit-iptables\">Funktioniert Fail2ban mit nftables oder nur mit iptables?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Beides. Moderne Distributionen wie Debian 12 und Ubuntu 22.04+ nutzen <code>nftables<\/code> als Standard, RHEL-Derivate setzen auf <code>firewalld<\/code>. Fail2ban bringt passende Aktionen f\u00fcr alle Backends mit. Wichtig ist nur, dass <code>banaction<\/code> zum tats\u00e4chlich aktiven Firewall-System passt, sonst greift der Bann ins Leere.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wo-speichert-fail2ban-die-gesperrten-ips\">Wo speichert Fail2ban die gesperrten IPs?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In einer SQLite-Datenbank unter <code>\/var\/lib\/fail2ban\/fail2ban.sqlite3<\/code>. Dadurch \u00fcberleben 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.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"kann-fail2ban-auch-windows-oder-anwendungen-ohne-log-schuetzen\">Kann Fail2ban auch Windows oder Anwendungen ohne Log sch\u00fctzen?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Fail2ban ist f\u00fcr 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\u00fctzen. F\u00fcr Windows gibt es eigene Werkzeuge; Fail2ban selbst l\u00e4uft dort nicht nativ.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"wie-viele-fehlversuche-sind-ein-guter-maxretry-wert\">Wie viele Fehlversuche sind ein guter maxretry-Wert?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr SSH mit Key-Login sind 3 ein guter Wert, weil legitime Nutzer praktisch nie scheitern. F\u00fcr Webanwendungen mit menschlichen Logins k\u00f6nnen 5 sinnvoller sein, um Tippfehler zu tolerieren. Kombinieren Sie einen niedrigen <code>maxretry<\/code> immer mit einem ausreichend langen <code>bantime<\/code> von mindestens einer Stunde.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ist-das-sperren-fremder-ip-adressen-datenschutzkonform\">Ist das Sperren fremder IP-Adressen datenschutzkonform?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Das Sperren zur Abwehr von Angriffen st\u00fctzt 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\u00e4ren Sie es mit Ihrem Datenschutzbeauftragten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"related-coverage\">Related Coverage<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/ssh-key-erstellen-ed25519-2026\/\">SSH-Key erstellen: Ed25519 in 8 Schritten [2026]<\/a><\/li>\n<li><a href=\"\/nginx-reverse-proxy-https-einrichten\/\">Nginx Reverse Proxy: HTTPS in 12 Schritten [2026]<\/a><\/li>\n<li><a href=\"\/opnsense-vs-pfsense\/\">OPNsense vs pfSense: EU vs USA, 0 \u20ac Basis [2026]<\/a><\/li>\n<li><a href=\"\/bsi-lagebericht-2025-bedrohungslage\/\">BSI Lagebericht: 280.000 Schadprogramme\/Tag [2026]<\/a><\/li>\n<li><a href=\"\/gpg-verschluesselung-gnupg\/\">GPG Verschl\u00fcsselung: 12 Schritte mit GnuPG [2026]<\/a><\/li>\n<li><a href=\"\/security-hub\/\">Online-Sicherheit verst\u00e4ndlich erkl\u00e4rt<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Weiterf\u00fchrende Quellen: das offizielle <a href=\"https:\/\/github.com\/fail2ban\/fail2ban\" target=\"_blank\" rel=\"noopener\">Fail2ban-Projekt auf GitHub<\/a>, die <a href=\"https:\/\/www.fail2ban.org\/wiki\/index.php\/Main_Page\" target=\"_blank\" rel=\"noopener\">Fail2ban-Wiki-Dokumentation<\/a>, die <a href=\"https:\/\/manpages.debian.org\/bookworm\/fail2ban\/jail.conf.5.en.html\" target=\"_blank\" rel=\"noopener\">Debian-Manpage zu jail.conf<\/a>, die <a href=\"https:\/\/github.com\/fail2ban\/fail2ban\/releases\" target=\"_blank\" rel=\"noopener\">offiziellen Release-Hinweise<\/a> sowie der Lagebericht des <a href=\"https:\/\/www.bsi.bund.de\/DE\/Home\/home_node.html\" target=\"_blank\" rel=\"noopener\">BSI<\/a> zur aktuellen Bedrohungslage in Deutschland.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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\u2026<\/p>\n","protected":false},"author":3,"featured_media":132,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-131","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security"],"_links":{"self":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/posts\/131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/comments?post=131"}],"version-history":[{"count":1,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/posts\/131\/revisions"}],"predecessor-version":[{"id":133,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/posts\/131\/revisions\/133"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/media\/132"}],"wp:attachment":[{"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/media?parent=131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/categories?post=131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shattered.io\/de\/wp-json\/wp\/v2\/tags?post=131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}