Traefik v2 – Reverse-Proxy mit CrowdSec einrichten

Mit Docker lassen sich sehr leicht neue Container auf einem Host erstellen. Sollen aber mehrere Container über dem Port 80 (HTTP) nach außen kommunizieren, so kann es etwas problematisch werden, da dieser Port nur einmal auf dem Server zur Verfügung steht. Wir benutzen Traefik und erweitern es mit CrowdSec um diese Thematik anzugehen.
0. Versionierung
Datum | Änderung |
---|---|
12.08.2022 | traefik.yml: – unötigen Code entfernt. – Log angepasst dynamic_conf.yml – deprecated funktion auskommentiert |
10.08.2022 | Erfolgskontrolle der Anleitung weiter nach hinten geschoben. 4.3.6. -> 5.1. |
Korrektur der dynamic_conf.yml: secHeder zu secHeaders | |
09.08.2022 | Name des CertResolver von ‚letsEncrypt‘ auf ‚http‘ geändert Anleitung ist nun vollständig auf ältere Anleitungen kompatibel |
Abschnitt 6 hinzugefügt | |
Kompatibilität zu alten Anleitungen verbessert | |
Optimierung der docker-compose.yml von Traefik Netzwerk ‚proxy‘ wird automatisch erstellt | |
08.08.2022 | Fehler in der docker-compose.yml von Traefik behoben- /var/log/crowdsec/traefik/:/var/log/traefik/ |
Information bei Voraussetzungen ergänzt | |
Pfad unter „3.2. Konfiguration anpassen“ korrigiert | |
Befehl um htpasswd-Passwort zu erstellen geändert | |
Veröffentlichung |
1. Was ist das Ziel dieser Anleitung?
Grundsätzlich erweitert diese Anleitung die ursprüngliche Anleitung von Christian. Es werden ein paar Dinge optimiert und es gilt weiterhin der Anspruch euch eine Anleitung zu schreiben, dass Ihr eure Applikationen möglichst sicher nutzen könnt! In dieser Anleitung werden wir:
- Traefik v2 installieren und konfigurieren
- Crowdsec installieren und konfigurieren
- Traefik via Crowdsec überwachen
- Wissen, wie ihr neue Anwendungen zu Traefik hinzufügt.
Achtung: Nach dieser Anleitung ist das Hinzufügen von Anwendungen in Traefik nicht mehr vollständig kompatibel zu Christians Anleitung. Dafür etwas kürzer und einfacher.
2. Vorraussetzung
- Docker mit Docker Compose installiert (Anleitung für Ubuntu / Debian) (Wichtig!)
- htpasswd installiert (
sudo apt update && sudo apt install apache2-utils
)
3. Traefik
3.1. Verzeichnisse / Dateien anlegen
Als erstes legen wir uns ein Verzeichnis für Traefik an und wechsel in das Verzeichnis:
mkdir -p /opt/containers/traefik cd /opt/containers/traefik
Anschließend erzeugen wir uns noch Datein und Ordner, welche wir später noch benötigen:
mkdir -p /opt/containers/traefik/data touch /opt/containers/traefik/data/acme_letsencrypt.json chmod 600 /opt/containers/traefik/data/acme_letsencrypt.json touch /opt/containers/traefik/data/traefik.yml
3.2. Konfiguration anpassen
Nun bearbeiten wir die Datei traefik.yml
:
Dabei ist wichtig, dass in der .yml nur Leerzeichen und keine Tabs benutzen werden dürfen!
nano /opt/containers/traefik/data/traefik.yml
api: dashboard: true certificatesResolvers: http: acme: email: "meine@email.de" storage: "acme_letsencrypt.json" httpChallenge: entryPoint: http entryPoints: http: address: ":80" http: redirections: entryPoint: to: "https" scheme: "https" https: address: ":443" global: checknewversion: true sendanonymoususage: false providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: "proxy" file: filename: "./dynamic_conf.yml" watch: true providersThrottleDuration: 10
# Statische Traefik-Konfigurationsdatei # https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-static-configuration # https://doc.traefik.io/traefik/reference/static-configuration/cli/ api: dashboard: true # Aktivieren des Dashboard # Certificate Resolver # Diese sind für den Abruf von Zertifikaten von einem ACME-Server zuständig # https://doc.traefik.io/traefik/https/acme/#certificate-resolvers certificatesResolvers: http: acme: email: "meine@email.de" # E-Mail-Adresse für die Registrierung storage: "acme_letsencrypt.json" # Datei für die Speicherung von Zertifikate (Ich weiche hier bewusst von dem "Standard": acme.json ab) httpChallenge: entryPoint: http # EntryPoints # EntryPoints sind die Netzwerk-Eingangspunkte in Traefik. Sie definieren den Port, der die Pakete empfängt. # https://doc.traefik.io/traefik/routing/entrypoints/ entryPoints: http: address: ":80" # Erstellen des Einstiegspunkt für HTTP (Port 80) http: redirections: # Weiterleitung von HTTP auf HTTPS (Port 80 zu Port 443). entryPoint: to: "https" # Das Ziel scheme: "https" # Umleitungszielschema https: address: ":443" # Erstellen des Einstiegspunkt für HTTPS (Port 443) global: checknewversion: true # In regelmäßigen Abständen prüfen, ob eine neue Version veröffentlicht wurde. sendanonymoususage: false # Regelmäßige Übermittlung anonymer Nutzungsstatistiken. providers: docker: endpoint: "unix:///var/run/docker.sock" # Den UNIX Docker socket beobachten exposedByDefault: false # Nur Container ausstellen, die explizit aktiviert sind (mit dem Label traefik.enabled) network: "proxy" # Standardnetzwerk, das für Verbindungen zu allen Containern verwendet wird. file: filename: "./dynamic_conf.yml" # Link zur dynamischen Konfiguration watch: true # Achten auf Änderungen providersThrottleDuration: 10 # Frequenz in welchen Abständen die Konfiguration nachgeladen wird
Notwendige Anpassungen (unkommentierte Version)
- Zeile 7: Anpassen an die eigene Email-Adresse.
Informationen
- Ich verwende in dieser Variante bewusst nicht
acme.json
als Dateiname. Diese Variante soll am Ende nicht nur Zertifikate via HTTP-Challange abrufen können sondern auch vorbereitet sein dies via DNS-Challange (damit sind Wildcard-Zertifikate möglich) zu machen. So das wir uns für jeden Container seperat entscheiden können welche Challange wir nutzen bzw. benötigen. - Mit ein Grund für Traefik ist, dass am Ende die Anfrage via HTTPS gehen soll. Um nun nicht jedem einzelnen Container händisch die Weiterleitung auf HTTPS mitgeben zu müssen machen wir das hier einfach als allgemeine Regel.
3.3. Anlegen der dynamischen Konfiguration
Jetzt legen wir noch die dynamische Konfiguration an:
nano /opt/containers/traefik/data/dynamic_conf.yml
tls: options: default: minVersion: VersionTLS12 cipherSuites: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 curvePreferences: - CurveP521 - CurveP384 sniStrict: true http: middlewares: traefikAuth: basicAuth: users: - "benutzer:passworthash" default: chain: middlewares: - default-security-headers - gzip secHeaders: chain: middlewares: - default-security-headers - gzip default-security-headers: headers: browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true frameDeny: true # Deprecated # sslRedirect: true stsIncludeSubdomains: true stsPreload: true stsSeconds: 31536000 customFrameOptionsValue: "SAMEORIGIN" gzip: compress: {}
# TLS # Hier werden alle notwendigen Einstellungen für das Zertifikat getroffen. # In Kombination mit den Einstellungen unter http.middlewares.default-security-headers bekommen wir ein A+ Zertifikat. tls: options: default: minVersion: VersionTLS12 cipherSuites: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 curvePreferences: - CurveP521 - CurveP384 sniStrict: true # Middlewares # Optionale Optimierungen, die bei jeder Anfrage vorgenommen werden sollen bevor diese an den Zielcontainer geleitet wird. http: middlewares: # Eine grundlegende Authentifizierungs-Middleware, um das Traefik-Dashboard via htpasswd zu schützen # Um die Authentifizierung für einen Container zu nutzen können wir "traefik.http.routers.definierteRoute.middlewares=traefikAuth@file" nutzen traefikAuth: basicAuth: users: - "benutzer:passworthash" # Empfohlene Standard-Middleware für die meisten Dienste # Hinzufügbar via "traefik.http.routers.definierteRoute.middlewares=default@file" # Equivalent mit "traefik.http.routers.definierteRoute.middlewares=default-security-headers@file,gzip@file" # Die Liste kann hier auch beliebig erweitert werden default: chain: middlewares: - default-security-headers - gzip # Kompatibilität zu alten Anleitungen. Damit kann auch wieder "traefik.http.routers.definierteRoute.middlewares=secHeader@file" secHeaders: chain: middlewares: - default-security-headers - gzip # Standard Header default-security-headers: headers: browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true frameDeny: true # Deprecated # sslRedirect: true #HSTS Configuration stsIncludeSubdomains: true stsPreload: true stsSeconds: 31536000 customFrameOptionsValue: "SAMEORIGIN" # Gzip Kompression gzip: compress: {}
3.4. Dashboard mit Passwort schützen
Wenn das Dashboard aktiviert wurde ist dies erst mal ungeschützt. Das Dashboard zeigt „nur“ Informationen über die laufenden Dienste an. Das sind Informationen, welche wir nicht unbedingt mit der gesamten Maße teilen möchten. Deswegen schützen wir das Dashboard via htpasswd. Die notwendige Middleware dazu haben wir bereits in der dynamischen Konfiguration unter traefikAuth
schon getroffen. Wir müssen uns nur noch einen Benutzernamen überlegen und ein Wunschpasswort dazu hashen:
echo $(htpasswd -nb <user> '<password>') # Zum Beispiel: # echo $(htpasswd -nb jonathan 'supersicher') # Ausgabe: jonathan:$$apr1$$J8vBlNIm$$lSwLv9iGa8KcCct3EyLD41 # Sollte es an dieser Stelle zu Problemen kommen kann man sich auch das Passwort auf Webseiten # wie zum Beispiel: https://www.redim.de/blog/passwortschutz-mit-htaccess-einrichten generieren lassen.
Nun ergänzen wir die dynamische Konfiguration um den eben generierte Benutzername/Passwort-Information:
nano /opt/containers/traefik/data/dynamic_conf.yml
# [...] http: middlewares: traefikAuth: basicAuth: users: - "benutzer:passworthash" # [...]
# [...] http: middlewares: traefikAuth: basicAuth: users: - "jonathan:$$apr1$$J8vBlNIm$$lSwLv9iGa8KcCct3EyLD41" # [...]
3.5. Docker-Compose.yml anlegen
Nun legen wir die docker-compose.yml
an:
nano /opt/containers/traefik/docker-compose.yml
version: '3.9' services: traefik: container_name: traefik image: traefik:latest volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/traefik.yml:/traefik.yml:ro - ./data/acme_letsencrypt.json:/acme_letsencrypt.json - ./data/dynamic_conf.yml:/dynamic_conf.yml labels: - "com.centurylinklabs.watchtower.enable=true" - "traefik.enable=true" - "traefik.http.routers.traefik.entrypoints=https" - "traefik.http.routers.traefik.rule=Host(`traefik.meinedomain.de`)" - "traefik.http.routers.traefik.middlewares=traefikAuth@file,default@file" - "traefik.http.routers.traefik.tls=true" - "traefik.http.routers.traefik.tls.certresolver=http" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.services.traefik.loadbalancer.sticky.cookie.httpOnly=true" - "traefik.http.services.traefik.loadbalancer.sticky.cookie.secure=true" - "traefik.docker.network=proxy" restart: unless-stopped security_opt: - no-new-privileges:true networks: - proxy hostname: traefik ports: - "80:80" - "443:443" networks: proxy: name: proxy driver: bridge attachable: true
version: '3.9' services: traefik: container_name: traefik image: traefik:latest volumes: # Traefik mit der Zeit vom Server syncronisieren - /etc/localtime:/etc/localtime:ro # Lesezugriff auf den UNIX Docker socket - /var/run/docker.sock:/var/run/docker.sock:ro # Traefik-Konfiguration bereitstellen - ./data/traefik.yml:/traefik.yml:ro # Datei mit Zertifikaten bereitstellen - ./data/acme_letsencrypt.json:/acme_letsencrypt.json # Datei mit dynamischer Konfiguration bereitstellen - ./data/dynamic_conf.yml:/dynamic_conf.yml labels: # Traefik durch Watchtower aktualisieren lassen # https://goneuland.de/docker-images-automatisiert-aktualisieren-mit-watchtower/ - "com.centurylinklabs.watchtower.enable=true" # Traefik für Traefik aktivieren - "traefik.enable=true" # Als Einstiegspunkt wählen wir direkt HTTPS - "traefik.http.routers.traefik.entrypoints=https" # Domain anpassen unter der Traefik erreichbar sein soll. - "traefik.http.routers.traefik.rule=Host(`traefik.meinedomain.de`)" # Middlewares definieren, welche verwendet werden sollen. Hier die Authentifizierung via htpasswd + alle die unter default definiert sind. - "traefik.http.routers.traefik.middlewares=traefikAuth@file,default@file" # SSL Zertifikat abrufen - "traefik.http.routers.traefik.tls=true" # Definierten Zertifikat Resolver aus traefik.yml wählen - "traefik.http.routers.traefik.tls.certresolver=http" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.services.traefik.loadbalancer.server.port=80" - "traefik.http.services.traefik.loadbalancer.sticky.cookie.httpOnly=true" - "traefik.http.services.traefik.loadbalancer.sticky.cookie.secure=true" # Traefik dem Proxy-Netzwerk hinzufügen. - "traefik.docker.network=proxy" restart: unless-stopped security_opt: - no-new-privileges:true networks: - proxy hostname: traefik ports: # Ports definieren, welche durch Traefik gemanaget werden. - "80:80" - "443:443" networks: proxy: name: proxy driver: bridge attachable: true
Notwendige Anpassungen in der unkommentierten Version
- Zeile 16: Auf eigene Domain anpassen
3.6. Traefik starten
Nun können wir Traefik starten:
docker compose -f /opt/containers/traefik/docker-compose.yml up -d
Wenn ihr nun auf traefik.meinedomain.de geht, solltet ihr folgendes sehen:

Nach dem Login mit eurem oben festgelegten Passwort solltet ihr diese Übersicht sehen:

Hier sind wir jetzt fertig mit der Traefik Konfiguration und Installation.
3.7. Anwendungen hinzufügen
Im Allgemeinen ist es wichtig, dass ihr die Labels hinzufügen:
wordpress: labels: # Aktiviert Traefik für diesen Container - "traefik.enable=true" # Hier wird der Einstiegspunkt definiert. Da wir eigentlich zu 99% HTTPS nutzen möchten können wir uns HTTP auch sparen. # Beispielhaft habe ich euch HTTP nochmal auskommentiert hinzugefügt. An dieser Stelle ist keine Weiterleitung zu HTTPS mehr notwenig. # Die Weiterleitung von HTTP zu HTTPS wurde bereits in der traefik.yml festgelegt # - "traefik.http.routers.wordpress.entrypoints=http" # - "traefik.http.routers.wordpress.rule=Host(`wordpress.euredomain.de`)" - "traefik.http.routers.wordpress-ssl.entrypoints=https" - "traefik.http.routers.wordpress-ssl.rule=Host(`wordpress.euredomain.de`)" - "traefik.http.routers.wordpress-ssl.tls=true" - "traefik.http.routers.wordpress-ssl.tls.certresolver=http" - "traefik.http.routers.wordpress-ssl.middlewares=default@file" - "traefik.http.routers.wordpress-ssl.service=wordpress-ssl" - "traefik.http.services.wordpress-ssl.loadbalancer.server.port=80" - "traefik.docker.network=proxy"
Wichtig ist hier auch, dass unser Service “wordpress-ssl” heißt und dementsprechend die Labels auch alle auf den Namen “wordpress-ssl” angepasst werden müssen. Dies kann aber auch jeder andere Name sein. Muss nur konstant sein.
Ihr müsst immer noch das Netzwerk hinzufügen, mit dem Traefik kommuniziert. Dieses Netzwerk ist im einfachsten Fall bei jeder Anwendung identisch. In diesem Fall also “proxy”.
wordpress: networks: - proxy networks: proxy: external: true
Der Name “proxy” wurde hier auch frei gewählt. Dort könnt ihr auch jeden anderen Namen verwenden. Das Netzwerk wird normalerweise durch die docker-compose.yml generiert. Sollte es das nicht der Fall sein:
docker network create proxy
4. CrowdSec
CrowdSec ist ein kostenloses, quelloffenes und kollaboratives IPS. Mit dem Verhaltensweisen analysiert werden, auf Angriffe reagiert wird und Hinweise in der Community geteilt werden. Es ist sozusagen das neue Fail2Ban.
4.1. Verzeichnisse / Dateien anlegen
Als erstes legen wir uns ein Verzeichnis für Crowdsec an und wechsel in das Verzeichnis:
mkdir -p /opt/containers/crowdsec cd /opt/containers/crowdsec
Anschließend erzeugen wir uns noch Datein und Ordner, welche wir später noch benötigen:
mkdir -p /opt/containers/crowdsec/{config,data} touch /opt/containers/crowdsec/.env
4.2. Docker-Compose.yml anlegen
Wir könnten CrowdSec nativ auf unserem Host installieren, allerdings machen wir hier alles mit Docker und auch CrowdSec funktioniert wunderbar mit Docker. In diesem Schritt legen wir uns für CrowdSec die docker-compose.yml an:
nano /opt/containers/crowdsec/docker-compose.yml
version: "3.9" services: crowdsec: container_name: crowdsec image: crowdsecurity/crowdsec:latest environment: PGID: "1000" COLLECTIONS: "crowdsecurity/traefik crowdsecurity/http-cve crowdsecurity/whitelist-good-actors" volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./config:/etc/crowdsec - ./data:/var/lib/crowdsec/data - /var/log/auth.log:/var/log/auth.log:ro - /var/log/crowdsec:/var/log/crowdsec:ro restart: unless-stopped security_opt: - no-new-privileges=true networks: - proxy hostname: crowdsec networks: proxy: external: true
Bis hier her ist das docker-compose.yml nichts besonderes. Wichtig ist, dass wir die GID Berechtigungen gesetzt haben und alle Logs lesen können. Dafür mounten wir:
- /var/log/auth.log:/var/log/auth.log:ro - /var/log/crowdsec:/var/log/crowdsec:ro
Die Umgebungsvariable COLLECTIONS
ermöglicht es uns die Vorinstallation von Collections aus dem CrowdSec Hub. Collections sind Bündel von Parsern und Szenarien, die es einfach machen, Dinge für beliebte Dienste einzurichten. Standardmäßig wird der Container mit der Linux-Sammlung ausgeliefert, welche Syslog- und SSH-Protokolle verarbeitet. Wir werden die traefik-Sammlung, die http-cve-Sammlung, die eine Sammlung derzeitiger aktiver CVEs abdeckt, und die whitelist-good-actors-Sammlung hinzufügen, die hauptsächlich CDNs wie Cloudflare abdeckt. Damit stellen wir sicher, dass wir sie nicht versehentlich blockieren und uns von großen Teilen des Internets abschneiden.
4.3. Konfiguration anpassen
Nun starten wir den Container um alle wichtigen Datein generieren zu lassen:
docker compose -f /opt/containers/crowdsec/docker-compose.yml up -d
4.3.1. Acquis.yaml bearbeiten
Nach dem wir den den Container gestartet haben finden wir die Datei config/acquis.yaml
und passen diese für unsere Bedürfnisse an:
sudo nano /opt/containers/crowdsec/config/acquis.yaml
filenames: - /var/log/auth.log - /var/log/syslog labels: type: syslog --- filenames: - /var/log/crowdsec/traefik/*.log labels: type: traefik ---
4.3.2. Traefik.yml anpassen
Jetzt müssen wir innerhalb Traefik die Ausgabe der Log-Dateien definieren um diese CrowdSec zur Verfügugn zu stellen. Dafür passen wir von Traefik die traefik.yml
an. Folgenden Teil kopieren wir uns an das Ende der Datei:
nano /opt/containers/traefik/data/traefik.yml
# [...] Ende der Datei log: level: "INFO" filePath: "/var/log/traefik/traefik.log" accessLog: filePath: "/var/log/traefik/access.log" bufferingSize: 100
4.3.3. Traefik docker-compose.yml anpassen
In diesem Schritt ergänzen wir die docker-compose.yml von Traefik um einen Mount für die Logs:
nano /opt/containers/traefik/docker-compose.yml
services: traefik: volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/traefik.yml:/traefik.yml:ro - ./data/acme_letsencrypt.json:/acme_letsencrypt.json - ./data/dynamic_conf.yml:/dynamic_conf.yml - /var/log/crowdsec/traefik/:/var/log/traefik/ # Diese Zeile muss hinzugefügt werden
4.3.4. Traefik neustarten
Um die geänderte Konfiguration zu laden starten wir Traefik erneut:
docker compose -f /opt/containers/traefik/docker-compose.yml up -d --force-recreate
4.3.5. CrowdSec Konfiguration neu laden
Jetzt muss noch die Konfiguration von CrowdSec neu geladen werden, dass er auch auf die von uns definierten Logs zugreifen kann. Dafür muss man den Container nicht neutstarten sondern kann einfach die Konfig neu laden:
docker compose exec -t crowdsec kill -SIGHUP 1
4.4. Traefik Bouncer
CrowdSec ist nun in der Lage die Log-Dateien zu lesen und verdächtige IP-Adressen auf die Ban-Liste zu setzten. Nice! Allerdings in dem aktuellen Zustand wird noch nichts unternommen um den potenziellen Angriff abzuwehren. In CrowdSec sind sogenante Bouncer dafür zuständig. Von diesen Bouncern gibt es sehr viele! Es gibt einen Firewall Bouncer für iptables/nftables, einen Cloudflare Bouncer um die Firewall von Cloudflare zu steueren und es gibt auch einen Traefik Bouncer, was für uns hier interessant ist.
4.4.1. CrowdSec: docker-compose.yml ergänzen
Wir ergänzen CrowdSec um den Traefik Bouncer:
nano /opt/containers/crowdsec/docker-compose.yml
bouncer-traefik: container_name: crowdsec-bouncer-traefik image: fbonalair/traefik-crowdsec-bouncer:latest environment: CROWDSEC_BOUNCER_API_KEY: ${TRAEFIK_BOUNCER_KEY} CROWDSEC_AGENT_HOST: crowdsec:8080 restart: unless-stopped depends_on: - crowdsec networks: - proxy hostname: crowdsec-bouncer-traefik
4.4.2. API-Schlüssel generieren
Nun müssen wir noch einen API-Schlüssel erzeugen in dem wir den Bouncer bei CrowdSec registieren:
docker compose exec -t crowdsec cscli bouncers add bouncer-traefik
Es wird uns der API-Key ausgegeben. Diesen müssen wir uns unbedingt notieren, da er nur dieses einemal angezeigt wird. Wir kopieren ihn dann in unsere .env-Datei:
nano /opt/containers/crowdsec/.env
TRAEFIK_BOUNCER_KEY=ef422bf99a6883bc9042x0xxx00x0xxx
4.4.3. Traefik erweitern
Nun können wir für jeden Container verdächtige IPs blocken aber wir werden diese Option global Konfigurieren. Damit kann keine unerwünschte IP Adresse auf unsere Services zugreifen.
Um dies zu aktivieren erweitern wir unsere dynamic_conf.yml von Traefik um eine weitere middleware:
nano /opt/containers/traefik/data/dynamic_conf.yml
tls: options: default: minVersion: VersionTLS12 cipherSuites: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 curvePreferences: - CurveP521 - CurveP384 sniStrict: true http: middlewares: traefikAuth: basicAuth: users: - "benutzer:passworthash" default: chain: middlewares: - default-security-headers - gzip secHeaders: chain: middlewares: - default-security-headers - gzip default-security-headers: headers: browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true frameDeny: true # Deprecated # sslRedirect: true stsIncludeSubdomains: true stsPreload: true stsSeconds: 31536000 customFrameOptionsValue: "SAMEORIGIN" gzip: compress: {} crowdsec-bouncer: forwardauth: address: http://crowdsec-bouncer-traefik:8080/api/v1/forwardAuth trustForwardHeader: true
Jetzt noch die statische Konfiguration von Traefik anpassen. Wir fügen zu unseren Einstiegspunkten (entryPoints) die gerade definierte Middleware standardgemäß hinzu:
nano /opt/containers/traefik/data/traefik.yml
api: dashboard: true certificatesResolvers: http: acme: email: "meine@email.de" storage: "acme_letsencrypt.json" httpChallenge: entryPoint: http entryPoints: http: address: ":80" http: redirections: entryPoint: to: "https" scheme: "https" # An dieser Stelle auskommentiert. Bevor die Anfrage an crowdsec geht wird sie erst an https weitergeleitet # middlewares: # - crowdsec-bouncer@file https: address: ":443" http: middlewares: - crowdsec-bouncer@file global: checknewversion: true sendanonymoususage: false providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: "proxy" file: filename: "./dynamic_conf.yml" watch: true providersThrottleDuration: 10 log: level: "INFO" filePath: "/var/log/traefik/traefik.log" accessLog: filePath: "/var/log/traefik/access.log" bufferingSize: 100
5. Dienste neustarten
Nun starten wir nach der Reihe die Dienste einmal neu. Dannach wird jede eingehende Anfrage von Traefik an den Bouncer weitergeleitet, um zu prüfen, ob die IP auf der Banliste steht. Alle IP Adressen auf der Banliste bekommen dann 403 Forbidden:
docker compose -f /opt/containers/crowdsec/docker-compose.yml up -d --force-recreate docker compose -f /opt/containers/traefik/docker-compose.yml up -d --force-recreate
5.1. Erfolgskontrolle
Nun können wir kontrollieren ob CrowdSec Log-Dateien von Traefik gefunden hat und diese auch analysiert:
docker exec crowdsec cscli metrics

6. Ältere Anleitungen anpassen
Viele Anleitungen auf GoNeuland sind entstanden bevor es diese hier gab. Das bedeutet wir müssen zumindest kleine Anpassungen an den Traefik Labels des jeweiligen Container machen. So sehen Beispielhaft die typischen Labels einer Anleitung aus:
labels: - "traefik.enable=true" - "traefik.http.routers.invidious.entrypoints=http" - "traefik.http.routers.invidious.rule=Host(`video.euredomain.de`)" - "traefik.http.middlewares.invidious-https-redirect.redirectscheme.scheme=https" - "traefik.http.routers.invidious.middlewares=invidious-https-redirect" - "traefik.http.routers.invidious-secure.entrypoints=https" - "traefik.http.routers.invidious-secure.rule=Host(`video.euredomain.de`)" - "traefik.http.routers.invidious-secure.tls=true" - "traefik.http.routers.invidious-secure.tls.certresolver=http" - "traefik.http.routers.invidious-secure.service=invidious" - "traefik.http.services.invidious.loadbalancer.server.port=3000" - "traefik.docker.network=proxy" - "traefik.http.routers.invidious-secure.middlewares=secHeaders@file"
Ich möchte diese jetzt Stück für Stück an die neue Anleitung anpassen euch dabei mitnehmen. Ich zeige euch die Stellen an denen wir was verändern.
Folgender Teil kann entfernt werden, da wir das schon in der traefik.yml definiert haben:
- "traefik.http.middlewares.invidious-https-redirect.redirectscheme.scheme=https" - "traefik.http.routers.invidious.middlewares=invidious-https-redirect"
7. Quellen
- https://goneuland.de/traefik-v2-reverse-proxy-fuer-docker-unter-debian-10-einrichten/
- https://docs.ibracorp.io/crowdsec/
- https://www.benjaminrancourt.ca/a-complete-traefik-configuration/
- https://docs.ibracorp.io/crowdsec/crowdsec/docker-compose/traefik-bouncer
- https://blog.vacum.se/securing-mailcow-with-crowdsec/
- https://spad.uk/integrating-crowdsec-with-traefik-discord/
- https://docs.technotim.live/posts/crowdsec-traefik/
[…] Traefik v2 – Reverse-Proxy mit CrowdSec einrichten […]