Haben Sie Fragen? Senden Sie uns doch eine Nachricht

OneSystems GmbH

OneSystems GmbH

System Management aus der Schweiz

+41 44 586 40 18
Email: info@onesystems.ch

OneSystems GmbH
Grindlenstrasse 9, 9630 Wattwil, Schweiz

Open in Google Maps
  • Home
  • Beratung & Betrieb
  • Dienstleistungen
    • Web Hosting
    • E-Mail Hosting
    • Ihre eigene Daten Cloud
  • Produkte
    • BackupPilot
    • OneTools
      • OneAI – AI Gateway
      • OneRun – Automatisierung
  • Blog
  • Kontakt
    • Remote Support
  • Home
  • Blog
  • Fail2Ban
  • Forgejo mit Fail2Ban absichern: Unsere Konfiguration gegen Crawler und Scanner
12. September 2026

Forgejo mit Fail2Ban absichern: Unsere Konfiguration gegen Crawler und Scanner

Forgejo mit Fail2Ban absichern: Unsere Konfiguration gegen Crawler und Scanner

by Michael Kleger / Sonntag, 09 August 2026 / Published in Fail2Ban, Linux, Sicherheit

Im letzten Beitrag haben wir gezeigt, wie ein stark verteilter Crawler unser öffentlich erreichbares Forgejo-System über längere Zeit nahezu vollständig ausgelastet hat. Die CPU lag zeitweise nahe bei 100 Prozent, während automatisierte Clients in hoher Frequenz unter anderem Blame- und Commit-Ansichten aufriefen.

Mit Checkmk konnten wir die Auswirkungen sauber nachvollziehen. Über die Nginx-Access-Logs liess sich anschliessend erkennen, welche Requests die Last verursachten und von welchen öffentlichen IP-Adressen sie stammten.

Die Lösung bestand am Ende nicht aus einer einzelnen Firewall-Regel. Wir haben die Requests bereits in Nginx möglichst früh abgefangen, Fail2Ban für die dynamische Erkennung und Sperrung eingesetzt und nftables für die eigentliche Blockierung verwendet. Checkmk zeigt uns gleichzeitig, ob diese Massnahmen tatsächlich Wirkung zeigen.

Nach der Veröffentlichung des ersten Artikels kam die Frage auf, wie diese Konfiguration konkret aussieht. Deshalb geht es diesmal stärker ins technische Detail.

Die Architektur

Unser Forgejo-System ist über eine zweistufige Proxy-Struktur erreichbar. Traefik übernimmt als zentraler Reverse Proxy den externen Zugriff und leitet die Requests an Nginx auf der Forgejo-VM weiter. Nginx und Forgejo selbst laufen auf derselben virtuellen Maschine.

Der Request durchläuft damit vereinfacht folgende Komponenten:

Internet
   |
   v
Traefik
   |
   v
Nginx
   |
   v
Forgejo :3000

Nginx übernimmt auf der Forgejo-VM die Weiterleitung an den lokal auf Port 3000 erreichbaren Forgejo-Dienst. Gleichzeitig liefert das Nginx-Access-Log die Grundlage für einen grossen Teil unserer Fail2Ban-Erkennung.

Für die Analyse des Vorfalls war genau dieses Log entscheidend. Dort konnten wir nachvollziehen, welche URLs aufgerufen wurden, wie häufig dies geschah und von welchen IP-Adressen die Requests stammten.

Die echte Client-IP über Traefik und Nginx

Bei einer solchen Proxy-Kette gibt es einen entscheidenden Punkt: Nginx muss die ursprüngliche öffentliche Client-IP kennen.

Ohne entsprechende Konfiguration würde Nginx lediglich die Adresse des vorgeschalteten Traefik-Systems sehen. Für Fail2Ban wäre das ausgesprochen ungünstig, denn eine Sperre muss natürlich den tatsächlichen Client treffen und nicht den eigenen Reverse Proxy.

Auf unserem HTTPS-VirtualHost ist deshalb der vorgeschaltete Proxy als vertrauenswürdig definiert:

set_real_ip_from 10.40.10.211;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

