Kontakt aufnehmen

Warum wir fail2ban ersetzt haben – und worauf es bei robuster Brute-Force-Abwehr wirklich ankommt

fail2ban ist ein Klassiker – stößt aber im echten Flottenbetrieb an Grenzen. Warum wir für die Brute-Force-Abwehr auf einen schlanken eigenen Dienst gesetzt haben und welche Design-Entscheidungen im Alltag den Unterschied machen.

01.07.2026 · 6 min Lesezeit

fail2ban gehört auf vielen Servern zur Grundausstattung, und das aus gutem Grund: Es liest Logs, erkennt zu viele Fehlversuche und sperrt die Quelle. Für einen einzelnen Server ist das solide und schnell eingerichtet. Sobald man aber viele Systeme gleichzeitig betreibt und sich darauf verlassen muss, dass die Abwehr immer läuft, tauchen Kanten auf, die im Kleinen nie stören.

Wir haben genau diese Kanten über die Zeit gesammelt – und uns irgendwann entschieden, für die Brute-Force-Abwehr einen eigenen, schlanken Dienst zu bauen, statt fail2ban immer weiter zu verbiegen. Das ist kein „fail2ban ist schlecht"-Text. Es ist eine Sammlung von Dingen, die man erst merkt, wenn so ein Schutz über Jahre auf vielen Maschinen laufen soll.

Wo fail2ban im Flottenbetrieb hakt

Die Probleme sind selten dramatisch. Sie sind eher die Art, die man an einem schlechten Tag teuer bezahlt:

  • Last durch Logparsing. Auf Systemen mit viel Log-Aufkommen kostet das ständige Regex-Matching spürbar Ressourcen. Auf einem Server egal, über eine ganze Flotte summiert es sich.
  • Bans verschwinden bei Firewall-Reloads. Wird die Firewall neu geladen oder geflusht – etwa durch ein anderes Tool oder ein Deployment – sind die aktiven Sperren oft einfach weg. Der Angreifer darf wieder klopfen, und niemand merkt es sofort.
  • Rennen um den Firewall-Lock. Wenn mehrere Prozesse gleichzeitig an den iptables-Regeln arbeiten, kommt es zu Konflikten. Im ungünstigen Fall scheitert das Setzen einer Regel stillschweigend.
  • Blinde Flecken beim Monitoring. Die unangenehmste Sorte: Der Dienst ist gestartet, meldet sich als „läuft", verarbeitet aber im Hintergrund seit Stunden nichts mehr. Von außen sieht alles gesund aus, während die Abwehr faktisch tot ist.

Kein einzelner dieser Punkte ist ein K.-o.-Kriterium. Zusammen ergeben sie aber ein Bild: Der Schutz ist nur so lange verlässlich, wie niemand an der Firewall dreht, die Last niedrig bleibt und man nie genau hinschauen muss.

Der Unterschied, der sofort auffällt: Reaktionszeit

Der auffälligste Vorteil zeigt sich schon beim ersten Angriff. fail2ban prüft die Logs in Intervallen und reagiert schubweise – je nach Konfiguration kann zwischen dem verdächtigen Versuch und der tatsächlichen Sperre gut eine Minute vergehen. Für einen automatisierten Brute-Force-Versuch ist eine Minute eine Ewigkeit: In dieser Zeit läuft er einfach weiter und bekommt hunderte zusätzliche Rateversuche geschenkt, bevor die Tür überhaupt zugeht.

Der eigene Dienst arbeitet stattdessen ereignisgetrieben. Er sieht den Fehlversuch praktisch in dem Moment, in dem er im Log landet, und setzt die Sperre innerhalb von Sekunden – im Normalfall im einstelligen Sekundenbereich statt am Ende eines Prüfintervalls. Bei Angriffen, die tausende Versuche pro Minute fahren, ist das kein „ein bisschen schneller", sondern der Unterschied zwischen ein paar abgefangenen Versuchen und einem offenen Zeitfenster von rund einer Minute – pro Angreifer, auf jedem System.

Design-Entscheidung 1: ein Binary ohne Laufzeit-Ballast

Der erste Schritt war bewusst unspektakulär: ein einzelnes, statisch gelinktes Programm ohne Abhängigkeiten zu einer bestimmten Sprachlaufzeit oder Systembibliotheken. Es läuft auf einem frisch installierten Server genauso wie auf einem alten, ohne dass man erst ein halbes Ökosystem nachinstalliert.

Das klingt nach einer Kleinigkeit, ist im Flottenbetrieb aber Gold wert. Ein Schutzmechanismus, der von einer bestimmten Interpreter-Version oder nachinstallierten Paketen abhängt, ist genau ein Paket-Update davon entfernt, unbemerkt auszufallen. Ein eigenständiges Binary hat diese Sollbruchstelle nicht.

Design-Entscheidung 2: Sperren, die einen Firewall-Flush überleben

