SSH- und Web-Logins zuverlässig absichern
fail2ban überwacht Log-Dateien von SSH und Webanwendungen in Echtzeit, erkennt wiederholte Fehlanmeldungen anhand konfigurierbarer Muster und sperrt die verursachende IP-Adresse automatisch über die Firewall. Dieser Artikel zeigt, wie Administratoren Jails für SSH und Web-Logins korrekt konfigurieren, Bannzeiten sinnvoll abstimmen und die Aktivität von fail2ban dauerhaft überwachen, ohne legitime Nutzer versehentlich auszusperren.
Inhaltsverzeichnis
- 1. Warum Brute-Force-Schutz auf jedem Linux-Server Pflicht ist
- 2. Wie fail2ban funktioniert: Log-Pattern-Matching und Firewall-Bans
- 3. Installation und Grundkonfiguration: jail.local, filter.d, action.d
- 4. SSH-Jail konfigurieren und absichern
- 5. Web-Login-Endpunkte schützen: Nginx, Magento Admin, WordPress
- 6. Bantime, Findtime und Maxretry richtig einstellen
- 7. Whitelisting und Schutz vor Selbstaussperrung
- 8. Monitoring und Log-Analyse im laufenden Betrieb
- 9. fail2ban im Vergleich: Fehlkonfiguration vs. bewährte Praxis
- 10. Zusammenfassung
- 11. FAQ
1. Warum Brute-Force-Schutz auf jedem Linux-Server Pflicht ist
Jeder Server mit offenem SSH-Port oder öffentlichem Login-Formular wird innerhalb weniger Minuten nach dem Livegang von automatisierten Scannern gefunden. Diese Bots probieren rund um die Uhr Kombinationen aus gängigen Benutzernamen wie root, admin oder www-data mit Passwörtern aus geleakten Listen durch. Ohne Gegenmaßnahme wird jeder einzelne Versuch geloggt, aber nichts hindert den Angreifer daran, den nächsten sofort zu starten. Bei tausenden Versuchen pro Tag steigt die Wahrscheinlichkeit eines Treffers messbar, besonders bei schwachen oder wiederverwendeten Passwörtern.
fail2ban schließt genau diese Lücke, indem es aus reaktiver Protokollierung eine aktive Verteidigung macht. Statt nur zu dokumentieren, dass ein Angriff stattfindet, wertet fail2ban die Logdateien in Echtzeit aus und reagiert automatisch mit einer Firewall-Sperre. Für Magento-Betreiber ist das besonders relevant, weil neben SSH auch das Admin-Backend und häufig ein zusätzliches Login-Formular im Storefront angegriffen werden. Ein einzelnes Tool, das beide Angriffsflächen gleichzeitig überwacht, reduziert den Konfigurationsaufwand erheblich gegenüber separaten Lösungen pro Dienst.
2. Wie fail2ban funktioniert: Log-Pattern-Matching und Firewall-Bans
Das Grundprinzip von fail2ban besteht aus drei Bausteinen: einem Filter, der per regulärem Ausdruck fehlgeschlagene Anmeldeversuche in einer Logdatei erkennt, einer Jail, die Filter, Logpfad und Schwellenwerte zu einer aktiven Überwachungseinheit verbindet, und einer Action, die bei Überschreiten der Schwelle eine Firewall-Regel setzt. fail2ban selbst manipuliert keine Passwörter und greift nicht in den Login-Prozess ein, es beobachtet ausschließlich die Logausgabe des überwachten Dienstes und reagiert auf Muster darin.
Technisch läuft der Daemon fail2ban-server permanent im Hintergrund und liest neue Zeilen entweder direkt aus Logdateien oder über die systemd-Journal-Schnittstelle. Erkennt der Filter innerhalb eines Zeitfensters (findtime) eine konfigurierte Anzahl an Fehlversuchen (maxretry) von derselben IP-Adresse, löst die Action aus. Standardmäßig fügt fail2ban dazu eine Regel in iptables, nftables oder firewalld ein, die den gesamten Traffic der betreffenden IP für die konfigurierte bantime verwirft. Nach Ablauf der Bannzeit entfernt fail2ban die Regel automatisch wieder.
3. Installation und Grundkonfiguration: jail.local, filter.d, action.d
Die Installation erfolgt auf Debian- und Ubuntu-Systemen über das offizielle Paket, das systemd-Integration und die gängigsten Filter für SSH bereits mitbringt. Wichtig ist der Unterschied zwischen jail.conf und jail.local: Die Datei jail.conf wird bei Paket-Updates überschrieben und darf deshalb nie direkt bearbeitet werden. Eigene Einstellungen gehören immer in jail.local, die fail2ban automatisch als Override lädt und die bei Updates unangetastet bleibt. Dieselbe Regel gilt für Filter- und Action-Overrides in filter.d/*.local beziehungsweise action.d/*.local.
Nach der Installation lohnt sich ein Blick in /etc/fail2ban/jail.conf, um die verfügbaren vordefinierten Jails zu sehen, auch wenn dort nichts geändert wird. Die eigentliche Konfiguration erfolgt anschließend zentral in jail.local mit einem [DEFAULT]-Block für globale Werte und einzelnen Sektionen pro Dienst. Nach jeder Änderung muss der Dienst neu geladen werden, damit fail2ban die neuen Jails aktiviert und bestehende Sperrlisten neu einliest.
#!/usr/bin/env bash
# Install fail2ban on Debian/Ubuntu and enable the systemd service
sudo apt update
sudo apt install -y fail2ban
# Copy nothing manually, jail.local overrides jail.conf automatically
sudo touch /etc/fail2ban/jail.local
# Enable and start the service
sudo systemctl enable --now fail2ban
# Reload after config changes without dropping active bans
sudo fail2ban-client reload
# Verify which jails are currently active
sudo fail2ban-client status
4. SSH-Jail konfigurieren und absichern
Die sshd-Jail ist bei den meisten Distributionen bereits vordefiniert, muss aber explizit mit enabled = true aktiviert werden. Der Filter sshd erkennt gescheiterte Passwort-Logins, ungültige Benutzernamen und abgebrochene Verbindungen anhand der Meldungen, die sshd nach auth.log beziehungsweise ins systemd-Journal schreibt. Wichtig ist, den korrekten backend-Wert zu setzen: Auf Systemen ohne klassische /var/log/auth.log-Datei, etwa vielen aktuellen Ubuntu- und Debian-Installationen, liest fail2ban über backend = systemd direkt aus dem Journal, statt auf eine nicht existierende Datei zu warten.
Für SSH empfiehlt sich eine strengere Schwelle als für andere Dienste, da erfolgreiche Angriffe hier die höchste Tragweite haben. Eine Kombination aus maxretry = 4, einer moderaten findtime und einer längeren bantime reduziert die Erfolgsquote von Wörterbuchangriffen drastisch, ohne bei einem einzelnen Tippfehler sofort zuzuschlagen. Wer SSH zusätzlich auf einen nicht-standard Port verlegt und Public-Key-Authentifizierung erzwingt, reduziert die Angriffsfläche noch weiter, fail2ban bleibt dabei die zweite Verteidigungslinie für den Fall, dass Passwort-Auth aus Kompatibilitätsgründen noch aktiv ist.
; /etc/fail2ban/jail.local
[DEFAULT]
# Global defaults, overridden per jail below
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = %(sshd_log)s
backend = systemd
maxretry = 4
bantime = 2h
[magento-admin]
enabled = true
port = http,https
filter = magento-admin
logpath = /var/www/html/var/log/system.log
maxretry = 5
findtime = 15m
bantime = 1h
5. Web-Login-Endpunkte schützen: Nginx, Magento Admin, WordPress
Web-Login-Formulare erfordern in der Regel eigene Filter, weil fehlgeschlagene Anmeldeversuche nicht im Standard-Access-Log erscheinen, sondern in einem Anwendungslog. Für Basic-Auth-geschützte Bereiche liefert fail2ban den fertigen Filter nginx-http-auth, der Meldungen aus dem Nginx-Errorlog erkennt. Für das Magento-Admin-Backend gibt es keinen offiziellen Filter, weil Magento fehlgeschlagene Logins in var/log/system.log und nicht im Webserver-Log protokolliert. Ein eigener Filter mit einer passenden failregex ist hier notwendig und lässt sich anhand des tatsächlichen Log-Formats der eigenen Magento-Version erstellen.
Der Filter muss die IP-Adresse zuverlässig als <HOST>-Platzhalter erkennen, sonst schlägt die Jail nie an. Läuft der Shop hinter einem Reverse-Proxy oder Load-Balancer, muss zusätzlich sichergestellt sein, dass die Anwendung die echte Client-IP über X-Forwarded-For korrekt in ihr Log schreibt, sonst bannt fail2ban im schlimmsten Fall die IP des Proxys selbst und legt den gesamten Traffic lahm. Für WordPress-Installationen gilt dasselbe Prinzip: Ein Plugin wie WP fail2ban schreibt strukturierte Log-Zeilen, die ein einfacher Standardfilter zuverlässig auswerten kann, ganz ohne eigene Regex-Entwicklung.
; /etc/fail2ban/filter.d/magento-admin.conf
[Definition]
# Matches failed Magento admin login attempts written to system.log
failregex = ^.*Login attempt failed for user.*from ip <HOST>.*$
^.*main\.CRITICAL: Invalid login attempt from <HOST>.*$
ignoreregex =
6. Bantime, Findtime und Maxretry richtig einstellen
Die drei Kernparameter jeder Jail hängen unmittelbar zusammen und bestimmen, wie aggressiv fail2ban reagiert. findtime definiert das Zeitfenster, in dem Fehlversuche gezählt werden, maxretry die Anzahl der Fehlversuche innerhalb dieses Fensters, bevor gebannt wird, und bantime die Dauer der Sperre. Zu niedrige Werte, etwa maxretry = 20 oder bantime = 60, verschenken die Schutzwirkung fast vollständig, weil ein Angreifer entweder ausreichend Versuche bekommt oder nach einer Minute einfach weitermacht.
Zu aggressive Werte bergen wiederum das Risiko, echte Nutzer bei einem vergessenen Passwort oder einem VPN-Wechsel mitten in der Arbeit auszusperren. Eine bewährte Praxis ist die progressive Bannzeit über bantime.increment = true: Der erste Bann dauert kurz, jede weitere Sperre derselben IP innerhalb der bantime.rndtime-Historie verlängert sich exponentiell. So bleibt ein einzelner Tippfehler folgenlos, während hartnäckige Angreifer nach wenigen Zyklen für Tage oder Wochen ausgesperrt bleiben. Für produktive SSH-Zugänge hat sich maxretry = 3-4 mit findtime = 10m und bantime = 1h als Startwert bewährt, für Web-Logins mit häufigeren legitimen Fehleingaben ist ein etwas großzügigerer Wert sinnvoll.
7. Whitelisting und Schutz vor Selbstaussperrung
Die ignoreip-Direktive im [DEFAULT]-Block ist die wichtigste Absicherung gegen versehentliche Selbstaussperrung. Hier gehören mindestens 127.0.0.1/8 und ::1 hinein, damit lokale Healthchecks und Monitoring-Tools niemals gebannt werden, sowie feste IP-Adressen von Admin-Arbeitsplätzen, Büro-Standorten und CI/CD-Runnern, die regelmäßig auf den Server zugreifen. Ohne diesen Eintrag kann ein fehlgeschlagener Deploy-Job aus der Pipeline die eigene Infrastruktur aus Versehen sperren, was besonders in automatisierten Umgebungen schwer zu diagnostizieren ist.
Wer mit wechselnden IP-Adressen arbeitet, etwa über mobile Verbindungen, sollte statt einer festen IP einen VPN-Zugang mit fester Ausgangs-IP nutzen und nur diese in ignoreip eintragen. Ein zweiter Schutzmechanismus ist ein dokumentierter Notfallzugang: Bei einem Cloud-Server lässt sich über die Konsole des Hosting-Anbieters auch ohne SSH-Zugriff eine Sperre über fail2ban-client set sshd unbanip <IP> aufheben. Diesen Weg im Vorfeld zu kennen erspart Stress, wenn es tatsächlich zu einer Aussperrung kommt.
8. Monitoring und Log-Analyse im laufenden Betrieb
fail2ban ist kein Fire-and-Forget-Tool, sondern erfordert regelmäßige Kontrolle, ob Jails tatsächlich greifen und keine falschen Positiven produzieren. Der Befehl fail2ban-client status <jailname> zeigt die Anzahl der aktuell gebannten IPs sowie die Gesamtzahl der Fehlversuche und Bans seit dem letzten Neustart. Für tiefere Analyse liefert /var/log/fail2ban.log jeden einzelnen Ban- und Unban-Vorgang mit Zeitstempel, was sich hervorragend mit journalctl oder einem zentralen Log-Aggregator kombinieren lässt.
Für proaktive Benachrichtigung lässt sich die action-Direktive um eine Mail- oder Webhook-Action erweitern, die bei jedem Ban automatisch eine Nachricht an Slack, ein Monitoring-System oder eine E-Mail-Adresse sendet. Das ist besonders wertvoll, um ungewöhnliche Angriffsspitzen frühzeitig zu erkennen, etwa wenn plötzlich zehnmal mehr Bans als üblich innerhalb einer Stunde auftreten, was auf eine koordinierte Kampagne statt vereinzelter Scanner hindeutet. Vor jeder produktiven Filteränderung sollte zudem fail2ban-regex gegen eine echte Logdatei laufen, um falsche Treffer oder gar keine Treffer vor dem Rollout zu erkennen.
# Show status and ban count for a specific jail
sudo fail2ban-client status sshd
# Live-tail the fail2ban log for ban and unban events
sudo tail -f /var/log/fail2ban.log
# List all currently banned IPs across all jails
sudo fail2ban-client banned
# Manually unban an IP that was blocked by mistake
sudo fail2ban-client set sshd unbanip 203.0.113.55
# Dry-run a filter against a real log file before enabling it
sudo fail2ban-regex /var/www/html/var/log/system.log \
/etc/fail2ban/filter.d/magento-admin.conf
{
"jail": "sshd",
"action": "ban",
"ip": "198.51.100.23",
"failures": 4,
"timestamp": "2026-07-12T08:14:32+02:00",
"hostname": "shop-prod-01.mironsoft.de",
"bantime_seconds": 7200
}
9. fail2ban im Vergleich: Fehlkonfiguration vs. bewährte Praxis
Die meisten fail2ban-Installationen scheitern nicht an der Installation selbst, sondern an einer zu laxen oder inkonsistenten Konfiguration der Kernparameter. Die folgende Übersicht zeigt die häufigsten Fehler im direkten Vergleich zur empfohlenen Einstellung.
| Bereich | Fehlkonfiguration | Empfohlene Praxis | Vorteil |
|---|---|---|---|
| maxretry | maxretry = 20 | maxretry = 3-5 | Angreifer bekommt kaum Versuche |
| bantime | bantime = 60 (1 Min.) | bantime = 1h + increment | Wiederholungstäter bleiben lange gesperrt |
| ignoreip | Direktive fehlt komplett | ignoreip = 127.0.0.1/8 ::1 Admin-IP | Keine Selbstaussperrung |
| logpath | Falscher Pfad, Jail läuft nie an | Geprüft mit fail2ban-regex | Jail schützt tatsächlich |
| Benachrichtigung | Nur stiller iptables-Eintrag | Mail- oder Webhook-Action | Angriffsspitzen fallen sofort auf |
Der wiederkehrende Fehler in nahezu allen Beispielen der linken Spalte: Werte werden einmal per Copy-Paste aus einem Tutorial übernommen und nie an die eigene Umgebung angepasst. Ein Server mit Reverse-Proxy braucht andere Logpfade als ein Server mit direktem SSH-Zugriff, und ein Shop mit häufigen legitimen Fehleingaben im Checkout braucht eine andere findtime als ein reines Admin-Backend. Die rechte Spalte funktioniert nur, wenn sie regelmäßig gegen die reale Log-Struktur des eigenen Systems validiert wird.
Mironsoft
Server-Hardening, Brute-Force-Schutz und Monitoring für Linux-Infrastruktur
fail2ban sauber konfiguriert, statt copy-paste aus dem Tutorial?
Wir richten Jails für SSH und eure Web-Login-Endpunkte ein, stimmen Bannzeiten auf euren tatsächlichen Traffic ab und bauen Monitoring auf, damit Angriffsspitzen nicht erst durch eine Aussperrung auffallen.
Security-Audit
Bestehende SSH- und Web-Zugänge auf Schwachstellen und fehlende Jails prüfen
Jail-Konfiguration
Individuelle Filter für Magento Admin, Nginx und weitere Login-Endpunkte
Monitoring-Setup
Webhook-Benachrichtigungen und zentrale Log-Auswertung für Ban-Events
10. Zusammenfassung
fail2ban gegen Brute-Force-Angriffe löst ein Problem, das jeder öffentlich erreichbare Server hat: automatisierte Anmeldeversuche, die ohne Gegenmaßnahme unbegrenzt weiterlaufen. Das Zusammenspiel aus Filter, Jail und Action verwandelt passive Logdateien in eine aktive Verteidigung, die verdächtige IP-Adressen automatisch über die Firewall sperrt. Für SSH reicht in der Regel die vordefinierte Jail mit angepassten Schwellenwerten, für Web-Login-Endpunkte wie das Magento-Admin-Backend braucht es meist einen eigenen Filter mit passender failregex auf das tatsächliche Log-Format der Anwendung.
Die Feinabstimmung von bantime, findtime und maxretry entscheidet darüber, ob der Schutz wirksam ist, ohne legitime Nutzer auszusperren. Eine korrekt gepflegte ignoreip-Liste verhindert die häufigste Ursache für Selbstaussperrung, und kontinuierliches Monitoring über fail2ban-client status sowie Webhook-Benachrichtigungen macht sichtbar, wann und wie stark der Server tatsächlich angegriffen wird. fail2ban ersetzt dabei keine grundsätzliche Härtung wie Public-Key-Authentifizierung oder Zwei-Faktor-Login, ergänzt sie aber um eine automatisierte, permanent aktive zweite Verteidigungslinie.
fail2ban gegen Brute-Force-Angriffe - Das Wichtigste auf einen Blick
Funktionsprinzip
Filter erkennt Fehlversuche per Regex, Jail bündelt Logpfad und Schwellenwerte, Action setzt die Firewall-Sperre.
SSH- und Web-Jails
sshd-Jail meist vordefiniert. Für Magento Admin und andere Web-Logins ist ein eigener Filter mit passender failregex nötig.
Tuning ohne Aussperrung
maxretry = 3-5, findtime moderat, bantime.increment für progressive Sperren. ignoreip für Admin-IPs pflegen.
Monitoring
fail2ban-client status, /var/log/fail2ban.log und Webhook-Actions für sofortige Benachrichtigung bei Angriffsspitzen.