Home ITHome Serverfail2ban einrichten: Angreifer automatisch aussperren

fail2ban einrichten: Angreifer automatisch aussperren

by Dimitri Roschkowski
0 Kommentare

Wer einen Server ins Internet stellt, hat innerhalb von Minuten die ersten Anmeldeversuche im Protokoll – automatisierte Netze probieren rund um die Uhr Benutzernamen und Passwörter durch. fail2ban liest diese Protokolle mit und sperrt Adressen, die zu oft scheitern, per Firewall aus.

Die Einrichtung dauert zehn Minuten. Zwei Dinge gehen dabei regelmäßig schief, und beide werden in dieser Anleitung nachprüfbar behandelt: Auf aktuellen Systemen gibt es die Protokolldatei nicht mehr, auf die fast alle Anleitungen zeigen. Und wer sich beim Freistellen der eigenen Adresse vertut, sperrt sich selbst aus.

Getestet auf Debian 13 mit fail2ban 1.1.0 (Stand September 2026). Die Sperre wurde dabei echt ausgelöst und wieder aufgehoben; alle Ausgaben stammen aus diesem Durchlauf.

Das Wichtigste in Kürze

  • Bearbeite niemals jail.conf – deine Änderungen wären beim nächsten Update weg. Immer jail.local.
  • Auf Debian 13 und Ubuntu gibt es kein /var/log/auth.log mehr. Die Angabe logpath führt ins Leere; richtig ist backend = systemd.
  • Bei ignoreip gehört die Adresse hinein, mit der du am Server ankommst – nicht zwingend die deines Rechners.
  • fail2ban 1.1 sperrt über nftables, nicht über iptables. Prüfbefehle aus älteren Anleitungen zeigen nichts an.

Schritt 1: Installieren

sudo apt update
sudo apt install fail2ban

Auf der RHEL-Familie – AlmaLinux, Rocky – heißt es sudo dnf install fail2ban, auf Arch sudo pacman -S fail2ban. Dort musst du den Dienst anschließend selbst starten, auf Debian und Ubuntu läuft er sofort:

$ fail2ban-client --version
Fail2Ban v1.1.0
$ systemctl is-enabled fail2ban
enabled
$ systemctl is-active fail2ban
active

Schritt 2: Wo protokolliert dein System eigentlich?

Dieser Schritt fehlt in den meisten Anleitungen und ist der Grund, warum fail2ban bei vielen Lesern „nichts tut“.

Klassisch schrieb der SSH-Dienst fehlgeschlagene Anmeldungen nach /var/log/auth.log. Auf aktuellen Systemen gibt es diese Datei nicht mehr – protokolliert wird ausschließlich ins systemd-Journal. Im Test auf Debian 13:

$ test -f /var/log/auth.log && echo vorhanden || echo NICHT VORHANDEN
NICHT VORHANDEN

Die Anmeldeversuche stehen aber sehr wohl da – nur woanders:

$ sudo journalctl -u ssh -n 3 --no-pager -o cat
Invalid user nichtexistent4 from 10.2.0.188 port 35394
Connection closed by invalid user nichtexistent4 10.2.0.188 port 35394 [preauth]

Steht in deiner Konfiguration also eine Zeile wie logpath = /var/log/auth.log, überwacht fail2ban eine Datei, die es nicht gibt. Der Dienst läuft, das Jail gilt als aktiv – und es wird nie jemand gesperrt. Richtig ist stattdessen backend = systemd.

Prüfe zuerst, was bei dir gilt:

test -f /var/log/auth.log && echo "Datei vorhanden" || echo "Journal verwenden"

Schritt 3: Die eigene Adresse herausfinden – bevor du dich aussperrst

Hier liegt die unangenehmste Falle, und sie hat mich beim Testen beinahe erwischt.

Man trägt üblicherweise die eigene IP-Adresse bei ignoreip ein, damit man sich bei eigenen Tippfehlern nicht selbst sperrt. Die naheliegende Annahme ist, dass das die Adresse des eigenen Rechners ist. Das stimmt nicht immer. Liegt ein Router, eine Bridge oder ein VPN dazwischen, kommst du unter einer anderen Adresse an.

