Zum Inhalt springen
Serverküche
Suche

Die Suche wird geladen … (nur in der veröffentlichten Seite verfügbar).

Sicherheit Schwierigkeit: Profi

CrowdSec: moderne, kollaborative Angriffsabwehr

CrowdSec mit dem Traefik-Bouncer einrichten: Angriffe aus den Zugriffs-Logs erkennen, Angreifer per 403 blocken und von der Community-Blocklist profitieren.

· 16 Min. Lesezeit ·Dauer: ca. 45 Minuten
Inhaltsverzeichnis

Fail2ban blockt Brute-Force auf deinen SSH-Zugang – aber was ist mit den Scannern, die den ganzen Tag deine Web-Apps nach Lücken abklopfen? CrowdSec schließt genau diese Lücke: Es erkennt Angriffe in den Zugriffs-Logs von Traefik und sperrt die Angreifer, bevor sie deine Anwendungen überhaupt erreichen.

Was bauen wir?

Am Ende läuft ein CrowdSec-Agent neben deinem Traefik, der die Zugriffs-Logs mitliest, verdächtiges Verhalten anhand von Szenarien erkennt (Port-Scans, Path-Probing, bekannte CVE-Ausnutzung, Login-Brute-Force) und Angreifer-IPs auf eine Sperrliste setzt. Ein Bouncer – hier als Traefik-Plugin – setzt diese Entscheidungen durch: Eine gesperrte IP bekommt bei jeder deiner Apps nur noch 403 Forbidden. Getestet mit CrowdSec v1.7.8, dem Traefik-Bouncer-Plugin v1.7.1 und Traefik v3.7.