Traefik übermittelt die ursprüngliche Client-Adresse über X-Forwarded-For. Nginx übernimmt diese Adresse und verwendet sie anschliessend als Client-IP.

Wichtig ist, bei set_real_ip_from ausschliesslich Systemen oder Netzen zu vertrauen, die tatsächlich als vorgeschaltete Proxys verwendet werden. Andernfalls könnte ein Client versuchen, seine Adresse über einen manipulierten X-Forwarded-For-Header vorzugeben.

Nachdem diese Konfiguration korrekt eingerichtet war, enthielt /var/log/nginx/access.log die tatsächlichen öffentlichen Quelladressen. Damit konnte Fail2Ban die Systeme sperren, die die Requests tatsächlich verursachten.

Interne Netze von Fail2Ban ausschliessen

Zusätzlich verwenden wir ignoreip, damit eigene Systeme und Management-Netze nicht versehentlich durch Fail2Ban ausgesperrt werden.

In unserer Umgebung gehören dazu unter anderem:

[DEFAULT]

ignoreip = 127.0.0.1/8 ::1 10.40.10.0/24 10.40.80.0/24

Gerade bei aggressiven Jails sollte diese Einstellung geprüft werden, bevor Fail2Ban aktiviert wird. Eine falsch erkannte interne Adresse kombiniert mit maxretry = 1 kann sonst ziemlich effizient die eigene Infrastruktur aussperren.

Crawler bereits in Nginx abfangen

Fail2Ban ist bei uns bewusst nicht die erste Verteidigungslinie. Wenn ein Request bereits eine aufwendige Verarbeitung in Forgejo auslöst, ist ein Teil der Last entstanden, bevor Fail2Ban überhaupt reagieren kann.

Deshalb versuchen wir bekannte Crawler bereits in Nginx abzufangen.

Dafür verwenden wir eine map-Direktive, welche typische Bot- und Crawler-Bezeichnungen im User-Agent erkennt:

map $http_user_agent $block_crawler {
    default 0;

    ~*bot                 1;
    ~*crawler             1;
    ~*spider              1;
    ~*scraper             1;
    ~*meta-externalagent  1;
    ~*facebookexternalhit 1;
    ~*GPTBot              1;
    ~*ChatGPT-User        1;
    ~*ClaudeBot           1;
    ~*Claude-Web          1;
    ~*Bytespider          1;
    ~*Amazonbot           1;
    ~*Google-Extended     1;
}

Im HTTPS-VirtualHost werden erkannte Crawler anschliessend direkt mit HTTP 403 abgewiesen:

# Crawler blockieren
add_header X-Robots-Tag "noindex, nofollow, noarchive" always;

if ($block_crawler) {
    return 403;
}

Damit erreichen viele bekannte Crawler Forgejo gar nicht mehr. Der Request wird bereits von Nginx beantwortet.

Zusätzlich senden wir über X-Robots-Tag die Anweisung, Inhalte nicht zu indexieren, Links nicht zu verfolgen und keine archivierten Kopien anzulegen. Das ist keine Sicherheitsmassnahme und funktioniert nur bei Crawlern, die solche Vorgaben respektieren. Es ist deshalb eine Ergänzung und kein Ersatz für die eigentliche Zugriffskontrolle.

Warum der User-Agent alleine nicht reicht

Eine reine User-Agent-Sperre löst das Problem allerdings nicht vollständig. Ein User-Agent ist keine verlässliche Identität und kann von einem Client praktisch beliebig gesetzt werden.

Genau das zeigte sich auch bei der Analyse unseres Vorfalls. Neben eindeutig erkennbaren Crawlern sahen wir zahlreiche Requests mit User-Agents, die wie normale Chrome-, Firefox-, Safari- oder Edge-Browser aussahen.

Deshalb verwenden wir den User-Agent lediglich als eine zusätzliche Möglichkeit, bekannte Crawler möglichst früh abzuweisen. Für die eigentliche Erkennung problematischer Zugriffe betrachten wir auch den aufgerufenen Pfad und das Verhalten des Clients.

