2tap2b

CrowdSec auf Traefik Plugin mit AppSec und Dashboard upgraden

Inhaltsverzeichnis

Warum das Upgrade?

In meinem vorherigen Post habe ich gezeigt, wie man CrowdSec mit dem separaten Bouncer-Container (fbonalair/traefik-crowdsec-bouncer) einrichtet. Das funktioniert, aber es gibt eine deutlich bessere Lösung: Das native CrowdSec Traefik Plugin.

Die Vorteile des Plugin-Ansatzes:

  • Weniger Container: Kein separater Bouncer-Container mehr nötig
  • AppSec/WAF-Support: Vollwertige Web Application Firewall direkt in Traefik
  • Bessere Performance: Streaming-Modus für schnellere Entscheidungen
  • Captcha-Remediation: Verdächtige IPs können statt gebannt werden erst mal ein Captcha lösen
  • Console-Integration: Alles übersichtlich im CrowdSec Dashboard

Wichtig: Der alte fbonalair/traefik-crowdsec-bouncer wird nicht mehr aktiv weiterentwickelt und unterstützt kein AppSec. Das native Plugin ist der Weg nach vorne.


Voraussetzungen

Bevor wir starten, stellt sicher, dass folgende Voraussetzungen erfüllt sind:


1. CrowdSec für AppSec vorbereiten

AppSec Collections installieren

Zuerst installieren wir die benötigten Collections für die WAF-Funktionalität:

docker exec crowdsec cscli collections install crowdsecurity/appsec-virtual-patching
docker exec crowdsec cscli collections install crowdsecurity/appsec-generic-rules

Die appsec-virtual-patching Collection wird regelmäßig aktualisiert und schützt vor bekannten CVEs. Die appsec-generic-rules Collection erkennt generische Angriffsmuster wie SQL-Injection oder XSS.

acquis.yaml für AppSec erweitern

Bearbeitet eure CrowdSec-Acquisition-Konfiguration:

nano /opt/containers/crowdsec/acquis.yaml

Erweitert die Datei um den AppSec-Listener:

filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik
---
listen_addr: 0.0.0.0:7422
appsec_config: crowdsecurity/virtual-patching
name: traefik_appsec
source: appsec
labels:
  type: appsec

Der AppSec-Listener horcht auf Port 7422 und verwendet die Virtual-Patching-Konfiguration.


2. CrowdSec compose.yaml anpassen

Bearbeitet eure CrowdSec Docker Compose Datei:

nano /opt/containers/crowdsec/compose.yaml
services:
  crowdsec:
    image: crowdsecurity/crowdsec:latest
    container_name: crowdsec
    environment:
      GID: "${GID-1000}"
      COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik"
      APPSEC_CONFIGS: "crowdsecurity/virtual-patching"
      APPSEC_RULES: "crowdsecurity/base-config crowdsecurity/crs"
    volumes:
      - /opt/containers/crowdsec/acquis.yaml:/etc/crowdsec/acquis.yaml
      - ./crowdsec/db:/var/lib/crowdsec/data/
      - ./crowdsec/config:/etc/crowdsec/
      - /opt/containers/traefik/logs:/var/log/traefik/:ro
    expose:
      - "7422"
    networks:
      - frontend
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped

networks:
  frontend:
    external: true

Wichtig: Der alte bouncer-traefik Container wird nicht mehr benötigt. Das Plugin übernimmt diese Aufgabe direkt in Traefik.


3. Traefik Plugin konfigurieren

traefik.yaml anpassen

Fügt das CrowdSec-Plugin zur statischen Konfiguration hinzu:

nano /opt/containers/traefik/config/traefik.yaml

Fügt den experimental-Block hinzu und die Middleware zu den EntryPoints:

global:
  checkNewVersion: false
  sendAnonymousUsage: false

log:
  level: INFO
  filePath: /var/log/traefik/traefik.log
