
Traefik V3: Installation, Konfiguration und CrowdSec-Security
7. Stack konfigurieren
7.1. docker-compose.yml
-Datei
In diesem Schritt beginnen wir mit der Konfiguration unserer docker-compose.yml
-Datei. Dafür verwenden wir den Texteditor nano
. Um die Verwaltung unseres Stacks übersichtlicher zu gestalten, wird die Konfiguration in mehrere Abschnitte aufgeteilt. Jeder Abschnitt deckt einen bestimmten Teil der Stack-Konfiguration ab.
Table Of Content
- Versionierung
- WICHTIG!
- 0. Testing
- 1. Zielsetzung
- 2. Voraussetzung
- 2.1. Hinweis
- 3. Grundlage: Netzwerke in Docker
- 3.1. Private Adressbereiche in IPv4
- 3.2. Adressbereiche in Docker
- 3.3. Verständnis der Netzwerkproblematik
- 3.4. Lösung
- 4. Netzwerke konfigurieren
- 4.1. Vorbereitung
- 4.2. Docker Konfigurieren anpassen
- 4.3. Ergebnis
- 4.3.1. IPv6-Konfiguration
- 5. Überblick über die Systeme
- 5.1. Traefik
- 5.2. Docker-Socket-Proxy
- 5.3. CrowdSec
- 5.4. CrowdSec Bouncer
- 6. Stack vorbereiten
- 6.1. Hauptverzeichnis erstellen und in das Verzeichnis wechseln
- 6.2. Dateien erstellen und Berechtigungen setzen
- 6.3. Überprüfung
- 7. Stack konfigurieren
- 7.1. docker-compose.yml-Datei
- 7.2. compose-Dateien
- 7.3. DOTENV anpassen
- 7.3.1. Allgemeine .env-Datei
- 7.3.2. .env-Datei für CrowdSec
- 7.3.3. .env-Datei für den Socket-Proxy
- 7.3.4. .env-Datei für den CrowdSec Bouncer für Traefik
- 7.3.5. .env-Datei für Traefik
- 7.3.6. API Key für den CrowdSec Bouncer für Traefik generieren
- 7.4. Traefik konfigurieren
- 7.4.1. Konfiguration der traefik.yml
- 7.4.2. Konfiguration von TLS
- 7.4.3. Konfiguration von http.middlewares.default.yml
- 7.4.4. Konfiguration von http.middlewares.traefik-dashboard-auth.yml
- 7.4.5. Passwort für Traefik-Dashboard festlegen
- 7.4.6. Konfiguration von http.middlewares.traefik-bouncer.yml
- 7.4.7. Integration des Bouncers in traefik.yml
- 7.5. CrowdSec konfigurieren
- 7.5.1. Acquisition anpassen
- 8. Dienst starten
- 8.1. Checkliste
- 9. Traefik-CrowdSec-Stack überprüfung
- 10. Optional
- 10.1. CrowdSec aktuell halten
- 10.2. Traefik-CrowdSec-Stack Update
- 10.3. Erweiterung der Firewall (UFW bzw. IPTables und NFTables) mit CrowdSec
- 10.3.1. Repository für CrowdSec Firewall Bouncer
- 10.3.2. Installation des Firewall Bouncers
- 10.3.3. Access Token generieren
- 10.3.4. Bouncer konfigurieren
- 10.3.5. CrowdSec Firewall Bouncer starten
- 10.3.6. Anzeigen der CrowdSec Bouncer-Liste
- 10.4. Logrotate für Traefik
- 10.5. Mailcow anpassen
- 11. Neuen Container hinzufügen
- 11.1. TLS anstelle von HTTP
- 99. Anleitung in 2 Minuten
- Hinweis zu Kommentaren
- Author: Psycho0verload
nano docker-compose.yml
Mit dem obigen Befehl öffnen wir den Editor nano
die Datei docker-compose.yml
.
Der Inhalt der Datei wird wie folgt strukturiert, indem wir verschiedene Konfigurationsdateien aus dem compose
-Verzeichnis einbinden:
include: - compose/crowdsec.yml - compose/socket-proxy.yml - compose/traefik-crowdsec-bouncer.yml - compose/traefik.yml - compose/networks.yml
Jeder dieser Abschnitte bezieht sich auf eine spezifische Dienstkonfiguration innerhalb unseres Stacks und ermöglicht eine saubere und modulare Aufteilung.
7.2. compose
-Dateien
In diesem Schritt befassen wir uns mit den einzelnen modularen Konfigurationsdateien im Verzeichnis compose/
. Jede dieser Dateien enthält eine spezifische Konfiguration für die jeweiligen Dienste, die wir in unserem Stack verwenden. Durch die Aufteilung in mehrere Dateien wird die Verwaltung und Anpassung der einzelnen Dienste vereinfacht und die Übersichtlichkeit erhöht.
Die folgenden Dateien werden konfiguriert:
nano /opt/containers/traefik-crowdsec-stack/compose/crowdsec.yml nano /opt/containers/traefik-crowdsec-stack/compose/socket-proxy.yml nano /opt/containers/traefik-crowdsec-stack/compose/traefik-crowdsec-bouncer.yml nano /opt/containers/traefik-crowdsec-stack/compose/traefik.yml nano /opt/containers/traefik-crowdsec-stack/compose/networks.yml
services: crowdsec: container_name: ${SERVICES_CROWDSEC_CONTAINER_NAME:-crowdsec} env_file: ${ABSOLUTE_PATH}/data/crowdsec/.env hostname: ${SERVICES_CROWDSEC_HOSTNAME:-crowdsec} healthcheck: test: ["CMD", "cscli", "version"] timeout: 2s interval: 20s retries: 5 start_period: 10s image: ${SERVICES_CROWDSEC_IMAGE:-crowdsecurity/crowdsec}:${SERVICES_CROWDSEC_IMAGE_VERSION:-latest} networks: crowdsec: ipv4_address: ${SERVICES_CROWDSEC_NETWORKS_CROWDSEC_IPV4:-172.31.127.254} ipv6_address: ${SERVICES_CROWDSEC_NETWORKS_CROWDSEC_IPV6:-fd00:1:be:a:7001:0:3e:6fff} socket_proxy: ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_SOCKET_PROXY_IPV4:-172.31.255.252} ipv6_address: ${SERVICES_TRAEFIK_NETWORKS_SOCKET_PROXY_IPV6:-fd00:1:be:a:7001:0:3e:8ffd} restart: unless-stopped security_opt: - no-new-privileges=true volumes: - ${ABSOLUTE_PATH}/data/crowdsec/config:/etc/crowdsec - ${ABSOLUTE_PATH}/data/crowdsec/data:/var/lib/crowdsec/data - /var/log/auth.log:/var/log/auth.log:ro - /var/log/traefik:/var/log/traefik:ro
services: socket-proxy: container_name: ${SERVICES_SOCKET_PROXY_CONTAINER_NAME:-socket-proxy} env_file: ${ABSOLUTE_PATH}/data/socket-proxy/.env hostname: ${SERVICES_SOCKET_PROXY_HOSTNAME:-socket-proxy} healthcheck: test: ["CMD-SHELL", "curl -s -o /dev/null -w '%{http_code}' http://localhost:2375 | grep -q '403' || exit 1"] timeout: 1s interval: 10s retries: 3 start_period: 10s image: ${SERVICES_SOCKET_PROXY_IMAGE:-lscr.io/linuxserver/socket-proxy}:${SERVICES_SOCKET_PROXY_IMAGE_VERSION:-latest} networks: socket_proxy: ipv4_address: ${SERVICES_SOCKET_PROXY_NETWORKS_SOCKET_PROXY_IPV4:-172.31.255.254} ipv6_address: ${SERVICES_SOCKET_PROXY_NETWORKS_SOCKET_PROXY_IPV6:-fd00:1:be:a:7001:0:3e:8fff} read_only: true restart: unless-stopped tmpfs: - /run volumes: - /var/run/docker.sock:/var/run/docker.sock:ro
services: traefik_crowdsec_bouncer: container_name: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_CONTAINER_NAME:-traefik_crowdsec_bouncer} depends_on: crowdsec: condition: service_healthy env_file: ${ABSOLUTE_PATH}/data/traefik-crowdsec-bouncer/.env hostname: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_HOSTNAME:-traefik-crowdsec-bouncer} image: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_IMAGE:-fbonalair/traefik-crowdsec-bouncer}:${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_IMAGE_VERSION:-latest} networks: crowdsec: ipv4_address: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_NETWORKS_CROWDSEC_IPV4:-172.31.127.252} ipv6_address: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_NETWORKS_CROWDSEC_IPV6:-fd00:1:be:a:7001:0:3e:6ffd} restart: unless-stopped
services: traefik: container_name: ${SERVICES_TRAEFIK_CONTAINER_NAME:-traefik} depends_on: crowdsec: condition: service_healthy socket-proxy: condition: service_healthy env_file: ${ABSOLUTE_PATH}/data/traefik/.env hostname: ${SERVICES_TRAEFIK_HOSTNAME:-traefik} healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] timeout: 1s interval: 10s retries: 3 start_period: 10s image: ${SERVICES_TRAEFIK_IMAGE:-traefik}:${SERVICES_TRAEFIK_IMAGE_VERSION:-3.1} labels: traefik.enable: "true" traefik.http.routers.traefik-dashboad.entrypoints: websecure traefik.http.routers.traefik-dashboad.middlewares: default@file, traefik-dashboard-auth@file traefik.http.routers.traefik-dashboad.rule: ${SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST:-HOST(`traefik.yourdomain.com`)} traefik.http.routers.traefik-dashboad.service: api@internal traefik.http.routers.traefik-dashboad.tls: "true" traefik.http.routers.traefik-dashboad.tls.certresolver: tls_resolver traefik.http.services.traefik-dashboad.loadbalancer.sticky.cookie.httpOnly: "true" traefik.http.services.traefik-dashboad.loadbalancer.sticky.cookie.secure: "true" traefik.http.routers.pingweb.rule: PathPrefix(`/ping`) traefik.http.routers.pingweb.service: ping@internal traefik.http.routers.pingweb.entrypoints: websecure networks: crowdsec: ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_CROWDSEC_IPV4:-172.31.127.253} ipv6_address: ${SERVICES_TRAEFIK_NETWORKS_CROWDSEC_IPV6:-fd00:1:be:a:7001:0:3e:6ffe} proxy: ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_PROXY_IPV4:-172.31.191.254} ipv6_address: ${SERVICES_TRAEFIK_NETWORKS_PROXY_IPV6:-fd00:1:be:a:7001:0:3e:7fff} socket_proxy: ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_SOCKET_PROXY_IPV4:-172.31.255.253} ipv6_address: ${SERVICES_TRAEFIK_NETWORKS_SOCKET_PROXY_IPV6:-fd00:1:be:a:7001:0:3e:8ffe} ports: - mode: host target: 80 published: "80" protocol: tcp - mode: host target: 443 published: "443" protocol: tcp restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /etc/localtime:/etc/localtime:ro - ${ABSOLUTE_PATH}/data/traefik/traefik.yml:/etc/traefik/traefik.yml - ${ABSOLUTE_PATH}/data/traefik/.htpasswd:/etc/traefik/.htpasswd - ${ABSOLUTE_PATH}/data/traefik/certs/acme_letsencrypt.json:/etc/traefik//acme_letsencrypt.json - ${ABSOLUTE_PATH}/data/traefik/certs/tls_letsencrypt.json:/etc/traefik/tls_letsencrypt.json - ${ABSOLUTE_PATH}/data/traefik/dynamic_conf:/etc/traefik/dynamic_conf:ro - /var/log/traefik/:/var/log/traefik/
networks: crowdsec: name: ${NETWORKS_CROWDSEC_NAME:-crowdsec} driver: bridge enable_ipv6: true ipam: driver: default config: - subnet: ${NETWORKS_CROWDSEC_SUBNET_IPV4:-172.31.64.0/18} - subnet: ${NETWORKS_CROWDSEC_SUBNET_IPV6:-fd00:1:be:a:7001:0:3e:6000/116} attachable: true proxy: name: ${NETWORKS_PROXY_NAME:-proxy} driver: bridge enable_ipv6: true ipam: driver: default config: - subnet: ${NETWORKS_PROXY_SUBNET_IPV4:-172.31.128.0/18} - subnet: ${NETWORKS_PROXY_SUBNET_IPV6:-fd00:1:be:a:7001:0:3e:7000/116} attachable: true socket_proxy: name: ${NETWORKS_SOCKET_PROXY_NAME:-socket_proxy} driver: bridge enable_ipv6: true ipam: driver: default config: - subnet: ${NETWORKS_SOCKET_PROXY_SUBNET_IPV4:-172.31.192.0/18} - subnet: ${NETWORKS_SOCKET_PROXY_SUBNET_IPV6:-fd00:1:be:a:7001:0:3e:8000/116} attachable: true internal: true
7.3. DOTENV anpassen
In diesem Schritt passen wir die .env
-Datei für unsere spezifischen Anforderungen an. Im Rahmen dieses Projekts haben wir mehrere .env
-Dateien erstellt, um die Konfigurationen flexibel und servicebezogen anpassen zu können. Dies ermöglicht uns, die Einstellungen für jeden Dienst gezielt zu verwalten und bei Bedarf zu modifizieren.
7.3.1. Allgemeine .env
-Datei
Zunächst bearbeiten wir die allgemeine .env
-Datei, die sich im Hauptverzeichnis unseres Projekts befindet:
nano /opt/containers/traefik-crowdsec-stack/.env
ABSOLUTE_PATH=${PWD} TZ=Europe/Berlin SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST=HOST(`unserewunschdomain.de`)
Erklärung der Konfiguration:
- ABSOLUTE_PATH=${PWD}: Dieser Wert wird automatisch auf das aktuelle Arbeitsverzeichnis gesetzt, um dynamische Pfade innerhalb des Projekts zu ermöglichen.
- TZ=Europe/Berlin: Die Zeitzone wird auf Mitteleuropäische Zeit (CET/CEST) festgelegt. Dies stellt sicher, dass alle zeitbasierten Aktionen korrekt in der deutschen Zeitzone durchgeführt werden.
- SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST=
HOST(unserewunschdomain.de)
: Hier legen wir den Hostnamen fest, den Traefik verwendet. Ob wir uns für eine Second-Level-Domain oder eine Third-Level-Domain entscheidest, bleibt dabei uns überlassen. Wichtig ist dabei, die richtige Notation mit den Backticks (`
) einzuhalten, um sicherzustellen, dass die Domain korrekt interpretiert wird. Dies sollte die gewünschte Domain des Projekts sein, um Anfragen richtig weiterzuleiten.
Hinweis:
Wir beschränken uns bewusst darauf, nur die nötigsten Variablen in der allgemeinen .env
-Datei zu definieren. Zusätzliche Variablen, die in spezifischen compose
-Dateien verwendet werden, nehmen wir hier nicht auf, um die Konfiguration schlank und übersichtlich zu halten. Diese zusätzlichen Variablen werden nur bei Bedarf in den jeweiligen Dienst-Konfigurationsdateien gesetzt.
7.3.2. .env
-Datei für CrowdSec
Im nächsten Schritt passen wir die .env
-Datei von CrowdSec an, um unsere spezifischen Anforderungen und Konfigurationen für den CrowdSec-Container festzulegen. Diese Datei steuert wichtige Einstellungen für den Betrieb von CrowdSec.
Wir öffnen die Datei mit dem folgenden Befehl:
nano /opt/containers/traefik-crowdsec-stack/data/crowdsec/.env
TZ=$TZ # Zugriff auf Docker-Socket-Proxy DOCKER_HOST=tcp://socket-proxy:2375 # Bouncers BOUNCER_KEY_TRAEFIK=$BOUNCER_KEY_TRAEFIK BOUNCER_KEY_FIREWALL=$BOUNCER_KEY_FIREWALL # Hub NO_HUB_UPGRADE="false" # Überspringen des Updates via Hub / Upgrade beim Start des Containers COLLECTIONS="crowdsecurity/linux crowdsecurity/traefik" # Sammlungen (Collections), die installiert werden sollen, getrennt durch Leerzeichen: COLLECTIONS="crowdsecurity/linux crowdsecurity/traefik" # PARSERS="" # Parser, die installiert werden sollen, getrennt durch Leerzeichen. # SCENARIOS="" # Szenarien, die installiert werden sollen, getrennt durch Leerzeichen. # POSTOVERFLOWS="" # Postoverflows, die installiert werden sollen, getrennt durch Leerzeichen. # CONTEXTS="" # Kontextdateien, die installiert werden sollen, getrennt durch Leerzeichen. # APPSEC_CONFIGS="" # AppSec-Konfigurationsdateien, die installiert werden sollen, getrennt durch Leerzeichen. # APPSEC_RULES="" # AppSec-Regeln, die installiert werden sollen, getrennt durch Leerzeichen. # DISABLE_COLLECTIONS="" # Sammlungen, die entfernt werden sollen, getrennt durch Leerzeichen: DISABLE_COLLECTIONS="crowdsecurity/linux crowdsecurity/nginx" # DISABLE_PARSERS="" # Parser, die entfernt werden sollen, getrennt durch Leerzeichen. # DISABLE_SCENARIOS="" # Szenarien, die entfernt werden sollen, getrennt durch Leerzeichen. # DISABLE_POSTOVERFLOWS="" # Postoverflows, die entfernt werden sollen, getrennt durch Leerzeichen. # DISABLE_CONTEXTS="" # Kontextdateien, die entfernt werden sollen, getrennt durch Leerzeichen. # DISABLE_APPSEC_CONFIGS="" # AppSec-Konfigurationsdateien, die entfernt werden sollen, getrennt durch Leerzeichen. # DISABLE_APPSEC_RULES="" # AppSec-Regeln, die entfernt werden sollen, getrennt durch Leerzeichen. # Log-Verbosity # LEVEL_FATAL=false # Erzwingen des FATAL-Protokollierungslevels für die Container-Protokolle. # LEVEL_ERROR=false # Erzwingen des ERROR-Protokollierungslevels für die Container-Protokolle. # LEVEL_WARN=false # Erzwingen des WARN-Protokollierungslevels für die Container-Protokolle. # LEVEL_INFO=false # Erzwingen des INFO-Protokollierungslevels für die Container-Protokolle. # LEVEL_DEBUG=false # Erzwingen des DEBUG-Protokollierungslevels für die Container-Protokolle. # LEVEL_TRACE=false # Erzwingen des TRACE-Protokollierungslevels (sehr ausführlich) für die Container-Protokolle.
- TZ: Hier wird die Zeitzone festgelegt, die auf die allgemeine Zeitzoneneinstellung des Systems ($TZ) verweist.
- NO_HUB_UPGRADE: Legt fest, ob automatische Updates über den CrowdSec Hub beim Start des Containers durchgeführt werden sollen.
- COLLECTIONS: Hier definieren wir, welche Sammlungen (z. B. für traefik oder linux) automatisch installiert werden sollen.
- Log-Verbosity: Ermöglicht das Einstellen der Protokollierungsstufen für den Container, um detaillierte Informationen über den Zustand und mögliche Fehler des Containers zu erhalten.
Optionale Einstellungen wie Parser, Szenarien oder AppSec-Regeln können nach Bedarf angepasst oder hinzugefügt werden, um spezifische Sicherheitsanforderungen abzudecken.
7.3.3. .env
-Datei für den Socket-Proxy
Nun passen wir die .env
-Datei für den Socket-Proxy an. Diese Datei befindet sich im Verzeichnis data/socket-proxy/.env
. Da das Docker-Image des Socket-Proxy kein tzdata
-Paket enthält, ist es hier nicht nötig, die Zeitzone (TZ
) anzugeben. Stattdessen konzentrieren wir uns auf die spezifischen Konfigurationsoptionen für den Socket-Proxy.
Öffne die Datei zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/socket-proxy/.env
INFO=1 CONTAINERS=1 POST=0 BUILD=0 COMMIT=0 CONFIGS=0 DISTRIBUTION=0 EXEC=0 GRPC=0 IMAGES=0 NETWORKS=0 NODES=0 PLUGINS=0 SERVICES=0 SESSION=0 SWARM=0 SYSTEM=0 TASKS=0 VOLUMES=0
Erklärung der Konfiguration:
- INFO=1: Aktiviert grundlegende Informationen für den Socket-Proxy.
- CONTAINERS=1: Aktiviert die Unterstützung für Container.
- POST=0, BUILD=0, COMMIT=0, usw.: Diese Optionen deaktivieren bestimmte Funktionen, die für diesen Proxy-Dienst nicht benötigt werden.
Durch das Setzen dieser Umgebungsvariablen können wir die Funktionen und das Verhalten des Socket-Proxy-Dienstes gezielt steuern.
7.3.4. .env
-Datei für den CrowdSec Bouncer für Traefik
Im nächsten Schritt bearbeiten wir die .env
-Datei für den CrowdSec Bouncer, der speziell für die Integration mit Traefik konfiguriert wird. Diese Datei befindet sich im Verzeichnis data/traefik-crowdsec-bouncer/.env
. Hier definieren wir die Zeitzone sowie die API-Konfiguration, um den Bouncer mit dem CrowdSec-Agent zu verbinden.
Öffne die Datei zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/traefik-crowdsec-bouncer/.env
TZ=$TZ GIN_MODE="debug" # Wenn das System sauber läuft kann hier "release" gesetzt werden CROWDSEC_BOUNCER_API_KEY=$BOUNCER_KEY_TRAEFIK CROWDSEC_AGENT_HOST=${SERVICES_CROWDSEC_HOSTNAME:-crowdsec}:8080
Erklärung der Konfiguration:
- TZ=$TZ: Verwendet die globale Zeitzoneneinstellung (
$TZ
), die in der allgemeinen.env
-Datei festgelegt wurde. - CROWDSEC_BOUNCER_API_KEY=$BOUNCER_KEY_TRAEFIK: Hier wird der generierte API-Schlüssel für den Traefik-Bouncer verwendet, den wir später in der
.env
-Datei speichern werden. Dies ermöglicht die Authentifizierung des Bouncers bei CrowdSec. - CROWDSEC_AGENT_HOST=${SERVICES_CROWDSEC_HOSTNAME:-crowdsec}:8080: Definiert den Hostnamen des CrowdSec-Agenten. Standardmäßig wird der Dienst auf
crowdsec:8080
erwartet, es sei denn, der Wert wird durch eine andere Umgebungsvariable (SERVICES_CROWDSEC_HOSTNAME
) überschrieben.
Diese Einstellungen sorgen dafür, dass der CrowdSec Bouncer korrekt mit dem Traefik-Dienst und dem CrowdSec-Agenten kommunizieren kann, um verdächtige Anfragen zu blockieren und den Schutz zu gewährleisten.
7.3.5. .env
-Datei für Traefik
Nun passen wir die .env
-Datei für den Traefik-Dienst an. Diese Datei befindet sich im Verzeichnis data/traefik/.env
. Hier wird die Zeitzoneneinstellung (TZ
) festgelegt, die für die allgemeine Konfiguration von Traefik benötigt wird.
Öffne die Datei zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/.env
TZ=$TZ
Erklärung der Konfiguration:
- TZ=$TZ: Hier wird die globale Zeitzoneneinstellung (
$TZ
) verwendet, die in der allgemeinen.env
-Datei des Projekts definiert wurde. Diese Einstellung stellt sicher, dass Traefik die gleiche Zeitzone wie die anderen Dienste verwendet.
Mit dieser Konfiguration bleibt der Traefik-Dienst konsistent in Bezug auf Zeitzoneneinstellungen, was wichtig ist, um Logs und zeitbasierte Aktionen richtig zu synchronisieren.
7.3.6. API Key für den CrowdSec Bouncer für Traefik generieren
Um den API-Schlüssel für den CrowdSec Bouncer zu generieren, verwenden wir einen sicheren Schlüssel, der mit openssl
erstellt wird. Dieser Schlüssel wird sowohl in der .env
-Datei gespeichert als auch im Terminal angezeigt, damit er bei Bedarf kopiert werden kann.
Führe die folgenden Befehle aus, um den API-Schlüssel zu generieren:
BOUNCER_PASSWORD=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9!@#$%^&*()-_=+[]{}<>?|') echo "BOUNCER_KEY_TRAEFIK=\"$BOUNCER_PASSWORD\"" >> /opt/containers/traefik-crowdsec-stack/.env echo "Generated BOUNCER_KEY_TRAEFIK: $BOUNCER_PASSWORD"
Erklärung der Schritte:
- BOUNCER_PASSWORD=$(openssl rand -base64 48 | tr -dc ‚a-zA-Z0-9!@#$%^&*()-_=+[]{}<>?|‘):
- Mit diesem Befehl wird ein komplexes, sicheres Passwort generiert, das 48 Zeichen lang ist und eine Kombination aus Groß- und Kleinbuchstaben, Zahlen und Sonderzeichen enthält.
- echo „BOUNCER_KEY_TRAEFIK=\“$BOUNCER_PASSWORD\““ >> /opt/containers/traefik-crowdsec-stack/.env:
- Das generierte Passwort wird als
BOUNCER_KEY_TRAEFIK
in die.env
-Datei geschrieben, um es für den Traefik Bouncer zu speichern.
- Das generierte Passwort wird als
- echo „Generated BOUNCER_KEY_TRAEFIK: $BOUNCER_PASSWORD“:
- Der generierte API-Schlüssel wird im Terminal ausgegeben, sodass er vom Benutzer kopiert und an anderer Stelle verwendet werden kann.
7.4. Traefik konfigurieren
7.4.1. Konfiguration der traefik.yml
In diesem Abschnitt widmen wir uns der statischen Konfiguration von Traefik in der Datei traefik.yml
. Diese Datei definiert die grundlegenden Einstellungen für den Traefik-Dienst, wie API-Zugriff, Protokolle, ACME-Zertifikate und Netzwerkeinstellungen.
Öffne die Konfigurationsdatei mit folgendem Befehl:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/traefik.yml
api: dashboard: true metrics: prometheus: addRoutersLabels: true certificatesResolvers: http_resolver: acme: email: "deine@email.de" storage: "/etc/traefik/acme_letsencrypt.json" httpChallenge: entryPoint: web tls_resolver: acme: email: "deine@email.de" storage: "/etc/traefik/tls_letsencrypt.json" tlsChallenge: {} entryPoints: ping: address: ':88' web: address: ':80' http: redirections: entryPoint: to: websecure scheme: https websecure: address: ':443' http: middlewares: - default@file ping: entryPoint: "ping" global: checknewversion: true sendanonymoususage: false providers: docker: endpoint: "tcp://socket-proxy:2375" exposedByDefault: false network: "proxy" file: directory: "/etc/traefik/dynamic_conf" watch: true providersThrottleDuration: 10s log: level: INFO filePath: "/var/log/traefik/traefik.log" format: json maxSize: 10 maxBackups: 10 maxAge: 14 accessLog: filePath: "/var/log/traefik/access.log" format: json bufferingSize: 50 fields: defaultMode: keep
Erklärung der Konfiguration:
- API und Dashboard:
api.dashboard: true
: Aktiviert das Traefik-Dashboard, welches über die API bereitgestellt wird.
- Metrics:
metrics.prometheus.addRoutersLabels: true
: Aktiviert Prometheus-Metriken und fügt Router-Labels hinzu.
- Zertifikatsresolver (Let’s Encrypt):
certificatesResolvers
: Hier konfigurieren wir zwei Resolver:- http_resolver für HTTP-Challenges.
- tls_resolver für TLS-Challenges.
- E-Mail-Adresse: Passe die E-Mail-Adresse unter beiden Resolvers an, da diese von Let’s Encrypt verwendet wird. Wichtig: Beide Resolver müssen die gleiche E-Mail-Adresse verwenden, um Fehler zu vermeiden.
- Entry Points:
- web: Der HTTP-Eingangspunkt auf Port 80 leitet alle Anfragen per HTTPS weiter (über
websecure
). - websecure: HTTPS-Eingangspunkt auf Port 443
- ping: Ein spezieller Ping-Endpoint auf Port 88 zur Gesundheitsüberwachung.
- web: Der HTTP-Eingangspunkt auf Port 80 leitet alle Anfragen per HTTPS weiter (über
- Global:
checknewversion: true
: Aktiviert die Überprüfung auf neue Versionen von Traefik.sendanonymoususage: false
: Deaktiviert das Senden von anonymen Nutzungsdaten.
- Providers:
- Docker: Konfiguriert den Docker-Provider für die automatische Erkennung von Diensten über einen Socket-Proxy.
- File: Aktiviert die Dateikonfiguration über ein Verzeichnis für dynamische Konfigurationen.
- Log- und Access-Log-Einstellungen:
- Log: Legt das Log-Level auf
INFO
fest und gibt den Speicherort der Logs an. - AccessLog: Aktiviert das Access-Log und speichert es in der angegebenen Datei. Bestimmte Felder wie
StartUTC
werden ausgeblendet.
- Log: Legt das Log-Level auf
Wichtiger Hinweis:
Die E-Mail-Adresse unter certificatesResolvers
muss für beide Resolver identisch sein. Sollten zwei verschiedene E-Mail-Adressen verwendet werden, führt dies zu einem Fehler:
traefik.go:81: command traefik error: unable to initialize certificates resolver "tls_resolver", all the acme resolvers must use the same email
Daher ist es wichtig, dass du die E-Mail-Adresse korrekt anpasst und beide Resolver auf die gleiche Adresse setzen, um Let’s Encrypt zu nutzen.
7.4.2. Konfiguration von TLS
In diesem Schritt konfigurieren wir die TLS-Einstellungen in der Datei tls.yml
, um die Sicherheitsstandards für die HTTPS-Kommunikation in Traefik festzulegen. Diese Datei befindet sich im Verzeichnis data/traefik/dynamic_conf/
.
Öffne die Datei zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/dynamic_conf/tls.yml
tls: options: default: minVersion: VersionTLS12 cipherSuites: - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA curvePreferences: - CurveP521 - CurveP384 sniStrict: true
Erklärung der Konfiguration:
- minVersion: VersionTLS12: Diese Option legt fest, dass Traefik nur TLS-Verbindungen ab Version 1.2 zulässt. Dies sorgt für eine erhöhte Sicherheit, da ältere TLS-Versionen wie 1.0 und 1.1 als unsicher gelten.
- cipherSuites: Hier werden die bevorzugten Cipher-Suiten festgelegt. Dies sind Algorithmen, die für die Verschlüsselung von Verbindungen verwendet werden. Die aufgelisteten Suiten bieten eine hohe Sicherheit und sind weit verbreitet.
- curvePreferences: Die bevorzugten elliptischen Kurven werden hier definiert. Diese werden in der TLS-Verschlüsselung verwendet und bieten eine starke kryptografische Sicherheit. Die Kurven
CurveP521
undCurveP384
werden bevorzugt. - sniStrict: true: Diese Option aktiviert den SNI (Server Name Indication)-Modus und erzwingt, dass der Hostname bei TLS-Verbindungen übereinstimmen muss. Dies erhöht die Sicherheit, da die Verbindung nur zustande kommt, wenn der angeforderte Hostname korrekt ist.
Diese Konfiguration sorgt dafür, dass die HTTPS-Verbindungen in deinem Traefik-Setup mit hohen Sicherheitsstandards verschlüsselt und abgesichert werden.
7.4.3. Konfiguration von http.middlewares.default.yml
In diesem Abschnitt konfigurieren wir die HTTP-Middlewares, die Traefik zur Sicherung und Optimierung der Webanfragen verwenden soll. Diese Konfiguration wird in der Datei http.middlewares.default.yml
definiert und enthält wichtige Sicherheits-Header sowie eine Komprimierungsoption für HTTP-Antworten. Die Middleware „default“ wird standardmäßig für die web
und websecure
EntryPoints in der traefik.yml
geladen.
Öffne die Datei zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/dynamic_conf/http.middlewares.default.yml
http: middlewares: default: chain: middlewares: - default-security-headers - gzip default-security-headers: headers: browserXssFilter: true contentTypeNosniff: true forceSTSHeader: true frameDeny: true stsIncludeSubdomains: true stsPreload: true stsSeconds: 31536000 customFrameOptionsValue: "SAMEORIGIN" gzip: compress: {}
Erklärung der Konfiguration:
- default:
- Dies ist die Hauptmiddleware, die in der
traefik.yml
als Standard-Middleware für dieweb
undwebsecure
EntryPoints verwendet wird. Sie besteht aus einer Kette (chain
) von Middlewares:- default-security-headers: Fügt Sicherheits-Header zu allen HTTP-Antworten hinzu.
- gzip: Komprimiert HTTP-Antworten, um die Datenübertragung zu optimieren.
- Dies ist die Hauptmiddleware, die in der
- default-security-headers:
- browserXssFilter: true: Aktiviert den Browser XSS-Schutz (Cross-Site-Scripting).
- contentTypeNosniff: true: Verhindert, dass der Browser den Dateityp anhand des Inhalts rät.
- forceSTSHeader: true: Aktiviert den HSTS (HTTP Strict Transport Security)-Header, der Browser anweist, nur HTTPS-Verbindungen zuzulassen.
- frameDeny: true: Verhindert das Laden der Seite in einem
<frame>
oder<iframe>
, um Clickjacking-Angriffe zu verhindern. - stsIncludeSubdomains: true: Erzwingt HSTS auch für alle Subdomains.
- stsPreload: true: Signalisiert, dass diese Seite in die HSTS-Preload-Liste aufgenommen werden kann, sodass HSTS auch ohne den ersten HTTP-Aufruf greift.
- stsSeconds: 31536000: Setzt die Gültigkeit des HSTS-Headers auf ein Jahr (31536000 Sekunden).
- customFrameOptionsValue: „SAMEORIGIN“: Erlaubt das Einbetten von Inhalten nur innerhalb der eigenen Domain (
SAMEORIGIN
).
- gzip:
- compress: {}: Aktiviert die GZIP-Komprimierung für HTTP-Antworten, was die Übertragungsgeschwindigkeit optimiert, indem die Daten komprimiert werden.
Wichtig:
Die Middleware „default“ wird in der traefik.yml
an die web
und websecure
EntryPoints angehängt und standardmäßig bei Anfragen über diese Endpunkte mitgeladen. Diese Konfiguration sorgt dafür, dass alle Anfragen über HTTPS gesichert und optimiert werden, und fügt wichtige Sicherheitsmaßnahmen wie XSS-Schutz und HSTS hinzu.
7.4.4. Konfiguration von http.middlewares.traefik-dashboard-auth.yml
In diesem Schritt fügen wir eine Basic-Auth-Authentifizierung für das Traefik-Dashboard hinzu. Diese Konfiguration schützt den Zugriff auf das Dashboard mithilfe eines Passworts, das in einer .htpasswd-Datei gespeichert wird.
Erstelle die Datei http.middlewares.traefik-dashboard-auth.yml
:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/dynamic_conf/http.middlewares.traefik-dashboard-auth.yml
http: middlewares: traefik-dashboard-auth: basicAuth: realm: "Traefik Dashboard" usersFile: "/etc/traefik/.htpasswd"
Erklärung der Konfiguration:
- traefik-dashboard-auth: Diese Middleware implementiert eine Basic-Auth-Authentifizierung für das Traefik-Dashboard.
- basicAuth:
- realm: Der Authentifizierungsbereich wird als “Traefik Dashboard” festgelegt.
- usersFile: Der Pfad zur .htpasswd-Datei, die die Benutzername-Passwort-Kombinationen enthält.
- basicAuth:
7.4.5. Passwort für Traefik-Dashboard festlegen
Um die Benutzername-Passwort-Kombination für die Basic-Auth festzulegen, müssen wir .htpasswd-Datei
mit Informationen füttern. Zuerst überprüfen wir ob der Befehl verfügbar ist und installieren die notwendigen Pakete:
command -v htpasswd >/dev/null 2>&1 || apt update && apt install -y apache2-utils
Nun generieren wir für unseren Benutzer ein Passwort und schreiben es in unsere .htpasswd-Datei
:
htpasswd /opt/containers/traefik-crowdsec-stack/data/traefik/.htpasswd <deinBenutzername>
Benutzername und Passwort sind “case-sensitive”, das bedeutet, Groß- und Kleinschreibung müssen exakt übereinstimmen. Wir können mit dem genannten Befehl jederzeit beliebig viele Nutzer zur .htpasswd-Datei hinzufügen. Allerdings müssen wir, wenn Traefik bereits läuft, den Container neu starten, damit die Änderungen wirksam werden.
7.4.6. Konfiguration von http.middlewares.traefik-bouncer.yml
In diesem Abschnitt fügen wir den CrowdSec Bouncer als Middleware hinzu. Diese Middleware prüft eingehende Anfragen auf ihre Berechtigung, basierend auf der CrowdSec-Bannliste. Der Bouncer wird als Middleware konfiguriert und sorgt dafür, dass unerwünschte Anfragen blockiert werden.
Öffne die Datei http.middlewares.traefik-bouncer.yml
zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/dynamic_conf/http.middlewares.traefik-bouncer.yml
http: middlewares: traefik-bouncer: forwardauth: address: http://traefik-crowdsec-bouncer:8080/api/v1/forwardAuth trustForwardHeader: true
Erklärung der Konfiguration:
- traefik-bouncer: Diese Middleware verwendet die
forwardauth
-Methode, um Anfragen über den CrowdSec Bouncer zu leiten. - address: Gibt die Adresse des Bouncers an, der auf
http://traefik-crowdsec-bouncer:8080/api/v1/forwardAuth
läuft. Dieser prüft, ob die IP-Adresse des Anfragenden auf der Bannliste steht. - trustForwardHeader: true: Traefik vertraut auf die im
Forwarded
-Header enthaltenen Informationen, um die Authentifizierung korrekt durchzuführen.
7.4.7. Integration des Bouncers in traefik.yml
Damit der Bouncer aktiv Anfragen überprüfen kann, müssen wir die traefik.yml
bearbeiten und die Middleware zu den web
und websecure
EntryPoints hinzufügen.
Öffne die traefik.yml
zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/traefik/traefik.yml
Füge in den Einträgen web
und websecure
die traefik-bouncer
-Middleware hinzu. Die Konfiguration sollte folgendermaßen aussehen:
entryPoints: ping: address: ':88' web: address: ':80' http: redirections: entryPoint: to: websecure scheme: https websecure: address: ':443' http: middlewares: - default@file - traefik-bouncer@file
Erklärung der Änderungen:
- traefik-bouncer@file: Diese Zeile fügt den CrowdSec Bouncer als zusätzliche Middleware hinzu. Dadurch wird jede Anfrage, die über
web
oderwebsecure
kommt, zuerst durch den Bouncer überprüft. Der Bouncer entscheidet, ob die Anfrage basierend auf der Bannliste zugelassen oder blockiert wird.
Durch diese Konfiguration wird sichergestellt, dass Anfragen an den Traefik-Proxy, die auf der Bannliste von CrowdSec stehen, standardmäßig blockiert werden. Dies erhöht die Sicherheit des Systems und schützt es vor bekannten Bedrohungen.
7.5. CrowdSec konfigurieren
7.5.1. Acquisition anpassen
Damit CrowdSec Angriffe oder unberechtigte Zugriffsversuche erkennen und die potenziellen Gefährder blockieren kann, müssen wir CrowdSec mit den relevanten Logs versorgen. CrowdSec überwacht und analysiert die Logs der Dienste, um nach vordefinierten Mustern verdächtige Aktivitäten zu erkennen und entsprechend zu reagieren.
Als ersten Schritt lassen wir CrowdSec die Standardkonfiguration laden:
docker compose up crowdsec -d && docker compose down
# Diese Anleitung setzt voraus, dass sie als Root-User ausgeführt wird. # Um Root-Rechte zu erlangen, kann folgender Befehl verwendet werden: sudo su # Wenn du stattdessen in deiner Umgebung auf `sudo` angewiesen bist, # sollte der Befehl an dieser Stelle in der Anleitung wie folgt lauten: sudo -E docker compose up crowdsec -d && docker compose down
Der Hinweis darf ignoriert werden:
WARN[0000] The "BOUNCER_KEY_FIREWALL" variable is not set. Defaulting to a blank string.
Nun können wir die Acquisition-Konfiguration anpassen, damit CrowdSec die richtigen Log-Dateien überwacht. Wir öffnen die Datei acquis.yaml
zur Bearbeitung:
nano /opt/containers/traefik-crowdsec-stack/data/crowdsec/config/acquis.yaml
Dort entfernen wir alle bestehenden Einträge und füge die folgenden Einträge hinzu, um die relevanten Logs hinzuzufügen:
filenames: - /var/log/auth.log - /var/log/syslog labels: type: syslog --- filenames: - /var/log/traefik/access.log labels: type: traefik ---
Erklärung der Konfiguration:
• /var/log/auth.log und /var/log/syslog: Diese Logs enthalten sicherheitsrelevante Informationen, wie Anmeldeversuche und Systemmeldungen, die CrowdSec überwachen soll. Der Log-Typ ist hier syslog.
• /var/log/traefik/*.log: Hier überwachen wir die Traefik-Logs. CrowdSec wird diese Logs durchsuchen, um verdächtige Aktivitäten zu identifizieren. Der Log-Typ ist traefik.
Diese Konfiguration sorgt dafür, dass CrowdSec die wichtigen System- und Traefik-Logs durchforstet und auf unberechtigte Zugriffe reagiert, indem es entsprechende Maßnahmen ergreift, z.B. das Blockieren von IP-Adressen.
No Comment! Be the first one.