Problematische Blame-Aufrufe separat behandeln

Bei der Analyse fiel auf, dass insbesondere Zugriffe auf Blame-Ansichten des betroffenen Checkmk-Repositories problematisch waren.

Typische Requests sahen beispielsweise so aus:

GET /Checkmk/Checkmk/blame/commit/...
GET /Checkmk/Checkmk/src/commit/...

Solche Repository-Ansichten können deutlich mehr Arbeit verursachen als der Abruf einer einfachen statischen Ressource. Bei mehreren hundert Requests pro Minute wurde daraus entsprechend schnell ein Problem.

Für das konkret betroffene Repository beantworten wir Blame-Aufrufe deshalb bereits direkt in Nginx:

location ~* ^/Checkmk/[^/]+/blame(?:/|$) {
    return 404;
}

Der entscheidende Punkt dabei ist, dass dieser Request Forgejo überhaupt nicht mehr erreicht.

Für Blame-Aufrufe auf anderen Repositories verwenden wir ebenfalls eine Einschränkung. Aus unseren internen Netzen bleiben diese Ansichten erreichbar, externe Zugriffe werden dagegen blockiert:

location ~* ^/[^/]+/[^/]+/blame(?:/|$) {
    allow 10.40.10.0/24;
    allow 10.40.80.0/24;
    deny all;

    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Damit bleibt die Funktion intern verfügbar, während externe automatisierte Zugriffe nicht mehr bis Forgejo gelangen.

Die eingesetzten Fail2Ban-Jails

Auf unserem Forgejo-System laufen mehrere Jails mit unterschiedlichen Aufgaben. Zum Zeitpunkt unserer Tests waren unter anderem folgende aktiv:

forgejo-crawler
nginx-botsearch
nginx-forgejo-scanner
nginx-limit-req
recidive
sshd

Dabei übernimmt nicht eine einzelne Jail den kompletten Schutz. Die Filter reagieren bewusst auf unterschiedliche Verhaltensmuster.

forgejo-crawler: Aus einem auffälligen Request wird eine IP-Sperre

Die Nginx-Regeln lösen zunächst das wichtigste Problem: Bestimmte unerwünschte Requests werden möglichst früh beantwortet und erzeugen dadurch keine entsprechende Arbeit mehr in Forgejo.

Damit ist die Sache allerdings noch nicht vollständig erledigt. Ohne Fail2Ban könnte derselbe Client weiterhin hunderte oder tausende Requests an Nginx senden und würde jedes Mal erneut eine HTTP-Antwort erhalten.

Hier kommt unsere eigene Jail forgejo-crawler ins Spiel.

Fail2Ban überwacht dafür das Nginx-Access-Log:

/var/log/nginx/access.log

Die dort protokollierten Zugriffe werden auf die zuvor identifizierten problematischen Forgejo-Pfade geprüft.

Der Filter kann beispielsweise so aufgebaut werden:

[Definition]

failregex = ^<HOST> - .* "(?:GET|HEAD) /.*?/blame/.* HTTP/.*" (?:403|404) \d+
            ^<HOST> - .* "(?:GET|HEAD) /.*?/src/commit/.* HTTP/.*" (?:403|404) \d+

ignoreregex =

Wichtig ist die Kombination aus Request-Pfad und HTTP-Status. Wir sperren ausdrücklich nicht pauschal jeden Client, der irgendwo einen 403- oder 404-Fehler erzeugt.

Vor der Aktivierung eines eigenen Filters testen wir diesen gegen vorhandene Logdaten:

fail2ban-regex \
    /var/log/nginx/access.log \
    /etc/fail2ban/filter.d/forgejo-crawler.conf

Damit lässt sich kontrollieren, welche Requests tatsächlich erkannt werden und ob Fail2Ban die richtige Client-IP extrahiert.

Warum wir bei forgejo-crawler maxretry = 1 verwenden

Die zugehörige Jail ist bewusst sehr aggressiv eingestellt:

[forgejo-crawler]

enabled = true
filter = forgejo-crawler
logpath = /var/log/nginx/access.log

port = http,https
protocol = tcp
backend = auto

findtime = 1h
maxretry = 1
bantime = 7d

action = %(action_)s

Besonders auffällig ist natürlich:

maxretry = 1

Für allgemeine Webfehler oder fehlgeschlagene Anmeldungen wäre uns dieser Wert viel zu aggressiv. Beim beobachteten Crawler hatten wir allerdings eine spezielle Situation.

Die Requests kamen aus einer enorm grossen Anzahl unterschiedlicher öffentlicher IP-Adressen. Viele Adressen tauchten nur ein einziges Mal auf.

Bei beispielsweise fünf erlaubten Treffern hätte ein grosser Teil dieser Adressen deshalb nie eine Sperre ausgelöst. Ein Client konnte einen Request senden, die IP wechseln und anschliessend von einer anderen Adresse weitermachen.

Deshalb haben wir den Filter möglichst spezifisch gestaltet und im Gegenzug die Schwelle auf einen Treffer reduziert.

maxretry = 1 ist damit ausdrücklich kein allgemeines Fail2Ban-Rezept. Die Einstellung ergibt in unserem Fall nur Sinn, weil vorher sehr genau definiert wurde, welches Verhalten als unerwünscht gilt.

Die Abwehr erfolgt damit in mehreren Stufen

Das Zusammenspiel von Nginx, Fail2Ban und nftables ist für uns der eigentliche Kern der Lösung.

  1. Der Request erreicht Traefik.
  2. Traefik leitet ihn mit der ursprünglichen Client-IP an Nginx weiter.
  3. Nginx erkennt bekannte Crawler oder speziell behandelte Forgejo-Pfade.
  4. Der Request wird gegebenenfalls bereits in Nginx mit 403 oder 404 beantwortet und erreicht Forgejo nicht.
  5. Der Zugriff erscheint mit der tatsächlichen öffentlichen Client-IP im Nginx-Access-Log.
  6. Fail2Ban erkennt ein definiertes problematisches Muster.
  7. Die IP-Adresse wird über nftables gesperrt.
  8. Weitere Verbindungen dieser Adresse werden anschliessend bereits auf Firewall-Ebene abgefangen.

Damit verschiebt sich die Abwehr möglichst weit nach vorne. Ein erster auffälliger Request kann noch Nginx erreichen, muss aber nicht mehr bis Forgejo gelangen. Nach dem Fail2Ban-Treffer wird die betreffende Adresse direkt über nftables blockiert.

nginx-forgejo-scanner gegen klassische Webscanner

Der zweite eigene Filter kümmert sich um ein wesentlich alltäglicheres Problem: automatisierte Scanner, die wahllos nach bekannten Webanwendungen, Konfigurationsdateien oder verwundbaren Endpunkten suchen.

Auf einem Forgejo-System sind beispielsweise Requests auf folgende Pfade auffällig:

/wp-admin/
/wp-login.php
/xmlrpc.php
/phpmyadmin/
/pma/
/.env
/.git/
/vendor/phpunit/
/cgi-bin/
/HNAP1
/boaform/
/actuator/
/server-status

Unser Filter dafür sieht sinngemäss so aus:

[Definition]

failregex = ^<HOST> - .* "(?:GET|POST|HEAD|OPTIONS) /(?:wp-admin(?:/|$)|wp-login\.php(?:\?| HTTP/)|xmlrpc\.php(?:\?| HTTP/)|phpmyadmin(?:/|$)|pma(?:/|$)|\.env(?:\?| HTTP/)|\.git(?:/|$)|vendor/phpunit(?:/|$)|cgi-bin(?:/|$)|HNAP1(?:/|$)|boaform(?:/|$)|actuator(?:/|$)|server-status(?:\?| HTTP/)).*" (?:400|401|403|404|405|410) \d+

ignoreregex =

Die dazugehörige Jail ist weniger aggressiv als forgejo-crawler:

[nginx-forgejo-scanner]

enabled = true
filter = nginx-forgejo-scanner
logpath = /var/log/nginx/access.log

port = http,https
protocol = tcp
backend = auto

findtime = 10m
maxretry = 3
bantime = 7d

Drei entsprechende Scanversuche innerhalb von zehn Minuten sind auf unserem Forgejo-System ein ausreichend deutliches Signal, um die betreffende Adresse vorübergehend zu sperren.

nginx-botsearch als zusätzliche Schutzschicht

Neben unseren eigenen Filtern verwenden wir auch vorhandene Fail2Ban-Filter wie nginx-botsearch.

Damit müssen wir allgemeine Bot- und Scanmuster nicht vollständig selbst pflegen. Die eigenen Filter konzentrieren sich stattdessen auf das Verhalten, das speziell für unsere Forgejo-Umgebung relevant ist.

Die Jail lässt sich beispielsweise folgendermassen aktivieren:

[nginx-botsearch]

enabled = true
port = http,https
logpath = /var/log/nginx/access.log
backend = auto

findtime = 10m
maxretry = 3
bantime = 24h

nginx-limit-req gegen hohe Request-Raten

Neben konkreten URL-Mustern ist auch die Häufigkeit von Requests interessant.

Nginx kann Requests bereits selbst begrenzen. Dadurch lässt sich verhindern, dass einzelne Clients innerhalb sehr kurzer Zeit unbegrenzt viele Anfragen an Forgejo weiterreichen.

Entsprechende Ereignisse können über das Nginx-Error-Log wiederum von Fail2Ban ausgewertet werden.

Die Jail sieht beispielsweise so aus:

[nginx-limit-req]

enabled = true
port = http,https
logpath = /var/log/nginx/error.log

findtime = 10m
maxretry = 10
bantime = 24h

Damit entsteht eine weitere abgestufte Reaktion. Nginx begrenzt zunächst die Request-Rate. Fallen Systeme wiederholt durch entsprechende Überschreitungen auf, kann Fail2Ban die Quelladresse anschliessend längerfristig sperren.

recidive für Wiederholungstäter

Eine weitere interessante Jail ist recidive.

Sie überwacht nicht direkt Nginx oder Forgejo, sondern das Fail2Ban-Log selbst. Damit lassen sich Adressen erkennen, die wiederholt in unterschiedlichen Jails auftauchen oder nach Ablauf einer Sperre erneut auffällig werden.

Eine entsprechende Konfiguration kann beispielsweise so aussehen:

[recidive]

enabled = true
logpath = /var/log/fail2ban.log
backend = auto

findtime = 7d
maxretry = 5
bantime = 4w

banaction = nftables-allports

Während die Web-Jails gezielt HTTP und HTTPS schützen, kann recidive hartnäckige Wiederholungstäter für einen deutlich längeren Zeitraum auf allen Ports sperren.

SSH bleibt ebenfalls geschützt

Neben den Forgejo- und Nginx-spezifischen Regeln läuft weiterhin die klassische sshd-Jail.

Die Webserver-Regeln ersetzen also nicht die üblichen Schutzmechanismen für andere öffentlich erreichbare Dienste. Sie ergänzen diese um Regeln, die auf das tatsächliche Verhalten unserer Anwendung zugeschnitten sind.

nftables übernimmt die eigentliche Sperre

Fail2Ban erkennt das unerwünschte Verhalten und entscheidet, wann eine Adresse gesperrt werden soll. Die eigentliche Blockierung übernimmt bei uns nftables.

Fail2Ban verwaltet dafür entsprechende nftables-Sets. Das lässt sich auf dem System beispielsweise mit folgendem Befehl kontrollieren:

nft list ruleset | grep -A20 -B5 f2b

Gerade bei unserem Forgejo-Crawler war diese Umsetzung relevant. Während des Vorfalls wurden zeitweise mehr als 600’000 IP-Adressen durch Fail2Ban verwaltet.

Solche Mengen möchte man nicht als hunderttausende einzeln gepflegte Firewall-Regeln vorfinden. nftables-Sets ermöglichen eine wesentlich effizientere Verwaltung und Prüfung grosser Mengen von Adressen.

Den Zustand der Jails prüfen

Welche Jails aktuell laufen, lässt sich jederzeit mit folgendem Befehl kontrollieren:

fail2ban-client status

Für Details zu einer einzelnen Jail verwenden wir beispielsweise:

fail2ban-client status forgejo-crawler

Während der intensiven Phase sahen wir dort beispielsweise folgende Werte:

Status for the jail: forgejo-crawler
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     520154
|  `- File list:        /var/log/nginx/access.log
`- Actions
   |- Currently banned: 476092
   |- Total banned:     476092

Die Gesamtzahl der Ban-Ereignisse stieg später auf über 600’000. Gleichzeitig war bereits sichtbar, dass die Anzahl neuer Sperren nach und nach deutlich zurückging.

Fail2Ban mit Checkmk überwachen

Damit kommen wir wieder zum Ausgangspunkt des gesamten Vorfalls.

Checkmk machte uns ursprünglich auf die ungewöhnlich hohe CPU-Auslastung des Forgejo-Servers aufmerksam. Nach der Einrichtung der zusätzlichen Schutzmechanismen wollten wir deshalb nicht einfach davon ausgehen, dass die Änderungen funktionieren.

Wir haben die Fail2Ban-Daten ebenfalls in unser Monitoring aufgenommen.

Dadurch können wir neben den klassischen Systemwerten wie CPU, RAM, Load, Storage und Diensten auch die Entwicklung der gesperrten IP-Adressen beobachten.

Das Ergebnis war ziemlich eindeutig: Während die Zahl der gesperrten Adressen zunächst massiv anstieg, fiel die CPU-Auslastung des Forgejo-Systems gleichzeitig von teilweise nahezu 100 Prozent auf einen niedrigen Bereich zurück.

Nach einigen Tagen ging auch die Anzahl neuer Sperren deutlich zurück. Gleichzeitig wurde das Nginx-Access-Log wesentlich ruhiger.

Genau dieser Zusammenhang ist für uns wichtiger als eine möglichst grosse Ban-Zahl. Mehr als 600’000 Sperren sehen eindrücklich aus, sind aber kein Selbstzweck. Entscheidend ist, dass Forgejo wieder stabil läuft und legitime Zugriffe normal verarbeitet werden können.

Warum wir nicht einfach komplette Netze sperren

Während der Analyse sah es zunächst so aus, als würden bestimmte Provider und Netze besonders häufig auftauchen.

Ein Beispiel war ein Adressbereich von Meta. Nachdem dieser Bereich gesperrt war, kamen die gleichen Request-Muster allerdings weiterhin aus zahlreichen anderen Netzen.

Später fanden wir unter anderem Adressen aus Cloud-Netzen, Mobilfunkanschlüssen und normalen Endkundenanschlüssen aus verschiedenen Ländern.

Damit war relativ schnell klar, dass eine statische Sperrliste von Providern das eigentliche Problem nicht lösen würde.

Komplette grosse Netze zu blockieren erhöht zudem das Risiko, legitime Benutzer auszusperren. Bei einem stark verteilten Crawler ist der Nutzen gleichzeitig begrenzt, weil einfach andere Quelladressen verwendet werden.

Die dynamische Sperre anhand des tatsächlichen Verhaltens war für unseren Fall deshalb die wesentlich sinnvollere Lösung.

Warum wir nicht jeden 404-Fehler sperren

Eine naheliegende Idee wäre gewesen, Fail2Ban einfach auf sämtliche HTTP-404-Antworten loszulassen.

Das wäre technisch leicht umzusetzen, produziert aber unnötige False Positives. Alte Links, Tippfehler, entfernte Ressourcen oder fehlerhafte Anwendungen können ebenfalls einen 404 verursachen.

Statt den HTTP-Status isoliert zu betrachten, kombinieren wir ihn deshalb mit konkreten Request-Mustern.

Ein Zugriff auf eine nicht vorhandene Seite führt damit nicht automatisch zu einer Sperre. Ein Client, der dagegen gezielt die für den Vorfall relevanten Forgejo-Pfade oder typische Scanner-Ziele aufruft, kann wesentlich präziser erkannt werden.

Auch externe Abuse-Reports haben wir getestet

Zwischenzeitlich hatten wir zusätzlich getestet, von Fail2Ban erkannte Adressen automatisiert an einen externen Blocklist-Dienst zu melden.

Technisch liess sich die Integration einrichten. Bei der enormen Anzahl von Ereignissen erwies sich dieser zusätzliche Weg für unseren konkreten Anwendungsfall allerdings als unnötig schwerfällig.

Wir haben die Integration deshalb wieder entfernt und konzentrieren uns auf die lokale Abwehr. Fail2Ban und nftables reagieren direkt auf dem betroffenen System und benötigen für die eigentliche Sperre keinen externen Dienst.

Eigene Filter immer testen

Die hier gezeigten Einstellungen sind auf unsere Forgejo-Umgebung und das tatsächlich beobachtete Verhalten zugeschnitten.

Insbesondere die Einstellung maxretry = 1 sollte nicht blind auf andere Systeme übertragen werden.

Je aggressiver eine Jail reagiert, desto spezifischer muss der zugrunde liegende Filter sein.

Eigene Filter testen wir deshalb zunächst gegen vorhandene Logs:

fail2ban-regex LOGDATEI FILTERDATEI

Nach Änderungen an der Fail2Ban-Konfiguration prüfen wir ausserdem die komplette Konfiguration:

fail2ban-client -t

Erst wenn dieser Test erfolgreich ist, wird die Konfiguration neu geladen beziehungsweise Fail2Ban neu gestartet.

System Management besteht aus dem Zusammenspiel

Für uns ist dieser Forgejo-Fall ein gutes Beispiel dafür, wie wir System Management verstehen.

Fail2Ban alleine hätte das ursprüngliche Problem nicht vollständig gelöst. Ohne korrekt konfigurierte Proxy-Kette hätte Fail2Ban nicht zuverlässig die tatsächlichen Client-Adressen gesehen. Ohne die Nginx-Regeln würden problematische Requests weiterhin Forgejo erreichen. Ohne nftables gäbe es keine effiziente Umsetzung der grossen Anzahl dynamischer Sperren. Und ohne Checkmk hätten wir deutlich weniger Transparenz darüber gehabt, ob die Massnahmen tatsächlich wirken.

Erst das Zusammenspiel der einzelnen Komponenten ergibt eine saubere Lösung:

  • Traefik übernimmt als zentraler Reverse Proxy den externen Zugriff.
  • Nginx läuft auf der Forgejo-VM, blockiert bekannte Crawler und problematische Pfade, leitet legitime Requests an Forgejo weiter und stellt die benötigten Logs bereit.
  • Forgejo stellt die eigentliche Git-Plattform bereit.
  • Fail2Ban wertet die Logs aus und erkennt definierte Verhaltensmuster.
  • nftables setzt die dynamischen IP-Sperren effizient um.
  • Checkmk überwacht Systemressourcen, Dienste und die Entwicklung der Fail2Ban-Sperren.

Bei OneSystems setzen wir genau auf diese Kombination aus Monitoring, Linux System Management, Automatisierung und individuellen Integrationen.

Dabei geht es nicht darum, möglichst viele Werkzeuge auf einem Server zu installieren. Entscheidend ist, zu verstehen, wo ein Problem entsteht, welche Daten für die Analyse benötigt werden, an welcher Stelle sinnvoll eingegriffen werden kann und wie sich die Wirkung anschliessend messen lässt.

Bei unserem Forgejo-System führte dieser Ansatz von einer zeitweise nahezu vollständig ausgelasteten CPU zu einem wieder ruhigen System. Nginx verhindert inzwischen, dass bekannte problematische Requests überhaupt bis Forgejo gelangen. Fail2Ban und nftables kümmern sich anschliessend um auffällige Quelladressen, während Checkmk sichtbar macht, wie sich die Massnahmen auf das Gesamtsystem auswirken.

Während der intensivsten Phase wurden dabei mehr als 600’000 IP-Adressen gesperrt. Inzwischen ist die Zahl neuer Sperren deutlich zurückgegangen und auch das Access-Log ist wesentlich ruhiger geworden.

  • Tweet
Tagged under: Fail2Ban, Forgejo, Nginx, Traefik

About Michael Kleger

What you can read next

Ransomware
Wie Monitoring und Fail2Ban über 600’000 IPs blockiert haben
Dateien mit Sonderzeichen sicher löschen

Schreibe einen Kommentar Antwort abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.

Letzten Beiträge

  • Wie Monitoring und Fail2Ban über 600’000 IPs blockiert haben

    Ein öffentlich erreichbarer Git-Server, eine da...
  • LenoQuectel RM520N-GL 5G Modem unter Ubuntu 26.04 zum Laufen bringen

    Wer schon einmal versucht hat, ein brandneues W...
  • Checkmk Agent Update Fehler: libz.so.1 failed to map segment from shared object

    Beim Ausführen des Checkmk Agent Updaters kann ...
  • PostgreSQL Wartung automatisieren

    PostgreSQL ist eine sehr stabile und leistungsf...
  • Mailrelay + SMTP OAuth Relay: SMTP ohne Passwort, bereit für Microsoft 365

    Dieser Beitrag ist Teil 2 der Mailrelay-Serie u...

Neueste Kommentare

  • Michael Kleger zu Mailrelay + SMTP OAuth Relay: SMTP ohne Passwort, bereit für Microsoft 365
  • Joerg zu Mailrelay + SMTP OAuth Relay: SMTP ohne Passwort, bereit für Microsoft 365
  • Forgejo mit Fail2Ban absichern: Unsere Konfiguration gegen Crawler und Scanner - OneSystems GmbH zu Wie Monitoring und Fail2Ban über 600’000 IPs blockiert haben
  • Computer: Betriebssystem Linux – Dietrichs Blog zu Remote Desktop mit Linux Mint 19
  • Ein schlanker SMTP-Relay-Container für moderne Infrastrukturen - OneSystems GmbH zu Mailrelay + SMTP OAuth Relay: SMTP ohne Passwort, bereit für Microsoft 365

Categories

  • b1gMail
  • CentOS
  • Checkmk
  • Debian
  • Docker
  • Fail2Ban
  • Identitätsanbieter
  • Linux
  • Mac OSX
  • Microsoft Exchange
  • Microsoft Outlook
  • Migration
  • Mint
  • Monitoring
  • Neuigkeiten
  • Nextcloud
  • PowerShell
  • Python
  • Raspberry Pi
  • Sicherheit
  • Tipps und Tricks
  • Ubuntu
  • VMware
  • Webseiten
  • Webserver
  • Windows
  • Windows zu Linux

Die OneSystems GmbH mit Sitz in Wattwil ist ein unabhängiger IT-Dienstleister für die Planung, Umsetzung und den Betrieb moderner IT-Infrastrukturen, Weblösungen und individueller Software. Wir begleiten Unternehmen ganzheitlich von der Konzeption bis zum laufenden Betrieb und übernehmen dabei sowohl technische Verantwortung als auch den langfristigen Support.

Unsere Kunden stammen aus der Schweiz, Deutschland und Österreich und vertrauen auf Lösungen, die stabil, sicher und nachvollziehbar aufgebaut sind. Statt kurzlebiger Trends setzen wir auf saubere Architektur, etablierte Standards und nachhaltige Qualität, damit Systeme nicht nur heute funktionieren, sondern auch morgen noch beherrschbar bleiben.

Letzten Blog Posts

  • Wie Monitoring und Fail2Ban über 600’000 IPs blockiert haben

  • LenoQuectel RM520N-GL 5G Modem unter Ubuntu 26.04 zum Laufen bringen

  • Checkmk Agent Update Fehler: libz.so.1 failed to map segment from shared object

Kontakt

Email: Kontaktformular

OneSystems GmbH
Grindlenstrasse 9
9630 Wattwil
Schweiz

Copyright © 2018-2026 OneSystems GmbH, Alle Rechte vorbehalten.
Impressum | Datenschutzerklärung | AGBs | Kontakt

TOP