So greifen die Teile ineinander:

  • Agent + Local API (LAPI): liest die Logs, wertet sie gegen die Szenarien aus und verwaltet die aktiven Sperren („Decisions"). Das ist der Container, den wir aufsetzen.
  • Bouncer: fragt die LAPI bei jeder Anfrage „ist diese IP gesperrt?" und blockt bei Ja. Der Traefik-Bouncer läuft als Plugin direkt im Reverse Proxy – kein zusätzlicher Container.
  • Community-Blocklist: CrowdSec meldet (anonymisiert) erkannte Angriffe an das zentrale Netzwerk und bekommt dafür eine von allen Nutzern gespeiste Blocklist zurück. IPs, die andernorts schon als bösartig auffielen, sind bei dir dann von vornherein gesperrt. Genau das ist das „kollaborativ" im Titel.

CrowdSec statt fail2ban – oder zusätzlich?

CrowdSec ersetzt fail2ban nicht, es ergänzt es. fail2ban ist unschlagbar einfach für einen Dienst auf dem Host (SSH). CrowdSec spielt seine Stärke bei HTTP-Apps hinter dem Reverse Proxy aus: ein Bouncer schützt alle Apps auf einmal, die Szenarien sind gepflegt und aktuell, und die Community-Blocklist bekommst du gratis dazu. Die saubere Aufteilung: fail2ban bleibt auf SSH, CrowdSec übernimmt die Web-Ebene. Beide dürfen parallel laufen.

Voraussetzungen

  • Ein laufender Reverse Proxy mit Traefik (das proxy-Netz und der Resolver le stammen von dort) mit mindestens einer App dahinter.
  • Fail2ban für den SSH-Schutz – CrowdSec kümmert sich hier um die HTTP-Ebene, nicht um SSH.
  • Grundwissen zu Docker Compose und ein abgesicherter Server mit aktiver Firewall.
🍳 Empfehlung Anzeige

VPS 2000 G12

8 vCore · 16 GB RAM · 512 GB NVMe

ab 19,24 €/Monat

CrowdSec läuft mit wenigen hundert MB neben deinem bestehenden App-Stack – der VPS 2000 hat dafür genug Reserve.

Zu netcup →

💶 5 € Gutschein für netcup-Neukunden:36nc17844976032 (nur Neukunden, keine Domains)

Schritt für Schritt

Schritt 1: Traefiks Zugriffs-Logs einschalten

CrowdSec kann nur erkennen, was es sieht – und es sieht Angriffe über Traefiks Zugriffs-Logs. Die sind standardmäßig aus. Öffne die compose.yaml deines Traefik (aus dem Traefik-Tutorial, Ordner ~/traefik) und ergänze im command-Block diese drei Zeilen:

YAML
      - "--accesslog=true"
      - "--accesslog.filepath=/var/log/traefik/access.log"
      - "--accesslog.format=json"

Das JSON-Format ist wichtig – die CrowdSec-Parser erwarten es so. Damit sowohl Traefik (schreibend) als auch CrowdSec (lesend) an dieselbe Datei kommen, legst du sie auf einen festen Host-Pfad. Ergänze im volumes-Block von Traefik:

YAML
      - /var/log/traefik:/var/log/traefik

Lege das Verzeichnis auf dem Host an und starte Traefik neu:

Terminal
sudo mkdir -p /var/log/traefik
cd ~/traefik && docker compose up -d

Ruf einmal eine deiner Apps auf und prüfe, dass Zeilen ankommen:

Terminal
tail -n 2 /var/log/traefik/access.log

Du solltest JSON-Zeilen mit "ClientHost", "RequestPath" und "DownstreamStatus" sehen. Bleibt die Datei leer, stimmt der Pfad im Volume nicht, oder es kam schlicht noch keine Anfrage.

Diese Kontrolle nicht überspringen: CrowdSec nimmt in Schritt 2 nur Dateien auf, die beim Start schon existieren. Fehlt die access.log in dem Moment, meldet es beim Hochfahren No matching files for pattern /var/log/traefik/access.log und liest sie auch später nicht – dann hilft nur ein Neustart des Containers.

Schritt 2: Den CrowdSec-Container aufsetzen

CrowdSec bekommt einen eigenen Ordner. Erzeuge zuerst einen Bouncer-Schlüssel – mit ihm authentifiziert sich später der Traefik-Bouncer an der LAPI:

Terminal
mkdir -p ~/crowdsec && cd ~/crowdsec
openssl rand -hex 32

Kopiere die Ausgabe; sie kommt gleich an zwei Stellen zum Einsatz. Lege die Acquisition an – sie sagt CrowdSec, welche Datei mit welchem Log-Typ zu lesen ist:

YAML
# ~/crowdsec/acquis.yaml
filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik

Jetzt die compose.yaml. Ersetze DEIN_BOUNCER_KEY durch den erzeugten Schlüssel:

YAML
services:
  crowdsec:
    image: crowdsecurity/crowdsec:v1.7.8
    container_name: crowdsec
    environment:
      COLLECTIONS: "crowdsecurity/traefik"
      BOUNCER_KEY_TRAEFIK: "DEIN_BOUNCER_KEY"
      GID: "1000"
    volumes:
      - ./acquis.yaml:/etc/crowdsec/acquis.d/traefik.yaml:ro
      - /var/log/traefik:/var/log/traefik:ro
      - crowdsec-db:/var/lib/crowdsec/data/
      - crowdsec-config:/etc/crowdsec/
    networks: [proxy]
    restart: unless-stopped

volumes:
  crowdsec-db:
  crowdsec-config:

networks:
  proxy:
    external: true

Was hier wichtig ist:

  • COLLECTIONS: crowdsecurity/traefik installiert beim ersten Start die passende Sammlung aus Parsern und Szenarien für Traefik-Logs (inklusive der HTTP-Basisszenarien).
  • BOUNCER_KEY_TRAEFIK registriert direkt beim Start einen Bouncer namens TRAEFIK mit deinem Schlüssel – das spart den Weg über cscli bouncers add.
  • GID: "1000" lässt den CrowdSec-Prozess unter dieser Gruppe laufen. 1000 ist der übliche Default für den ersten Nutzer; läuft Traefik als root, ist die access.log meist world-readable und die GID ohnehin egal. Ist sie enger gesetzt, prüfe mit ls -l /var/log/traefik/access.log und trag die GID der Gruppe der Datei ein.
  • Das Log ist nur lesend (:ro) eingebunden. CrowdSec hängt im proxy-Netz, damit der Traefik-Bouncer die LAPI später unter crowdsec:8080 erreicht.

Starte den Container und prüfe, dass alles greift:

Terminal
docker compose up -d
docker exec crowdsec cscli collections list

Die Traefik-Collection und die HTTP-Szenarien sollten als enabled erscheinen:

Ausgabe
 Name                                 📦 Status   Version
 crowdsecurity/base-http-scenarios    ✔️  enabled  1.4
 crowdsecurity/http-cve               ✔️  enabled  3.0
 crowdsecurity/linux                  ✔️  enabled  0.4
 crowdsecurity/sshd                   ✔️  enabled  0.9
 crowdsecurity/traefik                ✔️  enabled  0.2
 crowdsecurity/whitelist-good-actors  ✔️  enabled  0.4

linux, sshd und whitelist-good-actors hast du nicht angefordert – die bringt das Image von Haus aus mit. sshd läuft dabei ins Leere, solange du kein SSH-Log in die Acquisition aufnimmst (das macht bei uns weiter fail2ban); whitelist-good-actors verhindert, dass bekannte gute Bots wie der Googlebot gesperrt werden.

Prüfe, dass die Community-Blocklist aktiv ist – das kostet nichts und ist der halbe Nutzen von CrowdSec:

Terminal
docker exec crowdsec cscli capi status
Ausgabe
You can successfully interact with Central API (CAPI)
Sharing signals is enabled
Pulling community blocklist is enabled
Pulling blocklists from the console is enabled

Pulling community blocklist is enabled bestätigt, dass du die kollektive Sperrliste der CrowdSec-Community beziehst – Angreifer, die anderswo auffällig wurden, sind bei dir schon gesperrt, bevor sie es überhaupt versuchen.

Die Community-Blocklist ist am Anfang leer

Erwarte nach dem ersten Start keine gefüllte Sperrliste. Der frisch registrierte Container holt sich die Liste zwar sofort, bekommt aber noch nichts – im Log steht dann wörtlich capi/community-blocklist : received 0 new entries (expected if you just installed crowdsec), und cscli decisions list meldet No active decisions. CrowdSec zieht die Liste danach periodisch im Hintergrund nach; die ersten Einträge tauchen also mit Verzögerung auf. Das ist normal und kein Konfigurationsfehler.

Schritt 3: Den Traefik-Bouncer einbauen

Jetzt der Teil, der die Sperren durchsetzt. Der Bouncer ist ein Traefik-Plugin und besteht aus zwei Ergänzungen an deinem Traefik: das Plugin laden und eine Middleware definieren, die auf alle Apps wirkt.

Lade das Plugin, indem du im command-Block von ~/traefik/compose.yaml ergänzt:

YAML
      - "--experimental.plugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
      - "--experimental.plugins.bouncer.version=v1.7.1"
      - "--entrypoints.websecure.http.middlewares=crowdsec@file"

Die letzte Zeile hängt die Bouncer-Middleware global an den websecure-Entrypoint – damit läuft jede HTTPS-Anfrage an jede App durch den Bouncer, ohne dass du jede App einzeln anfassen musst.

Vorhandene Entrypoint-Middlewares nicht überschreiben

--entrypoints.websecure.http.middlewares ist einwertig: Hast du im Traefik-Aufbau an diesem Entrypoint schon Middlewares gesetzt (etwa Security-Header), überschreibt ein zweites Flag den vorhandenen Wert – dann fallen deine bisherigen Middlewares still weg. Setz also kein zweites Flag, sondern erweitere den bestehenden Wert komma-separiert, z. B. --entrypoints.websecure.http.middlewares=sec-headers@docker,crowdsec@file. Nur wenn an diesem Entrypoint bisher keine Middleware hängt, fügst du das Flag wie oben neu hinzu.

Der Zusatz @file sagt Traefik, woher die Middleware kommt: aus dem File-Provider, also aus einer YAML-Datei statt aus Container-Labels. Der Traefik-Aufbau aus dem Traefik-Tutorial kommt ohne diesen Provider aus – du schaltest ihn also jetzt mit zwei weiteren Zeilen im command-Block ein:

YAML
      - "--providers.file.directory=/dynamic"
      - "--providers.file.watch=true"

Und mountest das Verzeichnis, aus dem er liest, dazu in den volumes-Block:

YAML
      - ./dynamic:/dynamic:ro

--providers.file.watch=true lohnt sich hier besonders: Traefik liest Änderungen an der Middleware-Datei damit ohne Neustart ein – im Test hat eine geänderte Bouncer-Konfiguration nach wenigen Sekunden gegriffen.

Kein zweites File-Provider-Flag

Nutzt dein Traefik den File-Provider schon – etwa weil du ihn in Traefik härten (Tutorial folgt voraussichtlich im Oktober) eingerichtet hast –, ergänze kein zweites Flag: Traefik erlaubt filename und directory nicht gleichzeitig. Zeigt dein Provider auf ein Verzeichnis, kommt die Datei unten einfach dort hinein; zeigt er auf eine einzelne filename-Datei, schreibst du den http.middlewares-Block dort hinein.

Lege die Middleware an (Pfad an deinen File-Provider angepasst):

YAML
# ~/traefik/dynamic/crowdsec.yaml
http:
  middlewares:
    crowdsec:
      plugin:
        bouncer:
          enabled: true
          crowdsecMode: stream
          crowdsecLapiScheme: http
          crowdsecLapiHost: crowdsec:8080
          crowdsecLapiKey: "DEIN_BOUNCER_KEY"

crowdsecLapiKey ist derselbe Schlüssel wie in Schritt 2 – der Bouncer weist sich damit bei der LAPI aus. Mit crowdsecMode: stream zieht der Bouncer die Sperrliste in einem festen Intervall komplett vor und beantwortet jede Anfrage aus dem lokalen Cache – der vom Plugin empfohlene Modus, weil er die LAPI nicht bei jedem Request belastet.

Starte Traefik neu, damit es das Plugin herunterlädt und die Middleware lädt:

Terminal
cd ~/traefik && docker compose up -d
docker compose logs -f traefik

Im Log darf kein ERR zum Plugin oder zur Middleware stehen (Traefik v3 loggt bei Standard-Level nur Fehler – eine ruhige Ausgabe ist das gute Zeichen). Prüfe von der CrowdSec-Seite, dass der Bouncer sich verbunden hat:

Terminal
docker exec crowdsec cscli bouncers list
Ausgabe
 Name     IP Address  Valid  Last API pull         Type                             Version  Auth Type
 TRAEFIK  172.18.0.4  ✔️      2026-08-06T23:37:45Z  Crowdsec-Bouncer-Traefik-Plugin  v1.7.1   api-key

Ein gesetztes Last API pull beweist: Das Plugin spricht mit der LAPI. Die Spalte Version meldet dabei die Plugin-Version zurück – ein bequemer Weg, nach einem Update zu prüfen, dass Traefik wirklich die neue Fassung geladen hat und nicht eine gecachte alte.

Erst CrowdSec, dann Traefik neu starten

Kann der Bouncer die LAPI beim Start von Traefik nicht erreichen, macht er dicht und beantwortet jede Anfrage mit 403 – bis der nächste Pull klappt. Im Test dauerte dieses Fenster knapp eine Minute; im Traefik-Log steht in der Zeit crowdsecQuery:unreachable. Läuft der crowdsec-Container dagegen schon, geht ein Traefik-Neustart ohne eine einzige fehlgeschlagene Anfrage durch. Deshalb die Reihenfolge dieses Tutorials einhalten: CrowdSec zuerst (Schritt 2), Traefik danach.

Schritt 4: Scharf schalten und die Sperre testen

Ruf eine deiner Apps auf – sie sollte ganz normal antworten:

Terminal
curl -s -o /dev/null -w "%{http_code}\n" https://DEINE_APP.DEINE_DOMAIN/
Ausgabe
200

Jetzt sperrst du testweise eine IP von Hand und schaust, ob der Bouncer sie aussperrt. Nimm deine eigene öffentliche IP (curl -s https://ifconfig.me):

Terminal
docker exec crowdsec cscli decisions add --ip DEINE_TEST_IP --duration 5m --reason "test"

Neue Sperren greifen nicht sofort

Der Bouncer holt sich die Entscheidungen im Hintergrund ab und cached sie – bis eine frische Sperre wirkt, können bis zu ~60 Sekunden vergehen (im Test: 41 Sekunden zwischen decisions add und dem ersten 403). Das ist kein Fehler, sondern gewollt (weniger Last auf der LAPI). Im stream-Modus kommt die Verzögerung vom Pull-Intervall (updateIntervalSeconds, Default 60 Sekunden), im live-Modus vom Per-IP-Cache jeder Entscheidung (defaultDecisionSeconds, Default 60 Sekunden). Im echten Betrieb ist das irrelevant; beim Testen musst du kurz warten. Wer die Reaktionszeit drücken will, senkt den jeweils passenden Wert – also updateIntervalSeconds (stream) bzw. defaultDecisionSeconds (live) – in der Middleware, statt den Modus zu wechseln.

Nach der Wartezeit bekommt die gesperrte IP nur noch:

Terminal
curl -s -o /dev/null -w "%{http_code}\n" https://DEINE_APP.DEINE_DOMAIN/
Ausgabe
403

Heb die Test-Sperre wieder auf:

Terminal
docker exec crowdsec cscli decisions delete --ip DEINE_TEST_IP

Schritt 5: Echte Angriffe erkennen lassen

Der eigentliche Sinn: CrowdSec sperrt von selbst, ohne dass du Regeln schreibst. Sobald ein Scanner deine Domain nach Pfaden abklopft (viele 404 in kurzer Zeit), greift das Szenario crowdsecurity/http-probing. So sieht eine automatisch erkannte Sperre aus:

Terminal
docker exec crowdsec cscli alerts list
Ausgabe
 ID  value              reason                             country  as                     decisions
 3   Ip:162.142.125.29  crowdsecurity/http-probing         US       398324 CENSYS-ARIN-01  ban:1
 2   Ip:162.142.125.29  crowdsecurity/http-wordpress-scan  US       398324 CENSYS-ARIN-01  ban:1
Terminal
docker exec crowdsec cscli decisions list
Ausgabe
 ID  Source    Scope:Value        Reason                      Action  Country  AS                     Events
 3   crowdsec  Ip:162.142.125.29  crowdsecurity/http-probing  ban     US       398324 CENSYS-ARIN-01  11

Zwei Dinge sind daran lehrreich. Erstens reichert CrowdSec die Sperre automatisch um Land und Provider (AS) an – hier gehört die IP zum Adressbereich des Internet-weiten Scanners Censys, und sie hat gleich zwei Szenarien ausgelöst: das allgemeine Abklopfen von Pfaden und die WordPress-Variante davon. Zweitens kann eine IP zwar mehrere Alerts, aber nur eine aktive Entscheidung haben – cscli decisions list meldet die zweite als duplicated entries skipped.

Neben den selbst erkannten Angriffen tauchen hier mit der Zeit auch Sperren mit der Quelle lists:crowdsecurity/... auf – das ist die Community-Blocklist: IPs, die weltweit schon negativ aufgefallen sind, blockst du, bevor sie dich das erste Mal treffen.

Warum lokale Tests nichts auslösen

Wenn du das selbst nachstellen willst: Anfragen aus dem eigenen Netz erzeugen keine Sperre. CrowdSec hat den Parser crowdsecurity/whitelists an Bord, der alle privaten IP-Bereiche (RFC 1918) verwirft – cscli metrics zeigt sie dann unter Lines whitelisted. Ein Test von localhost oder aus dem Docker-Netz läuft also immer ins Leere; erst Verkehr von einer öffentlichen IP kommt bei den Szenarien überhaupt an.

Wer die Sperren lieber grafisch statt in cscli-Tabellen sieht, meldet die Instanz kostenlos in der CrowdSec-Console an (der Enroll-Befehl steht in „Wartung & Backups"). Dort erscheinen dieselben Entscheidungen aufbereitet:

Die CrowdSec-Console listet die aktiven Sperren als Tabelle: mehrere IP-Adressen mit der Aktion „ban", einer Ablaufzeit und dem auslösenden Szenario http-probing, jeweils „via crowdsec"
Die CrowdSec-Console (optional, kostenlos): dieselben Entscheidungen wie in cscli, nur grafisch

Die mit der Traefik-Collection installierten HTTP-Szenarien decken das ab, was echte Scanner den ganzen Tag versuchen: das Abklopfen nicht existierender Pfade (http-probing), das Suchen nach sensiblen Dateien und Backdoors, Path-Traversal- und SQL-Injection-/ XSS-Sondierungen, verdächtige User-Agents bekannter Scanner sowie die Ausnutzung bekannter CVEs (aus der Collection crowdsecurity/http-cve). Welche Szenarien aktiv sind, zeigt docker exec crowdsec cscli scenarios list.

Noch eine Stufe schärfer: AppSec (WAF)

Über das reine IP-Blocking hinaus kann CrowdSec als Web Application Firewall arbeiten und bösartige Requests direkt am Inhalt erkennen (Virtual Patching). Das Traefik-Plugin unterstützt diesen AppSec-Modus (ab Plugin 1.2.0 und CrowdSec 1.6.0). Für den Einstieg reicht das hier gezeigte Szenario-basierte Blocking; AppSec ist der lohnende nächste Ausbauschritt, wenn eine besonders exponierte App zusätzlichen Schutz braucht.

Ob CrowdSec deine Logs überhaupt liest, zeigt die Metrik-Übersicht. Ein blankes cscli metrics schüttet inzwischen ein Dutzend Tabellen aus – frag deshalb gezielt nur die Acquisition ab:

Terminal
docker exec crowdsec cscli metrics show acquisition
Ausgabe
| Source                           | Lines read | Lines parsed | Lines unparsed | Lines poured to bucket | Lines whitelisted |
| file:/var/log/traefik/access.log | 40         | 40           | -              | -                      | 40                |

Lines read und Lines parsed gleich hoch heißt: CrowdSec liest die Datei und versteht das JSON. Dass hier auch Lines whitelisted bei 40 steht, ist dem Test geschuldet – die Anfragen kamen aus dem Docker-Netz (siehe Kasten oben). Fehlt die Zeile ganz, kommt kein Log an: cscli lässt leere Tabellen weg, du siehst also nicht Lines read: 0, sondern überhaupt keine Acquisition-Zeile – dann zurück zu Schritt 1.

Schritt 6: Dich selbst nicht aussperren

Ein Fehlalarm gegen deine eigene Wartungs-IP ist ärgerlich. Trag deine feste IP als vertrauenswürdig in die Middleware ein – der Bouncer prüft sie dann gar nicht erst. Ergänze in ~/traefik/dynamic/crowdsec.yaml unter bouncer::

YAML
          clientTrustedIPs:
            - "DEINE_FESTE_IP/32"

Mit --providers.file.watch=true (Schritt 3) übernimmt Traefik die Änderung ohne Neustart. Nachgeprüft: Eine als vertrauenswürdig eingetragene IP bekommt selbst bei aktiver Sperre weiter 200 – der Bouncer fragt die Sperrliste für sie gar nicht erst ab.

Hast du dich doch einmal selbst gesperrt, hebt ein Befehl die Sperre sofort auf – und im Notfall kommst du über die VNC-Konsole im SCP immer noch auf den Server:

Terminal
docker exec crowdsec cscli decisions delete --ip DEINE_IP   # eine IP
docker exec crowdsec cscli decisions delete --all           # alle Sperren

Wenn es nicht funktioniert

Eine frisch gesetzte Sperre wirkt nicht, die IP bekommt weiter 200. Der Bouncer cached die Entscheidungen und zieht neue im stream-Modus erst nach dem Pull-Intervall (bis zu ~60 Sekunden). Kurz warten. Wer die Reaktionszeit drücken will, senkt updateIntervalSeconds in der Middleware (Schritt 3).

cscli metrics show acquisition zeigt keine Zeile für die Log-Datei. CrowdSec liest die Logs nicht – und weil cscli leere Tabellen weglässt, fehlt die Zeile komplett statt Lines read: 0 zu zeigen. Häufigste Ursache: der Container startete, bevor die access.log existierte; dann steht in docker logs crowdsec die Zeile No matching files for pattern /var/log/traefik/access.log, und CrowdSec nimmt die Datei auch später nicht von allein auf – cd ~/crowdsec && docker compose restart behebt das. Prüfe sonst, dass Traefik wirklich nach /var/log/traefik/access.log schreibt (Schritt 1), dass beide Container denselben Host-Pfad einbinden und dass die acquis.yaml genau diesen Pfad nennt.

Nach dem Neustart von Traefik bekommt jede App 403 – auch du selbst. Der Bouncer konnte die LAPI beim Start nicht erreichen und blockt dann im Zweifel, statt ungeschützt durchzulassen. Im Traefik-Log steht dazu crowdsecQuery:unreachable mit der URL http://crowdsec:8080/v1/decisions/stream. Prüfe mit docker ps, dass der crowdsec-Container Up ist – sobald der nächste Pull klappt (bis zu ~60 Sekunden), gehen die Anfragen von allein wieder durch. Das ist sicher, macht CrowdSec aber zu einer kritischen Komponente: Läuft der Container nicht, ist deine Seite betroffen. restart: unless-stopped (oben gesetzt) holt ihn nach einem Server-Neustart automatisch zurück.

CrowdSec sperrt lauter harmlose oder gar keine echten Besucher – die erkannte IP ist immer die deines CDNs. Sitzt ein CDN wie Cloudflare vor Traefik, sieht Traefik nur dessen IP. Dann die echte Client-IP aus dem X-Forwarded-For-Header lesen lassen: In der Middleware forwardedHeadersTrustedIPs mit den CDN-Netzen füllen – sonst sperrst du am Ende das CDN. Direkt an netcup (ohne CDN) ist hier nichts zu tun.

docker compose up -d bei Traefik meldet einen Plugin-Fehler. Traefik lädt das Plugin beim Start aus dem Netz. Prüfe, dass der Server raus darf (die netcup-Firewall sperrt ausgehend nichts, UFW ebenso wenig) und dass modulename und version exakt stimmen.

Wartung & Backups

  • Szenarien aktuell halten. CrowdSecs Stärke sind gepflegte Erkennungsregeln – zieh sie regelmäßig nach: docker exec crowdsec cscli hub update && docker exec crowdsec cscli hub upgrade. Das Image (crowdsecurity/crowdsec) und die Plugin-Version (v1.7.1) hebst du bewusst an; lies bei Hauptversionen die Release-Notes. Nach einem Plugin-Update zeigt dir die Spalte Version in cscli bouncers list, ob Traefik die neue Fassung wirklich geladen hat. CrowdSec entwickelt sich zügig – ein guter Kandidat für regelmäßige Versionsprüfung.

  • Zugriffs-Log rotieren. Traefiks /var/log/traefik/access.log wächst sonst unbegrenzt. Richte eine logrotate-Regel ein – zwingend mit copytruncate: Diese Variante kopiert die Datei weg und leert das Original an Ort und Stelle, statt es umzubenennen und neu anzulegen. Nur so behält CrowdSecs Tail den Dateizugriff (bei rename/create verlöre es den Handle und läse nichts mehr). Lege /etc/logrotate.d/traefik an:

    Ausgabe
    /var/log/traefik/access.log {
        daily
        rotate 7
        compress
        missingok
        notifempty
        copytruncate
    }

    CrowdSec liest nach dem Truncate an der wieder wachsenden Datei ganz normal weiter – ein Neustart des Containers ist nicht nötig.

  • fail2ban bleibt. Nimm fail2ban nicht heraus – es schützt weiter deinen SSH-Zugang auf Host-Ebene, während CrowdSec die Web-Apps abdeckt. Zwei Werkzeuge, zwei Zuständigkeiten.

  • Backups. Sichern musst du vor allem deine Konfiguration: den Ordner ~/crowdsec (compose.yaml, acquis.yaml) und ~/traefik/dynamic/crowdsec.yaml mit dem Bouncer-Key. Nimm sie in dein Restic-Backup auf. Die Sperrlisten selbst sind flüchtig und bauen sich von allein wieder auf – kein Backup nötig.

  • Optional: das CrowdSec-Dashboard. Wer die Angriffe grafisch sehen will, meldet die Instanz kostenlos in der CrowdSec Console an (docker exec crowdsec cscli console enroll DEIN_ENROLL_KEY). Die Community-Blocklist läuft auch ohne Anmeldung.

  • In dein Monitoring einbinden. cscli metrics liefert dir Zahlen fürs Terminal; für Dauerbeobachtung stellt CrowdSec einen Prometheus-Endpunkt bereit (in der Config unter prometheus: aktivieren), den du an deinen Grafana-Stack hängen kannst. Dann siehst du Sperren nach Herkunft und Szenario auf einen Blick:

    Ein Grafana-Dashboard mit CrowdSec-Metriken: rund 15.000 aktive Sperren gesamt, aufgeschlüsselt nach Herkunft (Community-Blocklist vs. lokal erkannt) und nach Szenario wie ssh:bruteforce, generic:scan und http-probing
    CrowdSec in Grafana: aktive Sperren nach Herkunft und Szenario, gespeist aus dem Prometheus-Endpunkt

  • Ehrlich zum Aufwand: Nach dem Aufsetzen läuft CrowdSec weitgehend allein. Plane einmal im Monat den hub upgrade und einen Blick auf cscli metrics und die Container-Version ein.

Zuletzt aktualisiert: 20.08.2026

Feedback per E-Mail: feedback@serverkueche.de

Das könnte dir auch schmecken