accessLog:
  filePath: /var/log/traefik/access.log

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
      middlewares:
        - crowdsec-bouncer@file
  websecure:
    address: :443
    http:
      middlewares:
        - crowdsec-bouncer@file

certificatesResolvers:
  cloudflare:
    acme:
      email: deine@mail.com
      storage: /var/traefik/certs/cloudflare-acme.json
      caServer: "https://acme-v02.api.letsencrypt.org/directory"
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

# CrowdSec Plugin Konfiguration
experimental:
  plugins:
    crowdsec:
      moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
      version: v1.4.1

providers:
  docker:
    exposedByDefault: false
  file:
    directory: /etc/traefik/conf.d
    watch: true

Bouncer API-Key generieren

Bevor wir die dynamische Konfiguration erstellen, brauchen wir einen API-Key:

# CrowdSec starten falls noch nicht läuft
cd /opt/containers/crowdsec
docker compose up -d

# Warten bis CrowdSec bereit ist
sleep 10

# API-Key für das Plugin generieren
docker exec crowdsec cscli bouncers add traefik-bouncer

Kopiert den angezeigten API-Key – den braucht ihr gleich.

Dynamische Konfiguration erstellen

nano /opt/containers/traefik/config/conf.d/dynamic_conf.yml
http:
  middlewares:
    crowdsec-bouncer:
      plugin:
        crowdsec:
          enabled: true
          crowdsecLapiKey: EUER-API-KEY-HIER
          crowdsecLapiHost: crowdsec:8080
          crowdsecAppsecEnabled: true
          crowdsecAppsecHost: crowdsec:7422
          forwardedHeadersTrustedIPs:
            - 10.0.0.0/8
            - 172.16.0.0/12
            - 192.168.0.0/16

Ersetzt EUER-API-KEY-HIER mit dem API-Key aus dem vorherigen Schritt.


4. Captcha statt Ban (Optional)

Eine coole Funktion des Plugins: Statt IPs direkt zu bannen, könnt ihr sie erst ein Captcha lösen lassen. Das reduziert False-Positives erheblich.

Captcha-Template erstellen