Der wichtigste Unterschied im Alltag: Die Sperren liegen in einer eigenen, klar abgegrenzten Firewall-Struktur, die ein pauschales Leeren der Firewall übersteht. Wenn ein anderes Tool die Regeln neu aufbaut, bleiben die aktiven Bans erhalten, statt lautlos zu verschwinden.

Genau dieses „lautlos verschwinden" ist das Tückische an der klassischen Variante. Ein Ban, der nach einem Reload weg ist, fällt niemandem auf – bis im Log wieder die immer gleiche Adresse auftaucht. Wenn die Sperre den Reload übersteht, entfällt eine ganze Klasse von schwer auffindbaren Aussetzern.

Design-Entscheidung 3: mit der Firewall zusammenarbeiten, nicht gegen sie

Statt blind eine Regel zu setzen und auf gut Glück zu hoffen, wartet der Dienst geduldig, bis er den Firewall-Lock wirklich bekommt, bevor er schreibt. Das verhindert die stillen Fehlschläge, bei denen eine Sperre eigentlich gesetzt werden sollte, aber im Gerangel mit einem anderen Prozess unterging.

Das ist eine dieser Entscheidungen, die man im Normalbetrieb nie bemerkt – und die genau dann zählt, wenn viel gleichzeitig passiert.

Design-Entscheidung 4: erst beobachten, dann sperren

Diese Lektion kennen wir aus anderen Projekten auch: Ein Schutz, der sofort scharf schaltet, sperrt im Zweifel die Falschen – im schlimmsten Fall die eigenen Leute. Deshalb läuft so etwas bei uns erst im Beobachtungsmodus: Der Dienst protokolliert, wen er sperren würde, ohne tatsächlich etwas zu blockieren.

So sieht man vor der Aktivierung, ob die Schwellwerte passen, ob legitime Zugriffe fälschlich getroffen würden und ob irgendwo ein Sonderfall lauert. Erst wenn das Bild sauber ist, wird tatsächlich gesperrt. Wer schon einmal einen ganzen Standort ausgesperrt hat, weil eine Regel zu aggressiv war, macht das nie wieder anders. Wir haben denselben Grundsatz an anderer Stelle ausführlicher beschrieben, als ein Härtungsprojekt beinahe den VPN abgeschossen hat – die Moral ist jedes Mal dieselbe: erst beobachten, dann erzwingen.

Design-Entscheidung 5: Monitoring, das den Wächter selbst überwacht

Ein Schutzdienst, der unbemerkt stehenbleibt, ist gefährlicher als gar keiner – weil man sich in falscher Sicherheit wiegt. Deshalb reicht es nicht, nur zu prüfen, ob der Prozess „läuft".

Der entscheidende Kniff ist eine recency-basierte Überwachung: Der Check schaut nicht nur, ob der Dienst da ist, sondern wann er zuletzt sinnvoll gearbeitet hat. Verarbeitet er trotz Aktivität seit zu langer Zeit nichts mehr, schlägt das Monitoring an – auch wenn der Prozess formal noch läuft.

Dazu kommt eine automatische Selbstheilung: Meldet die Überwachung einen kritischen Zustand, wird der Dienst kontrolliert neu angestoßen, statt auf einen manuellen Eingriff zu warten. Das fängt genau die Fälle ab, in denen sonst tagelang niemand merkt, dass der Schutz de facto aus ist.

Was das im Betrieb bedeutet

Unterm Strich geht es nicht um „Rust ist schneller als Python" oder um Rechthaberei gegenüber einem bewährten Werkzeug. Es geht darum, dass ein Sicherheitsbaustein, auf den man sich verlässt, ein paar unbequeme Eigenschaften haben muss:

  • Er darf nicht an nachinstallierten Abhängigkeiten hängen.
  • Seine Wirkung muss einen Firewall-Reload überleben.
  • Er muss sauber mit den anderen Werkzeugen auf dem System auskommen.
  • Er darf im Fehlerfall nicht scharf danebengreifen.
  • Und er muss laut werden, wenn er selbst nicht mehr arbeitet.

fail2ban ist für den Einstieg und für einzelne Server völlig in Ordnung. Sobald aber viele Systeme dranhängen und der Schutz wirklich immer stehen muss, lohnt sich der genauere Blick auf diese Punkte. Genau solche Details sind der Unterschied zwischen einem Schutz, der auf dem Papier existiert, und einem, der im Ernstfall auch wirklich greift – und sie sind fester Bestandteil davon, wie wir Server für Unternehmen betreiben und Managed IT verstehen.

Wenn du wissen willst, wie es um Brute-Force-Abwehr, Firewall und Monitoring auf deinen Systemen steht, schauen wir uns das im Rahmen eines IT-Sicherheits-Checks in Ruhe an – bevor es der nächste automatisierte Scan für dich tut.