Im Test hatte mein Rechner die Adresse 10.2.0.45 – am Server kam er aber so an:

$ ssh benutzer@server 'echo $SSH_CONNECTION'
10.2.0.200 51234 10.2.0.93 22

Der erste Wert ist die Quelladresse, wie der Server sie sieht: 10.2.0.200. Hätte ich 10.2.0.45 freigestellt, wäre die Ausnahme wirkungslos geblieben.

Führe deshalb immer diesen Befehl aus und nimm den ersten Wert:

ssh dein-benutzer@dein-server 'echo $SSH_CONNECTION'

Bei einer dynamischen Adresse vom Provider trägst du besser das ganze Heimnetz ein oder verlässt dich gar nicht auf ignoreip, sondern auf einen zweiten Zugangsweg – etwa die Konsole beim Anbieter oder Tailscale.

Schritt 4: jail.local anlegen

fail2ban liefert /etc/fail2ban/jail.conf mit. Diese Datei fasst du nicht an – sie wird bei Updates ersetzt. Eigene Einstellungen kommen in jail.local, die Vorrang hat:

sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# Die Adresse, mit der du ANKOMMST - vorher mit $SSH_CONNECTION pruefen
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24

bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
backend = systemd

Die vier Werte im Zusammenspiel:

Einstellung Bedeutung
maxretry So viele Fehlversuche sind erlaubt
findtime … innerhalb dieses Zeitraums
bantime So lange wird dann gesperrt
ignoreip Diese Adressen werden nie gesperrt

Also: fünf Fehlversuche innerhalb von zehn Minuten führen zu einer Stunde Sperre. Für einen Heimserver sind das vernünftige Werte. Wer mag, lässt die Sperrdauer mit jedem Wiederholungsfall wachsen:

bantime.increment = true
bantime.maxtime = 5w

Dann wird aus einer Stunde beim zweiten Mal mehr, beim dritten noch mehr – bis maximal fünf Wochen. Gegen hartnäckige Netze ist das wirksamer als eine feste Dauer.

Neu laden und prüfen:

sudo systemctl restart fail2ban
sudo fail2ban-client status
Status
|- Number of jail:	1
`- Jail list:	sshd

Ob deine Werte angekommen sind:

$ sudo fail2ban-client get sshd bantime
3600
$ sudo fail2ban-client get sshd maxretry
5

Schritt 5: Funktioniert es wirklich? Der Nachweis

Ein aktives Jail ist keine Garantie, dass gesperrt wird – siehe die Falle mit der Protokolldatei. Also prüfen wir es.

Wichtig: Löse den Test von einem anderen Rechner aus, nicht von deinem Arbeitsplatz. Im Test habe ich dafür einen zweiten Rechner im Netz verwendet, dessen Adresse nicht in ignoreip stand.

Ausgangslage:

$ sudo fail2ban-client status sshd
|  |- Currently failed:	0
   |- Currently banned:	0
   |- Total banned:	0

Dann fünf Anmeldeversuche mit nicht existierenden Benutzernamen – vom zweiten Rechner aus:

for i in 1 2 3 4 5; do
  ssh -o BatchMode=yes -o ConnectTimeout=5 nichtexistent$i@dein-server true
done
nichtexistent1@dein-server: Permission denied (publickey,password).
nichtexistent2@dein-server: Permission denied (publickey,password).
...

Und wenige Sekunden später auf dem Server:

$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	1
|  |- Total failed:	5
|  `- Journal matches:	_SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
   |- Currently banned:	1
   |- Total banned:	1
   `- Banned IP list:	10.2.0.188

Zwei Zeilen sind hier wichtig. „Banned IP list“ zeigt, dass gesperrt wurde. Und „Journal matches“ bestätigt, dass fail2ban tatsächlich das Journal liest – stünde dort ein Dateipfad, hättest du das Problem aus Schritt 2.

Die Sperre wirkt auch. Vom gesperrten Rechner aus:

$ ssh benutzer@dein-server
ssh: connect to host dein-server port 22: Connection refused

Der eigene Zugang blieb dabei unberührt, weil die Adresse in ignoreip stand.

Schritt 6: Wie gesperrt wird – nftables statt iptables

Viele Anleitungen zeigen zur Kontrolle sudo iptables -L f2b-sshd. Auf aktuellen Systemen kommt da nichts, und das verunsichert unnötig: fail2ban 1.1 nutzt standardmäßig nftables.

$ sudo fail2ban-client get sshd actions
The jail sshd has the following actions:
nftables

Und so sieht die Sperre auf Paketfilter-Ebene aus:

$ sudo nft list table inet f2b-table
table inet f2b-table {
	set addr-set-sshd {
		type ipv4_addr
		elements = { 10.2.0.188 }
	}

	chain f2b-chain {
		type filter hook input priority filter - 1; policy accept;
		tcp dport 22 ip saddr @addr-set-sshd reject with icmp port-unreachable
	}
}

Der Aufbau ist elegant: eine Adressmenge addr-set-sshd und eine einzige Regel, die alles aus dieser Menge auf Port 22 abweist. Neue Sperren fügen nur einen Eintrag in die Menge ein, statt jedes Mal eine neue Regel anzulegen. Und die Priorität filter - 1 stellt die Kette vor die normalen Filterregeln.

Schritt 7: Sperren verwalten

Die Befehle, die du im Alltag brauchst:

# Übersicht über alle Jails
sudo fail2ban-client status

# Detail zu einem Jail
sudo fail2ban-client status sshd

# Sperre aufheben
sudo fail2ban-client set sshd unbanip 203.0.113.5

# Adresse von Hand sperren
sudo fail2ban-client set sshd banip 203.0.113.5

# Alle Sperren eines Jails aufheben
sudo fail2ban-client unban --all

# Protokoll von fail2ban selbst
sudo journalctl -u fail2ban -n 30 --no-pager

Im Test hob das Entsperren die Wirkung sofort auf:

$ sudo fail2ban-client set sshd unbanip 10.2.0.188
1
$ sudo fail2ban-client status sshd | grep "Currently banned"
   |- Currently banned:	0

Und der vorher gesperrte Rechner kam unmittelbar wieder durch. Ursache und Wirkung sind damit in beide Richtungen belegt.

Weitere Dienste schützen

SSH ist der Anfang. fail2ban bringt Filter für viele Dienste mit – ansehen kannst du sie mit ls /etc/fail2ban/filter.d/. Für einen Heimserver sind vor allem diese interessant:

[nginx-http-auth]
enabled = true

[nginx-botsearch]
enabled = true

[postfix]
enabled = true

Bei Webdiensten hängt der Nutzen daran, ob die Protokolle überhaupt auswertbare Fehlversuche enthalten. Ein Anmeldeformular in einer Webanwendung schreibt seine Fehlschläge oft gar nicht ins Webserver-Protokoll – dann braucht es einen eigenen Filter, und das ist Bastelarbeit.

Der Sonderfall Docker

Läuft der zu schützende Dienst in einem Container, sieht das Protokoll häufig nicht die echte Absenderadresse, sondern die interne Docker-Adresse – und fail2ban sperrt dann sinnlos ein Container-Netz. Zwei Wege helfen:

Erstens einen Reverse Proxy davorsetzen, der die echte Adresse in seinen Protokollen führt, und fail2ban auf dessen Protokoll ansetzen. Zweitens daran denken, dass veröffentlichte Container-Ports die Firewall umgehen – eine fail2ban-Sperre in der normalen Filterkette greift dann für Container-Verkehr nicht. Wie das zusammenhängt, steht ausführlich in unserer Docker-Anleitung für Ubuntu.

Was fail2ban nicht kann

Damit die Erwartung stimmt, drei ehrliche Einschränkungen:

Es ersetzt keine Absicherung. fail2ban erschwert das Durchprobieren, verhindert es aber nicht. Wer ein schwaches Passwort hat, wird geknackt – nur langsamer. Der wirksamere Schritt ist, Passwort-Logins ganz abzuschalten und nur SSH-Keys zuzulassen. Danach ist fail2ban vor allem dafür gut, die Protokolle ruhig zu halten.

Gegen verteilte Angriffe hilft es kaum. Kommt jeder Versuch von einer anderen Adresse, erreicht keine davon maxretry.

Es kann dich aussperren. Ein Tippfehler beim eigenen Passwort, fünfmal wiederholt, und du bist draußen – deshalb der Aufwand mit ignoreip und einem zweiten Zugangsweg.

Nützlich für den eigenen Server

Ein zweiter Zugangsweg ist beim Absichern wichtiger als jede Software – und ein Mini-PC ist der beste Übungsserver.

* Affiliate-Links: Als Amazon-Partner verdienen wir an qualifizierten Käufen. Bitte prüfe die Kompatibilität mit deinem System.

Häufige Fragen

Was macht fail2ban genau?

Es liest Protokolle mit, erkennt darin Muster fehlgeschlagener Anmeldungen und legt für auffällige Adressen eine Firewall-Regel an, die sie für eine festgelegte Zeit abweist. Danach wird die Regel automatisch entfernt.

Wie sehe ich, welche Adressen gesperrt sind?

sudo fail2ban-client status sshd zeigt die Liste. Auf Paketfilter-Ebene: sudo nft list table inet f2b-table.

Ich habe mich selbst gesperrt. Was nun?

Wenn du noch eine offene Sitzung hast: sudo fail2ban-client set sshd unbanip DEINE_IP. Sonst brauchst du einen anderen Zugangsweg – die Notfallkonsole beim Anbieter, physischen Zugang oder ein VPN. Warte im Zweifel einfach die Sperrdauer ab. Genau deshalb sollte bantime beim Einrichten nicht auf „für immer“ stehen.

Warum wird bei mir niemand gesperrt?

Die häufigste Ursache ist Schritt 2: fail2ban überwacht eine Protokolldatei, die es auf deinem System nicht mehr gibt. Prüfe die Zeile „Journal matches“ in fail2ban-client status sshd – steht dort ein Dateipfad statt eines Journal-Ausdrucks, setze backend = systemd.

Soll ich zusätzlich den SSH-Port ändern?

Es reduziert den Lärm in den Protokollen, ist aber kein Sicherheitsgewinn. Wenn du es tust, muss fail2ban den neuen Port kennen – im Jail mit port = 2222.

Läuft fail2ban auch auf FreeBSD?

Ja, über pkg install py311-fail2ban. Die Konfiguration ist dieselbe, nur die Sperraktion nutzt dort pf statt nftables – in der Jail-Konfiguration banaction = pf.

Wie viele Ressourcen braucht es?

Sehr wenige. Ein Python-Prozess mit einigen Dutzend Megabyte Arbeitsspeicher, der Protokolle mitliest. Auf einem Raspberry Pi fällt das nicht auf.

Fazit

fail2ban ist in zehn Minuten eingerichtet und hält die Protokolle sauber, statt sie mit tausenden Fehlversuchen zu fluten. Die Konfiguration passt in zehn Zeilen jail.local.

Entscheidend sind drei Dinge, die keine Standardinstallation für dich erledigt: backend = systemd, weil die alte Protokolldatei nicht mehr existiert. Die richtige Adresse in ignoreip, geprüft über $SSH_CONNECTION. Und ein echter Test, weil ein aktives Jail noch nichts darüber sagt, ob wirklich gesperrt wird.

Den größeren Sicherheitsgewinn bringt allerdings der Schritt davor: SSH-Keys einrichten und Passwort-Login abschalten. Danach ist fail2ban die Ergänzung, nicht die Absicherung.

You may also like

Hinterlasse einen Kommentar