nano /opt/containers/traefik/config/captcha.html
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sicherheitsüberprüfung</title>
    <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0;
            color: #e0e0e0;
        }
        .container {
            background: rgba(255, 255, 255, 0.05);
            backdrop-filter: blur(10px);
            border-radius: 16px;
            padding: 40px;
            text-align: center;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        h1 { margin-bottom: 10px; color: #fff; }
        p { color: #a0a0a0; margin-bottom: 30px; }
        .cf-turnstile { display: flex; justify-content: center; }
    </style>
</head>
<body>
    <div class="container">
        <h1>🔒 Sicherheitsüberprüfung</h1>
        <p>Bitte bestätigt, dass ihr kein Bot seid.</p>
        <form method="POST">
            <div class="cf-turnstile" data-sitekey="{{.CaptchaSiteKey}}"></div>
            <input type="hidden" name="crowdsec_redirect" value="{{.RedirectURL}}">
        </form>
    </div>
</body>
</html>

Captcha in der Konfiguration aktivieren

Erweitert eure dynamic_conf.yml:

http:
  middlewares:
    crowdsec-bouncer:
      plugin:
        crowdsec:
          enabled: true
          crowdsecLapiKey: EUER-API-KEY-HIER
          crowdsecLapiHost: crowdsec:8080
          crowdsecAppsecEnabled: true
          crowdsecAppsecHost: crowdsec:7422
          forwardedHeadersTrustedIPs:
            - 10.0.0.0/8
            - 172.16.0.0/12
            - 192.168.0.0/16
          # Captcha-Konfiguration (Cloudflare Turnstile)
          captchaProvider: turnstile
          captchaSiteKey: "EUER-TURNSTILE-SITE-KEY"
          captchaSecretKey: "EUER-TURNSTILE-SECRET-KEY"
          captchaGracePeriodSeconds: 86400
          captchaHTMLFilePath: /captcha.html

Für die Turnstile-Keys braucht ihr einen kostenlosen Cloudflare-Account. Alternativ funktionieren auch hCaptcha oder reCaptcha.

Traefik Volume für Captcha-Template hinzufügen

Erweitert eure Traefik docker-compose.yaml:

services:
  traefik:
    # ...existing configuration...
    volumes:
      - /run/docker.sock:/run/docker.sock:ro
      - ./config/traefik.yaml:/etc/traefik/traefik.yaml:ro
      - ./data/certs/:/var/traefik/certs/:rw
      - ./config/conf.d/:/etc/traefik/conf.d/:ro
      - ./logs/:/var/log/traefik
      - ./config/captcha.html:/captcha.html:ro  # <-- Captcha-Template

5. CrowdSec Console einrichten

Das Beste kommt zum Schluss: Die CrowdSec Console gibt euch eine schöne Übersicht über alle Alerts, gebannte IPs und den Status eurer Security Engines.

Account erstellen

Erstellt einen kostenlosen Account auf app.crowdsec.net.

Security Engine enrollen

Nach der Registrierung findet ihr unter “Security Engines” → “Add Security Engine” einen Enrollment-Key. Führt dann folgenden Befehl aus:

docker exec crowdsec cscli console enroll EUER-ENROLLMENT-KEY

Danach müsst ihr die Enrollment in der Console bestätigen. Ab jetzt seht ihr:

  • Alle Alerts in Echtzeit
  • Gebannte IPs und deren Herkunft
  • AppSec/WAF-Events
  • Community Blocklists Status
  • Statistiken und Trends

6. Alles starten

Jetzt starten wir das komplette Setup neu:

# CrowdSec neustarten
cd /opt/containers/crowdsec
docker compose down && docker compose up -d

# Warten bis CrowdSec bereit ist
sleep 15

# Traefik neustarten
cd /opt/containers/traefik
docker compose down && docker compose up -d

7. Setup testen

Ban-System testen

# Test-IP sperren
docker exec crowdsec cscli decisions add --ip 1.2.3.4 --duration 5m --reason "Test"

# Entscheidungen anzeigen
docker exec crowdsec cscli decisions list

# Test-Sperre aufheben
docker exec crowdsec cscli decisions delete --ip 1.2.3.4

CrowdSec Metriken prüfen

docker exec crowdsec cscli metrics

Ihr solltet jetzt auch AppSec-Metriken sehen:

Appsec Metrics:
╭────────────────┬────────────────┬─────────────╮
│    Appsec      │ Processed      │ Blocked     │
├────────────────┼────────────────┼─────────────┤
│ traefik_appsec │ 1234           │ 12          │
╰────────────────┴────────────────┴─────────────╯

Nützliche Befehle

# Alle Collections anzeigen
docker exec crowdsec cscli collections list

# AppSec-Regeln anzeigen
docker exec crowdsec cscli appsec-rules list

# Aktuelle Alerts
docker exec crowdsec cscli alerts list --limit 10

# Bouncer-Status prüfen
docker exec crowdsec cscli bouncers list

# CrowdSec-Logs live verfolgen
docker logs -f crowdsec

# Console-Status prüfen
docker exec crowdsec cscli console status

Fazit

Euer CrowdSec-Setup ist jetzt deutlich leistungsfähiger:

  • Natives Traefik-Plugin statt separatem Bouncer-Container
  • WAF/AppSec schützt vor SQL-Injection, XSS und bekannten CVEs
  • Captcha-Remediation für weniger False-Positives
  • Console-Integration für zentrale Übersicht
  • Streaming-Mode für bessere Performance
  • Community Intelligence durch automatische Updates

Die CrowdSec Console zeigt euch jetzt alle Security-Events übersichtlich an – inklusive der AppSec-Alerts. Perfekt, um zu sehen, welche Angriffe tatsächlich auf eure Services stattfinden.