Wenn mehrere Dienste auf demselben Server über Port 80 (für HTTP) oder 443 (für HTTPS) kommunizieren sollen, kann dies zu Konflikten führen, da normalerweise nur ein Dienst einen bestimmten Port zu einem bestimmten Zeitpunkt belegen kann. Hier kommt Traefik ins Spiel und hilft, dieses Problem zu lösen.
Traefik agiert als Reverse-Proxy und Load-Balancer und ermöglicht es, dass alle eingehenden Anfragen auf Port 80 oder 443 an die richtigen Dienste weitergeleitet werden, basierend auf den von Ihnen konfigurierten Regeln. Dies wird manchmal als “Routing” bezeichnet.
In wie weit unterscheidet sich diese zu der bisherigen vorhandenen Anleitung?
- Meine bisherige Anleitung ist nun schon ein paar Tage alt und ich habe in der Zwischenzeit vieles weiter lernen dürfen.
- Es gab viele wichtige Kommentare, Fragen und Anregungen – vielen Dank dafür!
- Es steht in absehbarer Zeit ein Traefik Major Release an – Version 3
0. Versionierung
Datum | Änderung |
---|---|
06.11.2023 | 3 kleine Anpassungen an der traefik.yml nach Hinweisen von @Umek –
– providers.providersThrottleDuration: 10s – tls_resolver.acme.tlsChallenge: {} |
20.10.2023 | Anleitungüberprüfung. Frischer Ubuntu Server mit dieser Anleitung 1:1 umgesetzt. |
23.07.2023 | Differenz zwischen Ubuntu und Debian hinzugefügt unter 9.3.1. |
12.07.2023 | Entfernen des Hinweis vom 10.07.2023 |
10.07.2023 | Hinweis zu Problemen mit Docker 24.0.4 |
02.07.2023 | Hinweis zur Stabilität und automatisierten Updates hinzugefügt |
26.06.2023 | Bugfix zu Version Traefik v2.10.3 In der /opt/containers/traefik-crowdsec-stack/traefik/traefik.yml Zeile hub: true unter experimental entfernen |
04.06.2023 | sleep 30 aus Punkt 5.2. entfernt |
25.05.2023 | Migration ans Ende der Einleitung verschoben |
Initialer Release |
1. Zielsetzung & Vorwort
- Traefik v2 installieren und konfigurieren
- Crowdsec installieren und konfigurieren
- Traefik Services via CrowdSec sichern
- Einzelner Stack
- Wie wir unsere Services mit Traefik verfügbar machen
Hinweis: Bitte beachtet, dass ich nicht jede Änderung im Vergleich zur alten Anleitung ausführlich darlegen werde. Allerdings werde ich besondere Sorgfalt darauf verwenden, an Stellen, an denen die neue Anleitung nicht mehr mit der alten kompatibel ist, einen entsprechenden Hinweis einzufügen. Mein Ziel ist es, euch durch diesen Prozess so reibungslos und verständlich wie möglich zu führen.
Wenn du ein neues Setup, also einen neuen Server aufsetzt, dann kannst du diese Anleitung einfach abarbeiten.
Solltest du aber die alte Anleitung befolgt haben und möchtest nun auf diese FullStack-Anleitung setzten musst du vorher ALLE Container und ALLE Netzwerke außer host,bridge
und none
herunterfahren und dann nach der Anleitung anpassen und Schritt für Schritt wieder hochfahren!
ACHTUNG! Die gesamte Anleitung wurde als root
-User durchgeführt!
2. Voraussetzung
3. Traefik + CrowdSec im Stack vorbereiten
In dieser aktualisierten Anleitung konzentrieren wir uns darauf, Traefik, CrowdSec und alle damit verbundenen Komponenten in einem einzigen Stack zu definieren. Warum? Ganz einfach, die Erfahrung hat gezeigt, dass die Startreihenfolge der Container durchaus relevant sein kann. Mit einem Full-Stack-Ansatz kann ich diesen Aspekt besser steuern und somit eine optimale Performance und Funktionalität gewährleisten.
Wichtiger Hinweis!
Diese Anleitung ist nicht vollständig kompatibel zu meiner alten und wohl bekanntesten Anleitung! Ich werde am Ende ein extra Abschnitt nur der Migration widmen.
3.1. Verzeichnisse / Dateien anlegen
Beginnen wir mit der Erstellung der benötigten Verzeichnisse für den Full-Stack. Im Folgenden wird das Hauptverzeichnis traefik-crowdsec-stack
erstellt, und dann darin Unterordner für traefik
, crowdsec
, config
und zwei zusätzliche Unterordner für config
und data
in crowdsec
.
# Hauptverzeichnis erstellen und zusätzliche Unterordner in 'crowdsec' erstellen mkdir -p /opt/containers/traefik-crowdsec-stack/{traefik,crowdsec/{config,data},config} # Ins Hauptverzeichnis wechseln cd /opt/containers/traefik-crowdsec-stack
Im nächsten Schritt erzeugen wir die notwendigen Dateien und setzen die korrekten Zugriffsrechte.
# .env Datei im Hauptverzeichnis erstellen touch /opt/containers/traefik-crowdsec-stack/.env # Umgebungsspezifische .env Dateien in 'config' erstellen touch /opt/containers/traefik-crowdsec-stack/config/{crowdsec.env,traefik.env,traefik-crowdsec-bouncer.env} # Zusätzliche Dateien in 'traefik' erstellen und Zugriffsrechte für bestimmte Dateien festlegen touch /opt/containers/traefik-crowdsec-stack/traefik/{acme_letsencrypt.json,traefik.yml,dynamic_conf.yml,tls_letsencrypt.json} chmod 600 /opt/containers/traefik-crowdsec-stack/traefik/{acme_letsencrypt.json,tls_letsencrypt.json}
Als nächstes möchten wir sicherstellen, dass alles korrekt angelegt wurde. Hierfür verwenden wir den tree
Befehl. Falls das tree
Programm noch nicht installiert ist, können wir es wie folgt installieren:
Für Ubuntu/Debian:
apt install tree
Jetzt können wir den Befehl tree
Verzeichnis ausführen
tree -L 2 -a /opt/containers/traefik-crowdsec-stack/
um die Struktur zu überprüfen. Die Ausgabe sollte folgendermaßen aussehen:
. ├── config │ ├── crowdsec.env │ ├── traefik.env │ └── traefik-crowdsec-bouncer.env ├── crowdsec │ ├── config │ └── data ├── .env └── traefik ├── acme_letsencrypt.json ├── dynamic_conf.yml ├── tls_letsencrypt.json └── traefik.yml
Wenn eure Ausgabe genau so aussieht, habt ihr alles richtig gemacht und wir können weitermachen. Wenn nicht, überprüft bitte die vorherigen Schritte.
Bevor wir diesen Abschnitt abschließen, sollten wir einige wichtige Unterschiede zu meiner alten Anleitung hervorheben:
- Datenstruktur: Die Art und Weise, wie wir unsere Daten strukturieren, hat sich erheblich verändert. Wir nutzen jetzt eine ordentlichere und effizientere Struktur, die es uns ermöglicht, die Dinge besser zu organisieren und zu verwalten.
- Verwendung von .env Dateien: In dieser Anleitung verwenden wir .env Dateien, um Umgebungsvariablen zu speichern. Dies ist eine übliche Praxis, die uns hilft, sensitive Informationen sicher und organisiert zu halten, und es uns ermöglicht, verschiedene Einstellungen für verschiedene Umgebungen zu haben.
- TLS Resolver: Ein zusätzliches Feature dieser Anleitung ist die Verfügbarkeit eines TLS Resolvers. Dies ist ein mächtiges Werkzeug, das wir im weiteren Verlauf der Anleitung detailliert behandeln werden.
3.2. docker-compose.yml anlegen
Wir beginnen nun mit der Erstellung unserer docker-compose.yml
Datei. Hierfür verwenden wir den Texteditor nano
. Um die Lesbarkeit zu verbessern und die Verwaltung zu erleichtern, teilen wir die Datei in mehrere Abschnitte auf. Jeder Abschnitt befasst sich mit einem bestimmten Aspekt unserer Stack-Konfiguration.
nano docker-compose.yml
Mit dem obigen Befehl öffnen wir nano
und erstellen gleichzeitig die Datei docker-compose.yml
, falls sie noch nicht existiert. Nun können wir mit der Konfiguration unserer Full-Stack-Anwendung beginnen.
# Die Version der Docker Compose-Datei. Hier verwenden wir Version 3.9. version: "3.9" # Der Beginn des 'services' Abschnitts. services:
# Name des Services. crowdsec: # Der Name des Containers, der aus diesem Service erzeugt wird container_name: ${SERVICES_CROWDSEC_CONTAINER_NAME:-crowdsec} # Umgebungsvariablen für den Container. env_file: ./config/crowdsec.env # Hostname des CrowdSec-Containers, kann über eine Umgebungsvariable angepasst werden. hostname: ${SERVICES_CROWDSEC_HOSTNAME:-crowdsec} # Gesundheitsüberprüfung für den CrowdSec-Service healthcheck: test: ["CMD", "cscli", "version"] interval: 20s timeout: 2s retries: 5 start_period: 10s # Docker-Image, das für den Container verwendet wird. image: ${SERVICES_CROWDSEC_IMAGE:-crowdsecurity/crowdsec}:${SERVICES_CROWDSEC_IMAGE_VERSION:-latest} # Netzwerke, zu denen der Container gehört. networks: crowdsec: # Feste IPv4-Adresse vergeben. ipv4_address: ${SERVICES_CROWDSEC_NETWORKS_CROWDSEC_IPV4:-172.31.254.254} # Restart-Strategie für den Container. restart: unless-stopped # Sicherheitsoptionen für den Container. security_opt: - no-new-privileges=true # Volumes, die vom Container verwendet werden. volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - /var/log/auth.log:/var/log/auth.log:ro - /var/log/traefik:/var/log/traefik:ro - ./crowdsec/config:/etc/crowdsec - ./crowdsec/data:/var/lib/crowdsec/data
# Der Name des Service traefik: # Der Name des Containers, der aus diesem Service erzeugt wird container_name: ${SERVICES_TRAEFIK_CONTAINER_NAME:-traefik} # Diese Option sorgt dafür, dass der Traefik-Service erst gestartet wird, # nachdem der Crowdsec-Service healthy ist depends_on: crowdsec: condition: service_healthy # Umgebungsvariablen für den Container. env_file: ./config/traefik.env # Hostname des Traefik-Containers, kann über eine Umgebungsvariable angepasst werden. hostname: ${SERVICES_TRAEFIK_HOSTNAME:-traefik} # Gesundheitsüberprüfung für den Traefik-Service healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] interval: 10s timeout: 1s retries: 3 start_period: 10s # Das Docker-Image, das für diesen Service verwendet wird # Version kann über eine Umgebungsvariable angepasst werden. Standard: 2.10 image: ${SERVICES_TRAEFIK_IMAGE:-traefik}:${SERVICES_TRAEFIK_IMAGE_VERSION:-2.10} # Docker Labels für den Traefik-Service. Diese werden für die Traefik-Konfiguration verwendet labels: traefik.docker.network: proxy traefik.enable: "true" traefik.http.routers.traefik.entrypoints: websecure traefik.http.routers.traefik.middlewares: default@file traefik.http.routers.traefik.rule: Host(${SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST}) traefik.http.routers.traefik.service: api@internal traefik.http.routers.traefik.tls: "true" traefik.http.routers.traefik.tls.certresolver: http_resolver traefik.http.services.traefik.loadbalancer.sticky.cookie.httpOnly: "true" traefik.http.services.traefik.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 # Die Netzwerke, zu denen dieser Service gehört networks: crowdsec: # IPv4-Adresse des CrowdSec Containers im Traefik-Netwerk: crowdsec ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_CROWDSEC_IPV4:-172.31.254.253} proxy: # IPv4-Adresse des Traefik Containers im Traefik-Netwerk: proxy ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_PROXY_IPV4:-172.16.255.254} # Die Ports, die diesem Service zugeordnet sind ports: - "80:80" # HTTP - "443:443" # HTTPS # Der Restart-Policy dieses Service restart: unless-stopped # Sicherheitsoptionen für diesen Service security_opt: - no-new-privileges:true # Die Volumes, die diesem Service zugeordnet sind volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - /var/log/traefik/:/var/log/traefik/ - ./traefik/traefik.yml:/traefik.yml:ro - ./traefik/acme_letsencrypt.json:/acme_letsencrypt.json - ./traefik/tls_letsencrypt.json:/tls_letsencrypt.json - ./traefik/dynamic_conf.yml:/dynamic_conf.yml
# Definition des Traefik CrowdSec Bouncer-Dienstes traefik_crowdsec_bouncer: # Der Name des Containers, der aus diesem Service erzeugt wird container_name: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_CONTAINER_NAME:-traefik_crowdsec_bouncer} # Abhängigkeitsdefinition: Dieser Service wird erst gestartet, wenn der Crowdsec-Service als "healthy" gekennzeichnet ist depends_on: crowdsec: condition: service_healthy # Pfad zur .env-Datei für den Traefik CrowdSec Bouncer-Dienst env_file: ./config/traefik-crowdsec-bouncer.env # Der Hostname des Containers, kann über eine Umgebungsvariable angepasst werden hostname: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_HOSTNAME:-traefik-crowdsec-bouncer} # Docker-Image, das für den Container verwendet wird. Die Version kann über eine Umgebungsvariable angepasst werden image: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_IMAGE:-fbonalair/traefik-crowdsec-bouncer}:${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_IMAGE_VERSION:-latest} # Netzwerke, zu denen der Container gehört networks: crowdsec: # Feste IPv4-Adresse für den Container in diesem Netzwerk ipv4_address: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_NETWORKS_CROWDSEC_IPV4:-172.31.254.252} # Restart-Strategie für den Container. 'unless-stopped' bedeutet, dass der Container immer neu gestartet wird, es sei denn, er wird manuell gestoppt restart: unless-stopped
# Definition der Netzwerke, die von den Services verwendet werden networks: # Definition des 'proxy' Netzwerks proxy: # Der Name des Netzwerks, kann über eine Umgebungsvariable angepasst werden name: ${NETWORKS_PROXY_NAME:-proxy} # Der Treiber, der für das Netzwerk verwendet wird, hier ist es 'bridge' driver: bridge # IP-Adress-Management-Konfiguration (IPAM) ipam: # Konfiguration des IP-Adress-Subnetzes für das Netzwerk config: - subnet: ${NETWORKS_PROXY_SUBNET_IPV4:-172.30.0.0/16} # Wenn 'attachable' auf 'true' gesetzt ist, können Standalone-Container an dieses Netzwerk angehängt werden attachable: true # Definition des 'crowdsec' Netzwerks crowdsec: # Der Name des Netzwerks, kann über eine Umgebungsvariable angepasst werden name: ${NETWORKS_CROWDSEC_NAME:-crowdsec} # Der Treiber, der für das Netzwerk verwendet wird, hier ist es 'bridge' driver: bridge # IP-Adress-Management-Konfiguration (IPAM) ipam: # Konfiguration des IP-Adress-Subnetzes für das Netzwerk config: - subnet: ${NETWORKS_CROWDSEC_SUBNET_IPV4:-172.31.0.0/16} # Wenn 'attachable' auf 'true' gesetzt ist, können Standalone-Container an dieses Netzwerk angehängt werden attachable: true
version: "3.9" services: crowdsec: container_name: ${SERVICES_CROWDSEC_CONTAINER_NAME:-crowdsec} env_file: ./config/crowdsec.env hostname: ${SERVICES_CROWDSEC_HOSTNAME:-crowdsec} healthcheck: test: ["CMD", "cscli", "version"] interval: 20s timeout: 2s 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.254.254} restart: unless-stopped security_opt: - no-new-privileges=true volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - /var/log/auth.log:/var/log/auth.log:ro - /var/log/traefik:/var/log/traefik:ro - ./crowdsec/config:/etc/crowdsec - ./crowdsec/data:/var/lib/crowdsec/data traefik: container_name: ${SERVICES_TRAEFIK_CONTAINER_NAME:-traefik} depends_on: crowdsec: condition: service_healthy env_file: ./config/traefik.env hostname: ${SERVICES_TRAEFIK_HOSTNAME:-traefik} healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] interval: 10s timeout: 1s retries: 3 start_period: 10s image: ${SERVICES_TRAEFIK_IMAGE:-traefik}:${SERVICES_TRAEFIK_IMAGE_VERSION:-2.10} labels: traefik.docker.network: proxy traefik.enable: "true" traefik.http.routers.traefik.entrypoints: websecure traefik.http.routers.traefik.middlewares: default@file traefik.http.routers.traefik.rule: Host(${SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST}) traefik.http.routers.traefik.service: api@internal traefik.http.routers.traefik.tls: "true" traefik.http.routers.traefik.tls.certresolver: http_resolver traefik.http.services.traefik.loadbalancer.sticky.cookie.httpOnly: "true" traefik.http.services.traefik.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.254.253} proxy: ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_PROXY_IPV4:-172.30.255.254} ports: - "80:80" - "443:443" restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - /var/log/traefik/:/var/log/traefik/ - ./traefik/traefik.yml:/traefik.yml:ro - ./traefik/acme_letsencrypt.json:/acme_letsencrypt.json - ./traefik/tls_letsencrypt.json:/tls_letsencrypt.json - ./traefik/dynamic_conf.yml:/dynamic_conf.yml traefik_crowdsec_bouncer: container_name: ${SERVICES_TRAEFIK_CROWDSEC_BOUNCER_CONTAINER_NAME:-traefik_crowdsec_bouncer} depends_on: crowdsec: condition: service_healthy env_file: ./config/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.254.252} restart: unless-stopped networks: proxy: name: ${NETWORKS_PROXY_NAME:-proxy} driver: bridge ipam: config: - subnet: ${NETWORKS_PROXY_SUBNET_IPV4:-172.30.0.0/16} attachable: true crowdsec: name: ${NETWORKS_CROWDSEC_NAME:-crowdsec} driver: bridge ipam: config: - subnet: ${NETWORKS_CROWDSEC_SUBNET_IPV4:-172.31.0.0/16} attachable: true
Es ist zu beachten, dass wir nun keine direkten Änderungen an der docker-compose.yml
Datei mehr vornehmen müssen. Die meisten Einstellungen, einschließlich der Container-Namen, Hostnamen, Netzwerkeinstellungen und verwendeten Docker-Images, werden im nächsten Schritt über Umgebungsvariablen in einer .env
Datei definiert.
3.3. DOTENV Konfiguration
In diesem Schritt bearbeiten wir die .env
Datei, um die Dienste und Netzwerkeinstellungen anzupassen.
nano /opt/containers/traefik-crowdsec-stack/.env
Hier ist unser Setup:
# Service Crowdsec SERVICES_CROWDSEC_CONTAINER_NAME=crowdsec SERVICES_CROWDSEC_HOSTNAME=crowdsec SERVICES_CROWDSEC_IMAGE=crowdsecurity/crowdsec SERVICES_CROWDSEC_IMAGE_VERSION=latest SERVICES_CROWDSEC_NETWORKS_CROWDSEC_IPV4=172.31.254.254 # Service Traefik SERVICES_TRAEFIK_CONTAINER_NAME=traefik SERVICES_TRAEFIK_HOSTNAME=traefik SERVICES_TRAEFIK_IMAGE=traefik SERVICES_TRAEFIK_IMAGE_VERSION=2.10 SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST=`traefik.DeineDomainHier.de` SERVICES_TRAEFIK_NETWORKS_CROWDSEC_IPV4=172.31.254.253 SERVICES_TRAEFIK_NETWORKS_PROXY_IPV4=172.30.255.254 # Service Traefik Crowdsec Bouncer SERVICES_TRAEFIK_CROWDSEC_BOUNCER_CONTAINER_NAME=traefik_crowdsec_bouncer SERVICES_TRAEFIK_CROWDSEC_BOUNCER_HOSTNAME=traefik-crowdsec-bouncer SERVICES_TRAEFIK_CROWDSEC_BOUNCER_IMAGE=fbonalair/traefik-crowdsec-bouncer SERVICES_TRAEFIK_CROWDSEC_BOUNCER_IMAGE_VERSION=latest SERVICES_TRAEFIK_CROWDSEC_BOUNCER_NETWORKS_CROWDSEC_IPV4=172.31.254.252 # Netzwerkeinstellungen NETWORKS_PROXY_NAME=proxy NETWORKS_PROXY_SUBNET_IPV4=172.30.0.0/16 NETWORKS_CROWDSEC_NAME=crowdsec NETWORKS_CROWDSEC_SUBNET_IPV4=172.31.0.0/16
Bis auf eine Ausnahme ist dieses Beispielsetup bereits optimiert und erfordert keine weiteren Anpassungen, um richtig zu funktionieren. Die einzige Zeile, die du anpassen musst, ist SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST
. Hier definierst du die eigene Domain für das Traefik-Dashboard. Denke daran, `traefik.DeineDomainHier.de`
durch die tatsächliche Domain zu ersetzen, welche auch via A oder CNAME auf den richtigen Server zeigt, die du für das Traefik-Dashboard verwenden möchtest.
Achtung! Die ``
sind unabdingbar! Hier könnten aber auch mehrere Domains definiert werden:
SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST=`traefik.DeineDomainHier.de`,`www.traefik.DeineDomainHier.de`
3.4. Erläuterung zur Konfiguration
3.4.1. Healthchecks
Unsere Konfiguration nutzt Healthchecks für Traefik und CrowdSec. Healthchecks sind praktische Funktionen, die uns ermöglichen zu überprüfen, ob ein Service ordnungsgemäß läuft. Wenn ein Healthcheck fehlschlägt, weiß Docker, dass mit diesem Service etwas nicht stimmt, und kann entsprechend reagieren.
Die Healthchecks sind in diesem Kontext besonders wichtig, weil wir mit ihnen und der depends_on
-Funktion die Reihenfolge und Abhängigkeiten der einzelnen Services in unserem Stack besser kontrollieren können.
Die depends_on
-Option erlaubt es uns, die Startreihenfolge unserer Container festzulegen. Ein Container, der von einem anderen Container abhängt, wird erst gestartet, wenn der abhängige Container vollständig hochgefahren und betriebsbereit ist. Mit Healthchecks können wir sicherstellen, dass ein Service nicht nur gestartet wurde, sondern tatsächlich ordnungsgemäß funktioniert, bevor wir einen abhängigen Service starten.
In unserem Fall sorgt dies dafür, dass der Traefik und CrowdSec vollständig betriebsbereit sind, bevor der Traefik CrowdSec Bouncer gestartet wird, was uns dabei hilft, sicherzustellen, dass unser Stack stabil und zuverlässig läuft.
3.4.2. Netzwerkkonfiguration
In unserer Konfiguration vergeben wir für die beiden Netzwerke proxy
und crowdsec
spezifische IP-Adressbereiche. Zudem weisen wir den drei Services jeweils feste IP-Adressen zu, die sich am Ende des jeweils verfügbaren IP-Bereichs befinden. Aber warum machen wir das eigentlich?
Der IP-Adressbereich jedes Netzwerks wird festgelegt, um eine gewisse Konsistenz in unserer Setup-Konfiguration zu gewährleisten. Wir weisen jeder Service-Instanz im jeweiligen Netzwerk eine spezifische IP-Adresse zu, die sich am Ende des verfügbaren IP-Bereichs befindet. Dadurch stellen wir sicher, dass die IP-Adressen der Services konstant bleiben und es unwahrscheinlich ist, dass sie versehentlich von Docker’s DHCP-Dienst einem anderen Container zugewiesen werden. Dies könnte zu Adresskonflikten führen.
Zudem benötigen viele Systeme, wie zum Beispiel WordPress, die als Docker-Container laufen, die genaue IP-Adresse des Proxy-Servers (in unserem Fall Traefik). Sollte diese IP-Adresse nicht festgelegt sein, können Fehlfunktionen auftreten. Das liegt daran, dass sich die IP-Adresse bei einem neuen DHCP-Lease ändern könnte, was dazu führen würde, dass die Einstellungen von WordPress oder ähnlichen Systemen nicht mehr korrekt wären.
Durch die Festlegung von spezifischen IP-Adressbereichen und die Zuweisung von IP-Adressen am Ende dieser Bereiche an unsere Services sorgen wir für eine stabile und konsistente Netzwerkkonfiguration. Dies ermöglicht es uns, später weitere Container sicher hinzuzufügen, die dann vom Docker-Netzwerk-DHCP eine Adresse aus dem Anfangsbereich des Netzwerks zugewiesen bekommen können.
3.4.3. Neustart und Abhängigkeiten
Unsere Verwendung eines Docker Stacks bietet weitere Vorteile in Bezug auf die Wartung und Zuverlässigkeit unseres Systems. Innerhalb eines Docker Stacks werden alle definierten Netzwerke und Dienste als zusammenhängende Einheit behandelt. Das bedeutet, dass bei einem Neustart des Stacks alle Dienste in der korrekten Reihenfolge und mit den notwendigen Abhängigkeiten hochgefahren werden.
Durch diese Organisation wird sichergestellt, dass, falls das System neu gestartet werden muss oder aus irgendeinem Grund ausfällt, alle Dienste und Netzwerke ordnungsgemäß und in der korrekten Reihenfolge wieder hergestellt werden.
Das trägt nicht nur zu einem stabileren System bei, sondern erleichtert auch die Wartung, da wir nicht manuell jeden Dienst in einer bestimmten Reihenfolge starten müssen. Der Docker Stack kümmert sich automatisch darum, was letztlich Zeit spart und das Risiko von Fehlern reduziert.
4. Traefik-Konfiguration
4.1. Konfiguration der traefik.yml
Jetzt widmen wir uns der Konfigurationsdatei traefik.yml
. In dieser Datei setzen wir statische Konfigurationsoptionen fest.
nano /opt/containers/traefik-crowdsec-stack/traefik/traefik.yml
Hier ein unsere Konfiguration:
api: dashboard: true metrics: prometheus: addRoutersLabels: true certificatesResolvers: http_resolver: acme: email: "deine@email.de" storage: "acme_letsencrypt.json" httpChallenge: entryPoint: web tls_resolver: acme: email: "deine@email.de" storage: "tls_letsencrypt.json" tlsChallenge: {} entryPoints: ping: address: ':88' web: address: ':80' http: redirections: entryPoint: to: websecure scheme: https middlewares: - traefik-crowdsec-bouncer@file websecure: address: ':443' http: middlewares: - traefik-crowdsec-bouncer@file proxyProtocol: trustedIPs: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 forwardedHeaders: trustedIPs: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 ping: entryPoint: "ping" global: checknewversion: true sendanonymoususage: false experimental: plugins: real-ip: moduleName: github.com/Paxxs/traefik-get-real-ip version: "v1.0.2" providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: "proxy" file: filename: "./dynamic_conf.yml" watch: true providersThrottleDuration: 10s log: level: "INFO" filePath: "/var/log/traefik/traefik.log" accessLog: filePath: "/var/log/traefik/access.log" bufferingSize: 100
Beachte bitte, dass du die E-Mail-Adressen unter certificatesResolvers
zwei mal anpasst. Sie dienen als Kontaktinformationen für Let’s Encrypt und sollten daher auf eine gültige E-Mail-Adresse gesetzt sein, die du kontrollierst.
Hinweis! An dieser Stelle darf nur eine E-Mail-Adresse gesetzt werden. Zwei unterschiedliche führen 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
4.2. Konfiguration der dynamic_conf.yml
Jetzt widmen wir uns der Konfigurationsdatei dynamic_conf.yml
. In dieser Datei setzen wir statische Konfigurationsoptionen fest.
nano /opt/containers/traefik-crowdsec-stack/traefik/dynamic_conf.yml
Hier ein unsere Konfiguration:
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: 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: {} traefik-crowdsec-bouncer: forwardauth: address: http://traefik-crowdsec-bouncer:8080/api/v1/forwardAuth trustForwardHeader: true real-ip-cf: plugin: real-ip: Proxy: - proxyHeadername: "*" realIP: Cf-Connecting-Ip OverwriteXFF: true
4.3. Erläuterung zu Traefik-Konfiguration
4.3.1. Änderung im ACME-Bereich
Unter dem Abschnitt certificatesResolvers
haben wir den Bezeichner für den HTTP-Resolver von http
in http_resolver
geändert.
certificatesResolvers: http_resolver: acme: email: "deine@email.de" storage: "acme_letsencrypt.json" httpChallenge: entryPoint: web
Der Grund für diese Änderung ist, die Klarheit und Verständlichkeit der Konfigurationsdatei zu verbessern. Da der Begriff http
an mehreren Stellen in der traefik.yml
Konfiguration verwendet wird, kann dies zu Verwirrung führen. Durch die Umbenennung in http_resolver
verdeutlichen wir, dass es sich hier speziell um den Mechanismus zur Erstellung des Zertifikats handelt, nicht um den allgemeinen HTTP-Eintrag unter entryPoints
. Dies trägt zur Verbesserung der Lesbarkeit und des Verständnisses der Konfiguration bei.
4.3.2. Hinzufügen des tls_resolver
Unter dem Abschnitt certificatesResolvers
haben wir nun auch einen TLS-Resolver: tls_resolver
tls_resolver: acme: email: "deine@email.de" storage: "tls_letsencrypt.json" tlsChallenge: {}
Die TLS-Challenge (oder TLS-ALPN-01 Challenge) ist eine moderne und effektive Methode zur Überprüfung der Domainkontrolle für die Ausstellung von Let’s Encrypt-Zertifikaten. Sie nutzt eine spezielle TLS-Erweiterung namens “Application-Layer Protocol Negotiation” (ALPN) zur Kommunikation mit dem Let’s Encrypt-Validierungsserver während des TLS-Handshakes.
Für die Entwicklung von Python-Webanwendungen, insbesondere solchen, die auf dem Flask-Framework basieren, kann die Verwendung eines TLS-Resolvers besonders vorteilhaft sein. Viele solcher Anwendungen laufen auf Port 443 und profitieren daher von der Verwendung der TLS-Challenge zur Zertifikatserzeugung.
Wichtig zu beachten ist, dass die Verwendung der TLS-Challenge spezifische Anforderungen an die Server- und Netzwerkkonfiguration stellt. Unter anderem muss Ihr Server den ALPN-Erweiterungsstandard unterstützen und Port 443 muss in Ihrer Firewall offen sein. Daher ist es empfehlenswert, die Eignung Ihrer Server- und Netzwerkkonfiguration zu überprüfen, bevor Sie sich für die Verwendung der TLS-Challenge entscheiden.
4.3.3. Überarbeitung der EntryPoints
In unserem aktualisierten Setup haben wir einige Anpassungen an den entryPoints vorgenommen. Insbesondere haben wir den Namen des http
entryPoint zu web
und den https
entryPoint zu websecure
geändert.
entryPoints: ping: address: ":88" web: address: ":80" http: redirections: entryPoint: to: "websecure" scheme: "https" middlewares: - traefik-crowdsec-bouncer@file websecure: address: ":443" http: middlewares: - traefik-crowdsec-bouncer@file proxyProtocol: trustedIPs: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16 forwardedHeaders: trustedIPs: - 10.0.0.0/8 - 172.16.0.0/12 - 192.168.0.0/16
Diese Änderungen sind hauptsächlich aus Kompatibilitäts- und Klarheitsgründen durchgeführt worden. Die offizielle Dokumentation von Traefik verwendet in der Regel web
und websecure
als entryPoint-Namen, und durch die Einhaltung dieser Benennungskonvention werden unsere Konfigurationen leichter verständlich für jeden, der mit Traefik vertraut ist. Darüber hinaus erleichtert die Einhaltung der offiziellen Benennungskonventionen das Verständnis und die Anwendung der offiziellen Traefik-Dokumentation.
Es ist wichtig zu beachten, dass trotz der Namensänderungen die Funktionalität der entryPoints gleich bleibt – web
leitet den unverschlüsselten HTTP-Verkehr auf Port 80 und websecure
handhabt den verschlüsselten HTTPS-Verkehr auf Port 443.
4.3.4. Anpassung der Middleware-Namen
In der neuesten Version der Konfiguration haben wir die Middleware für beide Einträge web
und websecure
aktualisiert. Die Middleware wurde von crowdsec-bouncer@file
auf traefik-crowdsec-bouncer@file
geändert.
entryPoints: ... web: ... http: middlewares: - traefik-crowdsec-bouncer@file websecure: ... http: middlewares: - traefik-crowdsec-bouncer@file
Der Grund für diese Änderung liegt in der klaren Namensführung und Übersichtlichkeit. Der Name traefik-crowdsec-bouncer
verdeutlicht, dass dieser Bouncer speziell für Traefik konzipiert ist. Dies ist besonders wichtig, da es verschiedene Bouncer für unterschiedliche Anwendungen und Kontexte gibt. Ein klares und explizites Benennen erleichtert das Verständnis und die Wartung des Setups.
5. CrowdSec-Konfiguration
5.1. Konfiguration der crowdsec.env
Zur Konfiguration von CrowdSec bearbeiten wir die Datei config/crowdsec.env
. Diese Datei ist essentiell, um die Umgebungsvariablen übersichtlich und zentral zu definieren. Durch die Auslagerung dieser Definitionen in eine separate Datei, bleibt unser Setup klar strukturiert und wartungsfreundlich.
nano /opt/containers/traefik-crowdsec-stack/config/crowdsec.env
Dort definieren wir ein paar Environments welche wir in CrowdSec benötigen:
PGID="1000" COLLECTIONS="crowdsecurity/traefik crowdsecurity/http-cve crowdsecurity/whitelist-good-actors crowdsecurity/postfix crowdsecurity/dovecot crowdsecurity/nginx"
PGID
: Dies steht für “Group ID” und bestimmt, unter welcher Gruppen-ID der CrowdSec-Prozess ausgeführt wird. Im vorliegenden Fall ist das die Gruppen-ID “1000”. Die Gruppen-ID sollte der ID einer existierenden Gruppe in deinem System entsprechen, die die benötigten Zugriffsrechte hat.COLLECTIONS
: Dies ist eine Liste von sogenannten “Collection”-Namen. Eine Collection in CrowdSec ist eine Gruppe von Szenarien, Parsern und Post-Overflows, die einen bestimmten Zweck erfüllen. Im vorliegenden Fall werden die folgenden Collections verwendet:crowdsecurity/traefik
: Diese Collection ist speziell für die Überwachung und den Schutz von Traefik, einem modernen Reverse-Proxy und Load-Balancer.crowdsecurity/http-cve
: Diese Collection enthält Szenarien zur Erkennung von bekannten Schwachstellen und Angriffen (CVEs) auf HTTP-Server.crowdsecurity/whitelist-good-actors
: Eine Collection, die dafür sorgt, dass bekannte “gute” Akteure nicht fälschlicherweise als bösartig erkannt werden.crowdsecurity/postfix
undcrowdsecurity/dovecot
: Diese beiden Collections sind speziell für die Überwachung und den Schutz von Postfix- und Dovecot-Mailservern.crowdsecurity/nginx
: Eine Collection, die speziell für die Überwachung und den Schutz von Nginx-Webservern entwickelt wurde.
Diese Umgebungsvariablen sind entscheidend für die Konfiguration von CrowdSec. Sie ermöglichen es, das Verhalten von CrowdSec fein abzustimmen und an die spezifischen Anforderungen deines Systems anzupassen. Es ist wichtig, diese Werte sorgfältig zu überprüfen und zu aktualisieren, um die bestmögliche Sicherheit zu gewährleisten.
5.2. Konfiguration der acquis.yaml
Zu diesem Zeitpunkt könntest du bemerkt haben, dass wir bisher keine acquis.yaml
-Datei angelegt haben. Der Grund dafür ist, dass diese Datei Teil der Ressourcen ist, die das Docker-Image von CrowdSec bereitstellt. Um die Konfigurationsdateien von CrowdSec zu generieren, müssen wir den CrowdSec-Dienst kurz starten. Dazu wechseln wir zunächst in das Verzeichnis unserer Docker-Compose-Datei für den Traefik-CrowdSec-Stack und starten dann den Dienst:
cd /opt/containers/traefik-crowdsec-stack docker compose up crowdsec -d && docker compose down
Mit dem Befehl docker compose up crowdsec -d
starten wir den CrowdSec-Dienst im Hintergrundmodus. Schließlich beenden wir den Dienst wieder mit docker compose down
.
Jetzt sollten alle Konfigurationsdateien von CrowdSec vorhanden sein und wir können nun die acquis.yaml
-Datei nach anpassen. In der acquis.yaml
-Datei werden die Log-Dateien definiert welche eingelesen und beobachtet werden sollen. Hier ist es wichtig, dass die Logdateien und Services auch in CrowdSec eingebunden sind. Dies habe ich in dieser Anleitung bereits in der docker-compose.yml
angelegt:
version: "3.9" services: crowdsec: ... volumes: ... # Hier wird die auth.log vom System in CrowdSec eingebracht - /var/log/auth.log:/var/log/auth.log:ro # Hier wird die der Ordner in den Traefik seine Logs schreibt in CrowdSec eingebracht - /var/log/traefik:/var/log/traefik:ro ... traefik: ... volumes: ... # Hier wird der Ordner in den Traefik seine Logs schreibt auf den Host gemounted - /var/log/traefik/:/var/log/traefik/ ... ... ...
Nun zur acquis.yaml
-Datei. Die haben wir nun generiert. Nach aktuellem Stand sieht diese so aus:
filenames: - /var/log/nginx/*.log - ./tests/nginx/nginx.log #this is not a syslog log, indicate which kind of logs it is labels: type: nginx --- filenames: - /var/log/auth.log - /var/log/syslog labels: type: syslog --- filename: /var/log/apache2/*.log labels: type: apache2
Wir passen diese nun an unsere Bedürfnisse an und dafür öffnen wir sie mit nano
.
nano /opt/containers/traefik-crowdsec-stack/crowdsec/config/acquis.yaml
Dort fügen wir folgendes ein bzw. ersetzen den vorhandenen Inhalt:
filenames: - /var/log/auth.log - /var/log/syslog labels: type: syslog --- filenames: - /var/log/traefik/*.log labels: type: traefik ---
In ersten Abschnitt der Konfigurationsdatei werden die auth.log
und syslog
Dateien zur Analyse hinzugefügt. Das Label “syslog” wird diesen Dateien zugeordnet. Dies ermöglicht es CrowdSec, bestimmte Analysemethoden auf diese Dateien anzuwenden, die für syslog-Logs geeignet sind.
Im zweiten Abschnitt der Konfigurationsdatei fügen wir alle Logdateien hinzu, die im Verzeichnis /var/log/traefik/
liegen und deren Dateinamen mit .log
enden. Diesen Dateien weisen wir das Label “traefik” zu. So kann CrowdSec spezifische Analysemethoden anwenden, die für Traefik-Logs geeignet sind.
6. Traefik und Crowdsec verheiraten – der Bouncer
CrowdSec hat nun die Fähigkeit, Logdateien zu analysieren und verdächtige IP-Adressen in eine Sperrliste aufzunehmen – das ist ein großer Schritt! Doch in der aktuellen Konfiguration haben wir noch keine Maßnahmen ergriffen, um potenzielle Angriffe tatsächlich abzuwehren. Das ist die Aufgabe sogenannter “Bouncer” in CrowdSec.
Es gibt eine Vielzahl an verschiedenen Bouncern für diverse Einsatzgebiete: Es gibt zum Beispiel Bouncer für Firewalls wie iptables oder nftables, und es gibt auch Bouncer zur Steuerung der Firewall von Cloudflare. Für unseren konkreten Anwendungsfall ist jedoch der Traefik Bouncer besonders interessant, da er die Fähigkeit hat, speziell mit unserem Traefik Load Balancer zu interagieren.
6.1. Traefik CrowdSec Bouncer
Wie du vielleicht bemerkt hast, haben wir in der zu Beginn definierten Docker-Compose-Datei bereits alle notwendigen Komponenten für den Traefik CrowdSec Bouncer unter dem Abschnitt services -> traefik_crowdsec_bouncer
eingefügt.
An dieser Stelle brauchen wir nur noch die zugehörige .env-Datei, die wir zuvor erstellt haben, um zwei weitere Werte zu erweitern in dem wir die Datei mit nano
öffnen:
nano /opt/containers/traefik-crowdsec-stack/config/traefik-crowdsec-bouncer.env
Jetzt fügen wir folgende Variablen ein:
# Access-Token damit Bouncer und CrowdSec kommunizieren können CROWDSEC_BOUNCER_API_KEY= # Hostname mit richtigem Port von CrowdSec CROWDSEC_AGENT_HOST=${SERVICES_CROWDSEC_HOSTNAME}:8080
6.1.1. Access Token anlegen
In der traefik-crowdsec-bouncer.env
haben wir die Variable CROWDSEC_BOUNCER_API_KEY
angelegt und um diese mit einem Access-Token bzw. API-Key auch nutzen zu können müssen wir diesen wie folgt generieren:
cd /opt/containers/traefik-crowdsec-stack docker compose up crowdsec -d docker compose exec -t crowdsec cscli bouncers add traefik-crowdsec-bouncer docker compose down
So, oder so ähnlich sollte die Ausgabe aussehen:
[+] Running 3/3 ✔ Network crowdsec Created 0.1s ✔ Network proxy Created 0.1s ✔ Container crowdsec Started 0.4s Api key for 'traefik-crowdsec-bouncer': ee21c448d67e04550dec5b07b42ad6ee Please keep this key since you will not be able to retrieve it! [+] Running 3/3 ✔ Container crowdsec Removed 10.2s ✔ Network crowdsec Removed 0.2s ✔ Network proxy Removed
Nun speichern wir uns den generierten Schlüssel (in diesem Beispiel: ee21c448d67e04550dec5b07b42ad6ee
) in die Zwischenablage und fügen via nano
in unsere config/traefik-crowdsec-bouncer.env
.
# Access-Token damit Bouncer und CrowdSec kommunizieren können CROWDSEC_BOUNCER_API_KEY=ee21c448d67e04550dec5b07b42ad6ee # Hostname mit richtigem Port von CrowdSec CROWDSEC_AGENT_HOST=${SERVICES_CROWDSEC_HOSTNAME}:8080
6.1.2. Traefik kontrollieren
Wie wir bereits in einem früheren Abschnitt dieser Anleitung festgelegt haben, wird in der dynamic_conf.yml
-Datei die traefik-crowdsec-bouncer
-Konfiguration definiert:
traefik-crowdsec-bouncer: forwardauth: address: http://traefik-crowdsec-bouncer:8080/api/v1/forwardAuth trustForwardHeader: true
Dieser Abschnitt ermöglicht es Traefik, mit dem CrowdSec Bouncer zu kommunizieren. Hierbei müssen wir sicherstellen, dass der unter address
angegebene Hostname dem entspricht, den wir in der .env-Datei unter folgendem Punkt definiert haben:
SERVICES_TRAEFIK_CROWDSEC_BOUNCER_HOSTNAME=traefik-crowdsec-bouncer
Leider ist es in dieser Konfiguration nicht ohne Weiteres möglich, die Variable direkt zu setzen. Alternativ kann hier jedoch auch die IP-Adresse, die unter:
SERVICES_TRAEFIK_CROWDSEC_BOUNCER_NETWORKS_CROWDSEC_IPV4=172.31.254.252
definiert ist, verwendet werden.
In der traefik.yml
-Datei haben wir unter entryPoints
Traefik angewiesen, bei jeder Anfrage, die über den jeweiligen Point web
bzw. websecure
kommt, diese direkt über die Middleware an den Bouncer zu senden:
entryPoints: web: address: ":80" http: redirections: entryPoint: to: "websecure" scheme: "https" middlewares: - traefik-crowdsec-bouncer@file websecure: address: ":443" http: middlewares: - traefik-crowdsec-bouncer@file
Diese Konfiguration gewährleistet letztendlich das erfolgreiche Zusammenspiel zwischen allen Komponenten. Traefik kommuniziert mit dem Bouncer, der wiederum mit CrowdSec kommuniziert. Diese strukturierte Kommunikation zwischen den Komponenten sorgt dafür, dass potenziell schädliche Anfragen effektiv blockiert werden.
7. Dienst starten
Uff! Das war wirklich eine lange und gründliche Anleitung bis jetzt. Ich habe mein Bestes gegeben, um viele Aspekte direkt zu erläutern und das Verständnis der Funktionsweise sowie des Aufbaus des Stacks zu erleichtern.
Jetzt, bevor wir mit dem Starten des Dienstes fortfahren, möchte ich dich bitten: Nimm dir einen Moment Zeit, geh nochmal alle Schritte durch und prüfe, ob alle Dateien richtig erstellt und mit dem passenden Inhalt gefüllt wurden.
Also, gönn dir eine kleine Pause, streck dich mal und gönn deinen Augen eine kurze Verschnaufpause vom Bildschirm. Dann, mit frischem Blick und voller Energie, können wir uns dem nächsten Schritt zuwenden. Und keine Sorge, wir sind schon fast am Ziel!
☕️☕️☕️
Bereit?
cd /opt/containers/traefik-crowdsec-stack docker compose up -d
🚀🚀🚀 Fertig, oder?
So, wir sind fast durch, aber es gibt noch ein paar Dinge, die wir erledigen müssen. Was fehlt? Die Überprüfung und die bereits angekündigte Migration der alten Anleitung zu diesem Setup.
Außerdem werde ich noch einige optionale Dinge hinzufügen. Es handelt sich dabei um Extras, die nicht unbedingt notwendig sind, aber je nach deinen spezifischen Anforderungen nützlich sein könnten. Bleib also dran und lass uns diese letzten Schritte gemeinsam erledigen!
8. Überprüfung
Natürlich sollten wir zwischendurch und gemäß dieser Anleitung immer wieder überprüfen, ob alles funktioniert, wie es sollte. Das tun wir jetzt nach all diesen Schritten.
Wir haben den Container ja bereits gestartet. Als erstes überprüfen wir, ob alle Container als “healthy” (gesund) markiert sind:
cd /opt/containers/traefik-crowdsec-stack docker compose ps
root@mail:/opt/containers/traefik-crowdsec-stack# docker compose ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS crowdsec crowdsecurity/crowdsec:latest "/bin/sh -c '/bin/ba…" crowdsec 3 days ago Up 19 hours (healthy) traefik traefik:2.10 "/entrypoint.sh trae…" traefik 3 days ago Up 22 hours (healthy) 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp traefik_crowdsec_bouncer fbonalair/traefik-crowdsec-bouncer:latest "/app" traefik_crowdsec_bouncer 3 days ago Up 3 days (healthy) root@mail:/opt/containers/traefik-crowdsec-stack#
Wenn wir alles richtig gemacht haben, sind alle Container als “healthy” markiert.
Dann rufen wir das Traefik-Dashboard mit der zuvor festgelegten URL auf. Das Dashboard sollte sich öffnen und auch ein valides LE-Zertifikat haben.
Beim Öffnen des Dashboards werden auch Logdateien erstellt, und diese überprüfen wir als nächstes:
cd /var/log/traefik ls -all cat traefik.log cat access.log
Hier sollten wir idealerweise die Dateien traefik.log
und access.log
finden, und in beide sollte etwas geschrieben sein. Wenn die Datei access.log nicht vorhanden ist, ist das kein Beinbruch, sollte aber beobachtet werden.
Wenn das alles passt, betrachten wir mit dem Befehl:
docker exec crowdsec cscli metrics
die ganz oben stehenden Acquisition Metrics
. Dort sollte nun die traefik.log
aufgeführt sein. Wenn die Datei access.log
im System vorhanden ist, sollte sie ebenfalls dort erscheinen.
Sollte etwas nicht funktionieren schaue als erstes “Hinweis zu Kommentaren” an ☕️
9. Optional
Es gibt noch einige optionale Punkte. Diesen Bereich werde ich nach und nach erweitern bzw. auf vorhandene Anleitungen verweisen!
9.1. CrowdSec aktuell halten
Die benutzten COLLECTIONS werden überwiegend durch die Community gepflegt und natürlich auch auf neue Crowdsec-Versionen angepasst. Damit wir nicht in einen Fehler laufen oder eine veraltet COLLECTION verwenden ist es Sinnvoll diese regelmäßig zu aktualisieren. Dazu legen wir uns einen Cronjob an:
crontab -e
Dieser Cronjob wird jeden Tag um 03:00 Uhr aufgerufen, aktualisiert die Pakete aus dem CrowdSec Hub und läd die Konfiguration neu.
0 3 * * * docker exec crowdsec cscli hub update && docker exec crowdsec cscli hub upgrade && docker exec -t crowdsec kill -SIGHUP 1 >/dev/null 2>&1
9.2. Traefik Dashboard schützen
Um das Traefik Dashboard abzusichern und unbefugten Zugriff zu verhindern, wird empfohlen, eine zusätzliche Authentifizierung einzurichten. Dadurch wird eine Benutzername-Passwort-Überprüfung erforderlich, um auf das Dashboard zugreifen zu können.
Traefik bietet eine einfache Methode zur Implementierung der Authentifizierung. Um dies zu erreichen, müssen wir zunächst die folgenden Pakete auf unserem System installieren:
apt update && apt install apache2-utils
Nachdem wir diese Schritte durchgeführt haben, müssen wir innerhalb von Traefik eine Middleware konfigurieren. Bevor wir dies tun, erstellen wir ein Passwort mit dem folgenden Befehl:
echo $(htpasswd -nb DeinUsername 'DeinSuperSicheresPasswort') # Ausgabe DeinUsername:$apr1$xSRxT4UY$wk42WRgVzBW5Pf69sS5aT.
Es wird empfohlen, die Ausgabe zu speichern, zum Beispiel durch Kopieren und Einfügen in eine Textdatei.
9.2.1. dynamic_conf.yml anpassen
Jetzt ist es an der Zeit, die Middleware zu konfigurieren. Dazu öffnen wir die Datei dynamic_conf.yml mit Texteditor:
nano /opt/containers/traefik-crowdsec-stack/traefik/dynamic_conf.yml
Wir befinden uns im Abschnitt “http” -> “middlewares”. Bisher sieht dieser Teil folgendermaßen aus:
... 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: {} traefik-crowdsec-bouncer: forwardauth: address: http://traefik-crowdsec-bouncer:8080/api/v1/forwardAuth trustForwardHeader: true real-ip-cf: plugin: real-ip: Proxy: - proxyHeadername: "*" realIP: Cf-Connecting-Ip OverwriteXFF: true ...
Nun fügen wir die Konfiguration für unsere Schutzmaßnahmen hinzu:
traefikAuth: basicAuth: users: - "DeinUsername:$apr1$xSRxT4UY$wk42WRgVzBW5Pf69sS5aT."
Hierbei ersetzen wir natürlich “DeinUsername” und “$apr1$xSRxT4UY$wk42WRgVzBW5Pf69sS5aT.” durch die zuvor generierten Werte.
Dieses Snippet fügen wir an beliebiger Stelle in die middlewares ein:
... 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: {} traefik-crowdsec-bouncer: forwardauth: address: http://traefik-crowdsec-bouncer:8080/api/v1/forwardAuth trustForwardHeader: true real-ip-cf: plugin: real-ip: Proxy: - proxyHeadername: "*" realIP: Cf-Connecting-Ip OverwriteXFF: true traefikAuth: basicAuth: users: - "DeinUsername:$apr1$xSRxT4UY$wk42WRgVzBW5Pf69sS5aT." ...
9.2.2. docker-compose.yml anpassen
Im letzten Schritt müssen wir Anpassungen in der Datei docker-compose.yml vornehmen. Öffnen Sie die Datei mit einem Texteditor:
nano /opt/containers/traefik-crowdsec-stack/docker-compose.yml
Suchen Sie den Abschnitt für Traefik:
traefik: container_name: ${SERVICES_TRAEFIK_CONTAINER_NAME:-traefik} depends_on: crowdsec: condition: service_healthy env_file: ./config/traefik.env hostname: ${SERVICES_TRAEFIK_HOSTNAME:-traefik} healthcheck: test: ["CMD", "traefik", "healthcheck", "--ping"] interval: 10s timeout: 1s retries: 3 start_period: 10s image: ${SERVICES_TRAEFIK_IMAGE:-traefik}:${SERVICES_TRAEFIK_IMAGE_VERSION:-2.10} labels: traefik.docker.network: proxy traefik.enable: "true" traefik.http.routers.traefik.entrypoints: websecure traefik.http.routers.traefik.middlewares: default@file traefik.http.routers.traefik.rule: Host(${SERVICES_TRAEFIK_LABELS_TRAEFIK_HOST}) traefik.http.routers.traefik.service: api@internal traefik.http.routers.traefik.tls: "true" traefik.http.routers.traefik.tls.certresolver: http_resolver traefik.http.services.traefik.loadbalancer.sticky.cookie.httpOnly: "true" traefik.http.services.traefik.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.254.253} proxy: ipv4_address: ${SERVICES_TRAEFIK_NETWORKS_PROXY_IPV4:-172.16.255.254} ports: - "80:80" - "443:443" restart: unless-stopped security_opt: - no-new-privileges:true volumes: - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock:ro - /var/log/traefik/:/var/log/traefik/ - ./traefik/traefik.yml:/traefik.yml:ro - ./traefik/acme_letsencrypt.json:/acme_letsencrypt.json - ./traefik/tls_letsencrypt.json:/tls_letsencrypt.json - ./traefik/dynamic_conf.yml:/dynamic_conf.yml
Innerhalb dieses Abschnitts finden Sie unter “labels” das Label:
traefik.http.routers.traefik.middlewares: default@file
Erweitern Sie diese Zeile nun um unsere gerade erstellte Middleware “traefikAuth”:
traefik.http.routers.traefik.middlewares: default@file,traefikAuth@file
9.2.3 Neustart des Setups
Abschließend führen wir einen Neustart des FullStacks durch und überprüfen anschließend, ob beim Aufruf des Traefik Dashboards nun ein Passwort abgefragt wird.
Wechseln Sie zum Verzeichnis des Traefik-Crowdsec-Stacks:
cd /opt/containers/traefik-crowdsec-stack
Starten Sie den FullStack neu und erzwingen Sie die Neuerstellung der Container:
docker compose up -d --force-recreate
Nachdem der Neustart abgeschlossen ist, überprüfen Sie, ob beim Aufruf des Traefik Dashboards nun ein Passwort abgefragt wird.
9.3. Erweiterung der Firewall (IP-Tables bzw. UFW) mit CrowdSec
Jetzt wollen wir CrowdSec auf unserem System installieren und die Firewall mithilfe des Bouncers um CrowdSec erweitern. In dieser Anleitung haben wir CrowdSec bereits über Docker in unser System integriert. Doch wir möchten den Firewall-Bouncer direkt auf unserem System installieren und ihn dann mit CrowdSec verknüpfen, das in einem Docker-Container läuft.
9.3.1. Repository für CrowdSec Firewall Bouncer
Um den Firewall Bouncer zu installieren, müssen wir das entsprechende Repository unter Ubuntu (bei Debian nicht notwenig) einbinden. Wir führen den folgenden Befehl aus, um die erforderlichen Repositorys hinzuzufügen:
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
Dadurch werden die benötigten Repositorys zu unserem System hinzugefügt.
9.3.2. Installation des Firewall Bouncers
Die Pakete für den CrowdSec Firewall Bouncer sind in unseren Repositories verfügbar. Wir müssen das Paket entsprechend unserem Firewall-System auswählen: IPTables bzw. UFW
Verwenden wir den folgenden Befehl, um den CrowdSec Firewall Bouncer für IPTables bzw. UFW zu installieren:
apt install crowdsec-firewall-bouncer-iptables
9.3.3. Access Token anlegen
Ähnlich wie in Schritt 6.1.1. benötigen wir auch für den CrowdSec Firewall Bouncer für IPTables einen Access Token, um mit CrowdSec kommunizieren zu können. Um diesen Access Token zu erhalten, führen wir die folgenden Schritte aus:
cd /opt/containers/traefik-crowdsec-stack docker compose exec -t crowdsec cscli bouncers add crowdsec-firewall-bouncer-iptables
So könnte die erwartete Ausgabe aussehen:
API-Schlüssel für 'crowdsec-firewall-bouncer-iptables': ee21c448d67e04550dec5b07b42ad6ee Wir müssen beachten, dass wir diesen Schlüssel gut aufbewahren, da wir ihn nicht erneut abrufen können!
Nun speichern wir uns den generierten Schlüssel (in diesem Beispiel: ee21c448d67e04550dec5b07b42ad6ee
) in die Zwischenablage.
9.3.4. Anpassung der Konfiguration
Um die Konfiguration anzupassen, geben wir einfach den folgenden Befehl ein:
nano /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
Vorher:
api_url: http://127.0.0.1:8080/ api_key:
Nachher:
api_url: http://172.31.254.254:8080/ api_key: ee21c448d67e04550dec5b07b42ad6ee
Hierbei ersetzen wir die Werte für “api_url” und “api_key” entsprechend. Beachtet, dass die euer eigener Access-Token individuell ist und von den oben gezeigten Beispielen abweichen wird.
9.3.5. CrowdSec Firewall Bouncer starten
Jetzt starten wir den Bouncer mit dem folgenden Befehl:
systemctl start crowdsec-firewall-bouncer
Anschließend überprüfen wir den Status mit dem Befehl:
systemctl status crowdsec-firewall-bouncer
Die Ausgabe sollte in etwa wie folgt aussehen:
crowdsec-firewall-bouncer.service - The firewall bouncer for CrowdSec Loaded: loaded (/etc/systemd/system/crowdsec-firewall-bouncer.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2022-10-24 23:51:09 CEST; 21s ago Process: 14877 ExecStartPre=/usr/sbin/crowdsec-firewall-bouncer -c /etc/crowdsec/bouncers/crowd .. ..
Dadurch stellen wir sicher, dass der CrowdSec Firewall Bouncer ordnungsgemäß gestartet ist.
9.3.6. Anzeigen der CrowdSec Bouncer-Liste
Jetzt können wir uns alle CrowdSec Bouncer anzeigen lassen, um sicherzustellen, dass unser Firewall Bouncer dort aufgeführt wird.
Führen wir den folgenden Befehl aus:
docker exec crowdsec cscli bouncers list
Das Ergebnis sollte in etwa wie folgt aussehen:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Name IP Address Valid Last API pull Type Version Auth Type ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- traefik-crowdsec-bouncer 172.31.255.252 ✔️ 2023-05-24T21:14:45Z Go-http-client 1.1 api-key crowdsec-firewall-bouncer-iptables 172.31.240.1 ✔️ 2023-05-24T21:15:27Z crowdsec-firewall-bouncer v0.0.27-debian-pragmatic-8d09f19d69e92a63e63888794af3a57c6a- api-key de3489 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Wir müssen beachten, dass die im obigen Beispiel aufgeführten IP-Adressen individuell für unser Setup sind und bei uns andere Werte haben werden.
Damit haben wir bestätigt, dass alles erfolgreich funktioniert hat und unser Firewall Bouncer in der Liste aufgeführt wird.
9.3.7. Auslesen des CrowdSec Firewall Bouncer Logs
Nun werfen wir einen Blick auf das Log des Firewall Bouncers. Dies kann besonders im Fehlerfall sehr hilfreich sein. Geben wir dazu den folgenden Befehl ein:
cat /var/log/crowdsec-firewall-bouncer.log
In den letzten Zeilen sollten wir Informationen sehen, dass unser Bouncer neue Entscheidungen von CrowdSec erhalten hat. Ein Beispiel könnte wie folgt aussehen:
time="24-10-2022 23:51:09" level=info msg="Using API key auth" time="24-10-2022 23:51:09" level=info msg="Processing new and deleted decisions . . ." time="24-10-2022 23:51:09" level=info msg="14 decisions added" time="24-10-2022 23:52:59" level=info msg="1 decision added" time="24-10-2022 23:54:29" level=info msg="1 decision added"
Wir müssen beachten, dass die genauen Informationen in unserem Log individuell sein können und von den oben gezeigten Beispielen abweichen können. Durch das Auslesen des Logs können wir jedoch überprüfen, ob unser Bouncer neue Entscheidungen von CrowdSec erhalten hat.
9.3.8. Automatisches Starten des CrowdSec Firewall Bouncers
Um sicherzustellen, dass unser Firewall Bouncer automatisch bei jedem Serverneustart gestartet wird, können wir einen Cron-Eintrag erstellen. Dadurch ersparen wir uns das manuelle Starten nach jedem Neustart. Credits an @ice-cue für diesen Tipp in der alten Anleitung!
Geben wir den folgenden Befehl ein, um den Cron-Editor zu öffnen:
crontab -e
Dort fügen wir nun folgende Zeile hinzu:
@reboot sleep 120 && systemctl start crowdsec-firewall-bouncer
Mit diesem Befehl wird der CrowdSec Firewall Bouncer 120 Sekunden nach dem Serverneustart gestartet. Dadurch ist gewährleistet, dass unser Firewall Bouncer automatisch beim Start des Servers gestartet wird.
9.3.9. Anzeigen der gebannten IP-Adressen
Wir könnn uns mit einem Befehl alle aktuellen Bans anschauen:
docker exec crowdsec cscli decisions list
9.3.10. Eigene IP-Adresse bannen
Um zu testen, ob alles funktioniert, wollen wir uns selbst bannen. Dadurch haben wir für EINE MINUTE keinen Zugriff mehr auf unseren Server. Zuerst ermitteln wir unsere eigene IP-Adresse mithilfe einer Webseite wie z. B. https://www.wieistmeineip.de/.
Anschließend geben wir den folgenden Befehl ein. Achtet darauf, dass ihr die “1.2.3.4” durch eure eigene IP-Adresse ersetzt:
docker exec crowdsec cscli decisions add --ip 1.2.3.4 --duration 1m
Wenn wir alles richtig gemacht haben, sollten unsere SSH-Verbindung sowie alle anderen Verbindungen zu unserem Server nun eine Minute lang blockiert bzw. gesperrt sein.
Bitte beachtet, dass dies nur zu Testzwecken empfohlen ist und wir sicherstellen sollten, dass wir wieder Zugriff auf unseren Server erhaltet, nachdem der Test abgeschlossen ist.
9.4. Logrotate für Traefik
Es ist bereits bekannt, dass die traefik.log
-Datei sehr schnell wächst, insbesondere wenn das Debug-Level auf “info” gesetzt ist. Das kann schnell zu Speicherplatzproblemen führen, wenn sie nicht gehandhabt wird. Traefik selbst bietet keine eingebaute Log-Rotation-Funktion, aber zum Glück gibt es eine Standardkomponente namens Logrotate in vielen Linux-Distributionen wie Ubuntu, die uns dabei helfen kann.
Bei diesem Inhalt handelt es sich um exklusiven Content für Community Plus Mitglieder und Supporter.
Bitte logge dich mit deinem Account ein um den Inhalt zu sehen.
10. Migration
Ich bin mir ziemlich sicher, dass dieser Beitrag meinen alten Beitrag ersetzen wird. Genau so ist es auch gedacht. Mein Plan ist, den alten Beitrag weiterhin zu erhalten, allerdings mit dem Hinweis, dass es diesen neuen gibt. Weder Christian, ich noch irgendeiner der Co-Autoren wird in der Lage sein, alle Anleitungen zeitnah anzupassen. Deshalb möchte ich hier eine allgemeine Migrationsanleitung beschreiben.
- Für diejenigen, die ihre bisherige Konfiguration bereits individuell verändert haben, gehe ich davon aus, dass sie den Stack gut genug verstanden haben, um ihr Setup selbst zu übertragen.
- Für diejenigen, die einfach nur dankbar sind, dass das alte Setup funktioniert hat, gibt es hier die Migrationsanleitung.
10.1. Neuen Container hinzufügen
Um einen neuen Container über Traefik verfügbar zu machen und gleichzeitig durch CrowdSec zu schützen, müssen wir in der zugehörigen Docker-compose.yml die Ports entfernen und dem entsprechenden Container Labels hinzufügen. Hier ein Beispiel mit WordPress:
Dies ist die docker-compose.yml aus der WordPress-Dokumentation auf hub.docker.com:
version: '3.1' services: wordpress: image: wordpress restart: always ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: exampleuser WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_NAME: exampledb volumes: - wordpress:/var/www/html db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: exampledb MYSQL_USER: exampleuser MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql volumes: wordpress: db:
Dies wird dann zu folgender Konfiguration geändert:
version: '3.1' services: wordpress: environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_NAME: exampledb WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_USER: exampleuser image: wordpress labels: traefik.docker.network: proxy traefik.enable: "true" traefik.http.routers.wordpress-secure.entrypoints: websecure traefik.http.routers.wordpress-secure.middlewares: default@file traefik.http.routers.wordpress-secure.rule: Host(`meinwordpress.de`) traefik.http.routers.wordpress-secure.service: wordpress traefik.http.routers.wordpress-secure.tls: "true" traefik.http.routers.wordpress-secure.tls.certresolver: http_resolver traefik.http.routers.wordpress.entrypoints: web traefik.http.routers.wordpress.rule: Host(`meinwordpress.de`) traefik.http.services.wordpress.loadbalancer.server.port: "80" networks: default: null proxy: null restart: always volumes: - wordpress:/var/www/html db: environment: MYSQL_DATABASE: exampledb MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: "1" MYSQL_USER: exampleuser image: mysql:5.7 networks: default: null restart: always volumes: - db:/var/lib/mysql networks: default: proxy: external: true volumes: db: wordpress:
Eine kurze Erklärung dazu: Die Ports müssen nicht mehr explizit freigegeben (exposed) werden, da dies nun Traefik übernimmt. Wir teilen Traefik lediglich über Labels mit, welcher Resolver verwendet werden soll und über welchen Port Traefik auf WordPress zugreifen kann. Zusätzlich muss dem WordPress-Container noch das Traefik-Netzwerk namens “proxy” zugewiesen werden. Allerdings sollte dies nur dem WordPress-Container zugewiesen werden, da wir zwar die Datenbank gemeinsam mit WordPress im “default”-Netzwerk betreiben, die Datenbank jedoch nicht öffentlich zugänglich machen möchten.
10.2. Beispiel Mailcow anpassen
Eine sehr bekannte Anleitung hier im Blog ist die “Mailcow – E-Mail Komplettsytem mit Antivirus, Spam Filer, Webmail, Webfrontend installieren mittels Docker und Traefik” die von Christian und mir gepflegt wird. In der Anleitung von Mailcow ist an Punkt “4.2 docker-compose.override.yml erstellen“ der Teil an dem die Labels definiert werden.
10.2.1. Ursprüngliche Konfiguration
version: '3.9' services: nginx-mailcow: labels: - "traefik.enable=true" - "traefik.http.routers.nginx-mailcow.entrypoints=http" - "traefik.http.routers.nginx-mailcow.rule=HostRegexp(`{host:(autodiscover|autoconfig|mail|mta-sts|imap|pop3|smtp).+}`)" - "traefik.http.routers.nginx-mailcow-secure.entrypoints=https" - "traefik.http.routers.nginx-mailcow-secure.rule=Host(`mail.euredomain.de`)" - "traefik.http.routers.nginx-mailcow-secure.rule=HostRegexp(`{host:(autodiscover|autoconfig|mail|mta-sts|imap|pop3|smtp).+}`)" - "traefik.http.routers.nginx-mailcow-secure.rule=Host(`mail.euredomain.de`, `autodiscover.euredomain.de`, `autoconfig.euredomain.de`, `mta-sts.euredomain.de`)" - "traefik.http.routers.nginx-mailcow-secure.middlewares=default@file" - "traefik.http.routers.nginx-mailcow-secure.tls=true" - "traefik.http.routers.nginx-mailcow-secure.tls.certresolver=http" - "traefik.http.routers.nginx-mailcow-secure.service=nginx-mailcow" - "traefik.http.services.nginx-mailcow.loadbalancer.server.port=80" - "traefik.docker.network=proxy" networks: - proxy certdumper: image: humenius/traefik-certs-dumper:latest restart: unless-stopped network_mode: none command: --restart-containers mailcowdockerized-postfix-mailcow-1,mailcowdockerized-dovecot-mailcow-1 volumes: - /opt/containers/traefik/data:/traefik:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/assets/ssl:/output:rw environment: DOMAIN: ${MAILCOW_HOSTNAME} ACME_FILE_PATH: "/traefik/acme_letsencrypt.json" networks: proxy: external: true
10.2.2. Neue Konfiguration
version: '3.9' services: nginx-mailcow: labels: - "traefik.enable=true" - "traefik.http.routers.nginx-mailcow.entrypoints=web" - "traefik.http.routers.nginx-mailcow.rule=HostRegexp(`{host:(autodiscover|autoconfig|mail|mta-sts|imap|pop3|smtp).+}`)" - "traefik.http.routers.nginx-mailcow-secure.entrypoints=websecure" - "traefik.http.routers.nginx-mailcow-secure.rule=Host(`mail.euredomain.de`)" - "traefik.http.routers.nginx-mailcow-secure.rule=HostRegexp(`{host:(autodiscover|autoconfig|mail|mta-sts|imap|pop3|smtp).+}`)" - "traefik.http.routers.nginx-mailcow-secure.rule=Host(`mail.euredomain.de`, `autodiscover.euredomain.de`, `autoconfig.euredomain.de`, `mta-sts.euredomain.de`)" - "traefik.http.routers.nginx-mailcow-secure.middlewares=default@file" - "traefik.http.routers.nginx-mailcow-secure.tls=true" - "traefik.http.routers.nginx-mailcow-secure.tls.certresolver=http_resolver" - "traefik.http.routers.nginx-mailcow-secure.service=nginx-mailcow" - "traefik.http.services.nginx-mailcow.loadbalancer.server.port=80" - "traefik.docker.network=proxy" networks: - proxy certdumper: image: humenius/traefik-certs-dumper:latest restart: unless-stopped network_mode: none command: --restart-containers mailcowdockerized-postfix-mailcow-1,mailcowdockerized-dovecot-mailcow-1 volumes: - /opt/containers/traefik-crowdsec-stack/traefik:/traefik:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/assets/ssl:/output:rw environment: DOMAIN: ${MAILCOW_HOSTNAME} ACME_FILE_PATH: "/traefik/acme_letsencrypt.json" networks: proxy: external: true
10.2.3. Änderungen
- Änderung der Eintrittspunkte:
- Von: “traefik.http.routers.nginx-mailcow.entrypoints=http”
- Zu: “traefik.http.routers.nginx-mailcow.entrypoints=web”
- Von: “traefik.http.routers.nginx-mailcow-secure.entrypoints=https”
- Zu: “traefik.http.routers.nginx-mailcow-secure.entrypoints=websecure”
- Änderung des Zertifikat-Resolver:
- Von: “traefik.http.routers.nginx-mailcow-secure.tls.certresolver=http”
- Zu: “traefik.http.routers.nginx-mailcow-secure.tls.certresolver=http_resolver”
- Änderung des Volumes für den “certdumper” Dienst:
- Von: “/opt/containers/traefik/data:/traefik:ro”
- Zu: “/opt/containers/traefik-crowdsec-stack/traefik:/traefik:ro”
10.2.4. Konfiguration mit neuerer Notationen
Mit den steigenden Docker Versionen hat auch eine leicht angepasste Notation Einzug genommen, welche ich zumindest kurz zeigen möchte:
version: '3.9' services: nginx-mailcow: labels: traefik.enable: true traefik.http.routers.nginx-mailcow.entrypoints: web traefik.http.routers.nginx-mailcow.rule: HostRegexp(`{host:(autodiscover|autoconfig|mail|mta-sts|imap|pop3|smtp).+}`) traefik.http.routers.nginx-mailcow-secure.entrypoints: websecure traefik.http.routers.nginx-mailcow-secure.rule: Host(`mail.euredomain.de`) traefik.http.routers.nginx-mailcow-secure.rule: HostRegexp(`{host:(autodiscover|autoconfig|mail|mta-sts|imap|pop3|smtp).+}`) traefik.http.routers.nginx-mailcow-secure.rule: Host(`mail.euredomain.de`, `autodiscover.euredomain.de`, `autoconfig.euredomain.de`, `mta-sts.euredomain.de`) traefik.http.routers.nginx-mailcow-secure.middlewares: default@file traefik.http.routers.nginx-mailcow-secure.tls: true traefik.http.routers.nginx-mailcow-secure.tls.certresolver: http_resolver traefik.http.routers.nginx-mailcow-secure.service: nginx-mailcow traefik.http.services.nginx-mailcow.loadbalancer.server.port: "80" traefik.docker.network: proxy networks: - proxy certdumper: image: humenius/traefik-certs-dumper:latest restart: unless-stopped network_mode: none command: --restart-containers mailcowdockerized-postfix-mailcow-1,mailcowdockerized-dovecot-mailcow-1 volumes: - /opt/containers/traefik-crowdsec-stack/traefik:/traefik:ro - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/assets/ssl:/output:rw environment: DOMAIN: ${MAILCOW_HOSTNAME} ACME_FILE_PATH: "/traefik/acme_letsencrypt.json" networks: proxy: external: true
10.3. Beispiel Nextcloud Server
Eine weitere sehr bekannte Anleitung hier im Blog ist die “Nextcloud Server – mit Docker Compose und Traefik installieren” die von Christian gepflegt wird. In der Anleitung von Nextcloud ist an Punkt “2. Docker Compose anlegen“ der Teil an dem die Labels definiert werden.
10.3.1. Alte Konfiguration
version: '3.3' services: ... nextcloud-app: environment: TRUSTED_PROXIES: 172.18.0.2/16 ... labels: - "traefik.enable=true" - "traefik.http.routers.nextcloud.entrypoints=https" - "traefik.http.routers.nextcloud.rule=(Host(`nextcloud.euredomain.de`))" - "traefik.http.routers.nextcloud.tls=true" - "traefik.http.routers.nextcloud.tls.certresolver=http" - "traefik.http.routers.nextcloud.service=nextcloud" - "traefik.http.services.nextcloud.loadbalancer.server.port=80" - "traefik.docker.network=proxy" - "traefik.http.routers.nextcloud.middlewares=nextcloud-dav,default@file" - "traefik.http.middlewares.nextcloud-dav.replacepathregex.regex=^/.well-known/ca(l|rd)dav" - "traefik.http.middlewares.nextcloud-dav.replacepathregex.replacement=/remote.php/dav/" ...
10.3.2. Neue Notation und Konfiguration
version: '3.3' services: ... nextcloud-app: environment: TRUSTED_PROXIES: 172.16.255.254 ... labels: traefik.docker.network: proxy traefik.enable: "true" traefik.http.middlewares.nextcloud-dav.replacepathregex.regex: ^/.well-known/ca(l|rd)dav traefik.http.middlewares.nextcloud-dav.replacepathregex.replacement: /remote.php/dav/ traefik.http.routers.nextcloud.entrypoints: websecure traefik.http.routers.nextcloud.middlewares: nextcloud-dav,default@file traefik.http.routers.nextcloud.rule: (Host(`nextcloud.euredomain.de`)) traefik.http.routers.nextcloud.service: nextcloud traefik.http.routers.nextcloud.tls: "true" traefik.http.routers.nextcloud.tls.certresolver: http_resolver traefik.http.services.nextcloud.loadbalancer.server.port: "80" ...
10.3.3. Hinweis zur Nextcloud Anleitung
An dieser Stelle ist nochmal ein gesonderter Hinweis zur Anleitung angebracht! Der Punkt “2.1 Trusted Proxy IP ermitteln” entfällt vollständig! In dem FullStack hat Traefik immer eine fest definierte IPv4-Adresse. So müssen wir keine Range mehr an Nextcloud weitergeben sondern können uns auf die spezifische Adresse von Traefik im proxy
-Netzwerk verlassen!
10.4. Liste bereits migrierter Anleitungen
Hier ist eine Liste von Anleitungen, die bereits erfolgreich migriert wurden:
Diese Anleitungen wurden sorgfältig überarbeitet und sind nun auf die neue Umgebung und die aktuelle Anleitung angepasst.
Hinweis
Hinweis zur Stabilität und automatisierten Updates
Es ist in der Tat eine komplexe Aufgabe, eine allumfassende Aussage über die Stabilität des Full-Stacks von Traefik und Crowdsec zu treffen. In vielerlei Hinsicht zeigt sich dieser Stack auf einer Vielzahl von Servern als außerordentlich robust und betriebssicher. Dabei ist es nicht ungewöhnlich, dass sich gelegentlich ein Container im Full-Stack verabschiedet, ein Phänomen, das in der Welt von Docker nicht nur auf Full-Stack-Systeme beschränkt ist. Hier habt ihr die Wahl, es entweder als gegeben hinzunehmen oder in den Logdateien nach der genauen Ursache zu forschen.
Um euch ein persönliches Beispiel zu geben: Diese spezielle Konfiguration läuft bei mir auf mehr als zehn Servern und über einen Zeitraum von mehr als fünf Monaten kam es nur einmal zu einem solchen Vorfall auf einem Server. Wenn ein ähnliches Ereignis nahezu zeitgleich auf mehreren Servern auftritt, liegt die Vermutung nahe, dass es eher nicht am Setup, sondern an einem externen Dienst liegt. In den Fällen, die ich beobachten konnte, gab es beispielsweise ein kurzes Problem mit Crowdsec, einem Dienst, der naturgemäß von externen Faktoren beeinflusst wird.
Dies unterstreicht nur noch mehr die unabdingbare Bedeutung eines gründlichen Monitorings der kritischen Komponenten. Damit ist es möglich, eine optimale Performance zu gewährleisten und gleichzeitig die Fähigkeit zu bewahren, bei möglichen Problemen entsprechend zu reagieren. Updates sollten dabei immer unter Aufsicht durchgeführt werden, was die Implementierung von automatisierten Updates ohne entsprechende Fallback-Option nahezu ausschließt.
Hinweis zu Traefik v3.0beta2
Das in diesem Artikel beschriebene Setup ist grundsätzlich auch mit Traefik v3.0beta2 kompatibel. Ich habe es erfolgreich getestet. Es ist jedoch wichtig zu beachten, dass in der aktuellen Beta-Version ein bekannter Fehler vorhanden ist, der dazu führt, dass das Dashboard trotz korrekter Konfiguration nicht erreichbar ist. Wie kann ich dann sicher sein, dass das Setup korrekt funktioniert? Zum Beispiel funktioniert die oben beschriebene WordPress-Anleitung perfekt und ist mit Traefik v3.0beta2 gut erreichbar. Daher ist es sicher zu schlussfolgern, dass das Setup korrekt funktioniert, trotz des Bugs mit dem Dashboard.
Hinweis zu Kommentaren
Wenn etwas nicht funktioniert, gehe noch einmal alle einzelnen Punkte in der Anleitung durch. Ich habe die Anleitung mehrfach getestet und Christian hat sie auch durchgesehen. Wenn du sicher bist, dass du alles richtig konfiguriert hast und das noch einmal überprüft hast, dann hinterlasse gerne einen Kommentar. Der Blog wird von Christian betrieben und er, sowie alle Co-Autoren, bemühen uns, alle Fragen und Probleme zu lösen – allerdings ist dies auch immer von unserer verfügbaren Zeit abhängig!
Bitte abonniert GoNeuland, damit dieser Blog uns auch weiterhin viele Jahre Freude bereiten kann 😉
Ich bekomme in den letzten Tagen immer wieder für alle Webseiten auf dem Server ein forbidden. Nicht mal die Traefik-Seite kann geladen werden.
Ich habe den Bouncer abgeschaltet (systemctl stop crowdsec-firewall-bouncer),
Server mehrfach neugestartet, alle Seiten über Docker-Down heruntergefahren, aber alles umsonst.
In der “docker exec crowdsec cscli decisions list” sind keine Einträge.
Nur ein “docker exec crowdsec cscli decisions delete –all” bringt die Befreiung. Obwohl in der decision list keine Einträge sind, steht dann dort, dass über 30.000 Einträge gelöscht wurden.
Ich sehe nur in den Crowdsec-Logs ständig
Die Messages sollten aber eigentlich nicht zu einem Ban führen, dachte ich? Ich weiß trotzdem nicht, wieso dort für jeden Aufruf so ein Message kommt.
Hat jemand eine Idee, woran es liegen könnte? Hat der Logeintrag vom Crowdsec event. mit dem Problem etwas zutun?
Für jede Hilfe wäre ich sehr dankbar!
Hallo und vielen Dank für deinen großartigen Beitrag! Mein Setup ähnelt dem deinen, allerdings verwende ich den Nginx-Proxy-Manager für meine Dienste. Ich würde ungern auf Traefik umsteigen und frage mich daher, ob du ein Tutorial für den Nginx-Proxy-Manager erstellen könntest. Das wäre wirklich fantastisch! Selbstverständlich wäre ich bereit, als Dankeschön eine kleine Spende beizusteuern. Vielen herzlichen Dank im Voraus!
Hallo Zusammen,
ich verzweifel:
Mein Server schmeißt mich immer wieder raus und bannt mich dann. Workaround: WAN-Verbindung am Router trennen und neu einwählen, um eine neue IP-Adresse zu beziehen. Dann kann ich mich wieder für ca. fünf Minuten auf dem Server einloggen, danach werde ich wieder gebannt usw. Die IP-Adresse bleibt auch für mind. 12h gebannt :-(.
Ich habe alles nach der Anleitung abgearbeitet und finde den Fehler nicht. Jetzt habe ich den crowdsec-bouncer-firewall per systemctl stop crowdsec… gestoppt. Trotzdem fliege ich immer wieder raus. Hat einer eine Idee, was der Fehler sein könnte? Ich habe übrigens nach diversen Anleitungen hier aus den Kommentaren versucht den Fehler zu beseitigen, leider erfolglos. Auch habe ich den Server komplett neu aufgesetzt, die Anleitung wieder komplett durchgespielt und es funktioniert trotzdem nicht 🙁
Hallo zusammen,
ich kämpfe ja schon eine Weile mit den Problem (Forbidden), das Frank als Timing-Problem beschreibt. Ich habe den iptables-Firewall-Bouncer nebendran installiert und der hat sich korrekt angemeldet. (IP-Addresse sichtbar in cscli bouncers list). der Traefik-crowdsec-bouncer zeigte aber KEINE IP-Adresse.
Jetzt haltet euch fest, was der Fehler war:
Ich hatte (weil ich noch alte alisese dafür benutzt habe)
“docker-compose crowdsec -d up” eingegeben.
Dann geht es nicht! wenn ich
“docker compose crowdsec -d up” eingebe (OHNE “-“)
dann geht es. Es sind also definitiv die Timingprobleme.
DANKE an Frank!
Das gute daran ist, dass ich jeden Stein in Traefik umgedreht habe und viel gelernt habe 🙂
Vielen dank für die anleitung. Ich versuche das ältere system von goneuland auf das neue zu übertragen.
Dabei stolpere ich – nach eingabe des befehls
docker compose up crowdsec -d && docker compose down
über folgende fehlermeldung:
no configuration file provided: not found
Könnte mir jemand vielleicht sagen, was ich falsch gemacht habe?
Danke!
jko
PS: Ich hatte die _docker-compose.yml_ nicht angelegt. Nichts desto trotz: ich bekomme immer noch keine konfigurationsdateien, sondern die meldung:
validating /opt/containers/traefik-crowdsec-stack/docker-compose.yml: services must be a mapping
Irgendwie verpasse ich etwas.
Hallo zusammen ,
super Anleitung aber ein paar Fehler haben sich eingeschlichen 🙂 und ein Erweiterung die für mich wichtig war:
1. Bannen auf dem Host wird nicht gehen da die Konfig in “9.3.4. Anpassung der Konfiguration” nicht auf dem Crowdsec service im container zugreifen kann. Dafür muss das Dockercompose file mit einem Portmapping erweitert werden. (Fehler sind im log sichtbar)Anpassung der docker-compose.yml :
2. ! für alle die gebannt werden ! : (ich ja auch ;)) es gibt noch einen config Fehler das “Whitelist”s nicht gezogen werden . Dafür muss mindestens folgende Ordnerstruktur und die whitelists.yaml angelegt werden.
Ihr werdet merken das noch einige SymLinks fehlen aber die sind für den ersten Betrieb nicht notwendig.
Check via :
ach ja und wenn schon gesperrt/banned dann (1.2.3.4 mit euer ip ersetzen)
unban :
3. der Healthcheck war für mich nicht ausreichend da Crowdsec immer wieder lange braucht zum hochfahren und ich somit einige Probleme mit Bouncer & Traefik hatte. (bspw konnt letsencrypt nicht gezogen werden. >> Thema Forbidden
Anpassung der docker-compose.yml :
Guten Abend zusammen,
vielen Dank für die Anleitung.
Ich habe einen neuen Server genau nach Anleitung aufgesetzt.
Das Traefik Dashboard läuft.
Dann habe ich nach Eurer Anleitung den Matrix-Server aufgesetzt.
Läuft auch.
Anschließend habe ich das WhatsApp-Plugin installiert.
Lief auch.
Nach einiger Zeit bricht die SSH-Verbindung zusammen mit der Meldung, dass sie seitens des Servers disconnected wurde. Gleichzeitig ist beim Zugriff auf das Traefik Dashboard, und die Matrix Page nur noch ein “Forbidden” zu sehen.
Ich scheine gebannt zu sein 🙁
WhatsApp-Plugin kann ich nicht deinstallieren, weil ich jedesmal mitten im Ansible Playbook disconnected werde.
Was kann ich tun?
Hallo zusammen,
ich habe nach eurer Anleitung traefik mit nextcloud installiert. Es lief ungefähr 2 Tage.
Jetzt kommt nur noch eine schwarze Seite mit Forbidden. In den LOgs habe ich gefunden, dass eich anscheinend von crowdsec gebannt wurde. Wie kann das sein?
Kann ich das irgendwie rückgängig machen?
Gruß,
STS
Die Anleitung ist ja wirklich etwas umfangreicher. Vielen Dank für die Mühe.
Ein kleines Problem habe ich bei der acme_challenge:
Ich bekomme einen 403
time=”2023-11-16T13:08:20+01:00″ level=error msg=”Unable to obtain ACME certificate for domains \”traefik7.ce.gmbh\”: unable to generate a certificate for the domains [traefik7.ce.gmbh]: error: one or more domains had a problem:\n[traefik7.ce.gmbh] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: 148.251.235.6: Invalid response from http://traefik7.ce.gmbh/.well-known/acme-challenge/itZsOGR6uA_X28FLos1Roshku_q6kGiqZkKIm-s6lSk: 403\n” rule=”Host(
traefik7.cloudservice.gmbh
)” providerName=http_resolver.acme ACME CA=”https://acme-v02.api.letsencrypt.org/directory” routerName=traefik@dockerNormalerweise mache ich letsencrypt auf einem zweiten Server, aber das sollte doch kein Problem sein, oder?
Gerne würde ich Monit lokal auf dem Host installieren und dabei das Monit Webportal nur für den Localhost (127.0.0.1) zugänglich machen. Danach würde ich gerne den Zugriff von “aussen” über Traefik/Crowdsec routen lassen. Hat jemand Erfahrung damit und könnte beschreiben, ob und wie man so etwas macht? Danke im Voraus für Tipps und Hilfen.
Nachdem Traefik nach dieser Anleitung nun lauft, vielen Dank nochmal dafür 2 Fragen
zu den logs
muss hier was getan werden ?
kann gefahrlos ein update gemacht werden ?
Ralf
Hallo Allerseits,
erstmal Danke
psycho0verload für die sehr gute und prima kommentierte Anleitung.
Ich habe mein Setup:
Docker traefik-crowdsec-stack
Docker nextcloud
Docker kanboard
noch um folgende externe Dienste erweitert (auf einem separaten univention Server)
extern Wekan -> läuft
extern portal-Anwendung -> läuft
Woran ich seit mehreren Tagen scheitere, ist folgendes Problem:
Ein externer Server “M-Server” benötigt ein eigenes LE-Zertifikat. Hierzu soll der Traffic verschlüsslt an den Server durchgereicht werden. Allerdings scheitere ich am Acme Challenge, hier bekomme ich immer eine 404 in der Access.log oder traefik.log.
Ich bin dabei nach folgender Anleitung vorgegangen:
https://blog.alexanderhopgood.com/traefik/letsencrypt/2020/07/18/traefik-tls-passthrough
Meine Config folgt dabei noch prinzipiell der Anleitung oben, testweise habe ich in der Traefik.yml die standard-weiterleitung von web zu websecure aufgehoben, sonst ist alles “original”.
Crowdsec meldet keine bans.
Hat jemand von Euch eine Idee, was hier verkehrt läuft?
LG Jochen
Traefik.log
Access.log
Dynamic Conf:
Hallo
habe die Anleitung bis 9.3 soweit durch, traefik Dashboard startet mit Benutzerabfrage aber im traefik log bekomme ich den Fehler nicht weg:
cme-v02.api.letsencrypt.org/directory” providerName=tls_resolver.acme
time=”2023-11-07T17:46:38Z” level=error msg=”middleware \”traefik-crowdsec-bouncer@file\” does not exist” routerName=web-to-websecure@internal entryPointName=web
time=”2023-11-07T17:46:38Z” level=error msg=”middleware \”traefik-crowdsec-bouncer@file\” does not exist” entryPointName=web routerName=acme-http@internal
Irgendeine Idee?
Eine Anleitung wie ich im Docker Container custom parser/whitelists hinzufügen kann wäre noch hilfreich.
Ich habe FoundryVTT bei mir laufen, basiert auf NodeJS, und ich werde ständig selbst wegen probing gebannt wenn ich auf die Seite davon gehe.
Ich würde gerne eine Ausnahme dafür hinzufügen, bzw. erstmal rausfinden warum genau ich gebannt werde?
Hallo,
ich habe eine komplette Neuinstallation aufgrund dieser tollen Beschreibung durchgeführt. Alles hat sauber funktioniert, doch als ich zum Testen kam, konnte das Traefik Dashboard nicht geladen werden.
Ich erhalte die folgenden Meldungen in der traefik.log:
##################
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Traefik version 2.10.5 built on 2023-10-11T13:54:02Z”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://doc.traefik.io/traefik/contributing/data-collection/\n”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Enabling ProxyProtocol for trusted IPs [10.0.0.0/8 172.16.0.0/12 192.168.0.0/16]” entryPointName=websecure
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Starting provider aggregator aggregator.ProviderAggregator”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Starting provider *file.Provider”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Starting provider *traefik.Provider”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Starting provider *docker.Provider”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Starting provider *acme.ChallengeTLSALPN”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Starting provider *acme.Provider”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Starting provider *acme.Provider”
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Testing certificate renew…” ACME CA=”https://acme-v02.api.letsencrypt.org/directory” providerName=tls_resolver.acme
time=”2023-11-04T19:03:44+01:00″ level=info msg=”Testing certificate renew…” providerName=http_resolver.acme ACME CA=”https://acme-v02.api.letsencrypt.org/directory”
time=”2023-11-04T19:03:44+01:00″ level=error msg=”middleware \”traefik-crowdsec-bouncer@file\” does not exist” entryPointName=web routerName=web-to-websecure@internal
time=”2023-11-04T19:03:44+01:00″ level=error msg=”middleware \”traefik-crowdsec-bouncer@file\” does not exist” entryPointName=web routerName=acme-http@internal
time=”2023-11-04T19:04:03+01:00″ level=error msg=”Unable to obtain ACME certificate for domains \”speedtraefik….\”: unable to generate a certificate for the domains [speedtraefik…..]: error: one or more domains had a problem:\n[speedtraefik…..] acme: error: 400 :: urn:ietf:params:acme:error:connection :: 1.1.1.1: Fetching http://speedtraefik…../.well-known/acme-challenge/oeZnfS….R1YYf1XBGm1qmM4: Error getting validation data\n” providerName=http_resolver.acme ACME CA=”https://acme-v02.api.letsencrypt.org/directory” routerName=traefik@docker rule=”Host(
speedtraefik.....
)”######################
Ich habe hier leider bisher keine Lösung gefunden. Wie kann ich dieses Problem lösen?
Schöne Grüße
Guten Abend 🙂 Also es scheint so, dass alles funktioniert. Top! Eine Frage habe ich noch, wie ich folgendes Szenario am besten löse?
Ich betreibe einige Dienste, welche ich nur intern im Zugriff haben möchte. Bespiel: paperless.private.meinedomain.de. Bis dato mache ich das über Wildcard-Zertifikate mittels Cloudflare und folgenden Labels an der docker-compose.yml.
– “traefik.http.routers.traefik-secure.tls=true”
– “traefik.http.routers.traefik-secure.tls.certresolver=cloudflare”
– “traefik.http.routers.traefik-secure.tls.domains[0].main=private.meinedomain.de”
– “traefik.http.routers.traefik-secure.tls.domains[0].sans=*.private.meinedomain.de”
Kann ich das mit diesem Setup ebenfalls irgendwie erreichen bzw. wie würdest “du” (hoffe das passt” umsetzen? LG
Mit Debian 12 (bookworm) müssen die erforderlichen Repositorys für das crowdsec-firewall-bouncer-iptables package mittels “curl” hinzugefügt werden.
Wenn man dies nicht tut, bekommt man folgende Fehlermeldung:
root@XXXXX:/opt/containers/traefik-crowdsec-stack# apt install crowdsec-firewall-bouncer-iptables
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
E: Unable to locate package crowdsec-firewall-bouncer-iptables
Die angehängte Grafik zeigt den ausgeführten curl Befehl auf Debian 12, im Anschluss daran konnte das crowdsec-firewall-bouncer-iptables package mittels apt install normal installiert werden
Danke erstmal für die zahlreichen Anleitungen! Ich wollte eben auf meiner Ubuntu 22.0.4 VM eine neue Installation vornehmen. Nun die Frage warum in das /opt Verzeichnis? Das ist doch grundsätzlich nur mittels root Rechten zugänglich. Grundsätzlich passt es vom Platz her schon, aber laut Eurer Anleitung wird kein sudo verwendet. So kommt aber die Meldung: 😁
Wenn ich das nun mittels sudo mache geht es, aber so muss ich doch immer mittels sudo arbeiten? Habe ich irgendwas übersehen?
Vielen Dank für die tolle Anleitung -sie funktionierte bei mir auf Anhieb 👍
Ich würde mir noch wünschen, wenn man anstatt der Absicherung des Treafik-Dashboards via UserID/Passwort auch noch den Fall der Absicherung über eine 2FA mit Authelia behandeln könnte. Dies basierend auf der ebenfalls sehr gelungenen Authelia-Anleitung in goneuland.
Hallo Zusammen. Super Anleitung. DTraefik läuft bei mir auf mehrere Servern ohne Probleme. Meine Frage ist nun was genau muss ich den ändern wenn ich ein Lets Encrypte Zertifikat per DNS Challenge beziehen möchte?
Hallo, ich bekomme die Installation hin und das Dashboard öffnet sich auch. Füge ich nun gemäß 9.2 + 9.2.1 die Authentifizierung hinzu, komme ich nach Neustart nicht mehr auf meine traffic.xyz.de Seite. Hat jemand noch dieses Problem? vg
Hallo,
hat jemand eine Idee was die folgende Fehlermeldung nach einem einfachen apt update/upgrade zu bedeuten hat? (Debian 11)
Setting up crowdsec-firewall-bouncer-iptables (0.0.28) …
Job for crowdsec-firewall-bouncer.service failed because the control process exited with error code.
See “systemctl status crowdsec-firewall-bouncer.service” and “journalctl -xe” for details.
dpkg: error processing package crowdsec-firewall-bouncer-iptables (–configure):
installed crowdsec-firewall-bouncer-iptables package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
crowdsec-firewall-bouncer-iptables
E: Sub-process /usr/bin/dpkg returned an error code (1)
Frage zu 5.1
PGID
: Dies steht für “Group ID” und bestimmt, unter welcher Gruppen-ID der CrowdSec-Prozess ausgeführt wird. Im vorliegenden Fall ist das die Gruppen-ID “1000”. Die Gruppen-ID sollte der ID einer existierenden Gruppe in deinem System entsprechen, die die benötigten Zugriffsrechte hat.Welche Zugriffsrechte für was muss die Gruppe haben? In meinem Setup gibt es nur den Root Nutzer. Wenn ich jetzt einen User erstelle, brauch ich ja für diesen eine Gruppe mit den entsprechenden Rechten
Es gibt mittlerweile eine bessere Lösung für das automatische Starten des Bouncers, dass du unter Punkt 9.3.8 über einen cronjob erreichst: https://github.com/crowdsecurity/cs-firewall-bouncer/issues/216#issuecomment-1365493725. Damit integriert man das Ganze sauber in die Systemd-Umgebung.
Yowa hat es auch schon angemerkt: Die traefik.env wird gar nicht benutzt und kann somit entfernt werden 😉
Ich bekomme ab Schritt 8 im taffic.log folgenden Fehler:
Neustarts ändern nichts.
Allerdings startet bei mir Dashboard. Es wird an keiner Stelle ein Fehler ausgewiesen. Siehe Anlage.
Dashboard ist die Middlware traefik-crowdsec-bouncer@file mit einem Haken vorhanden. Ich bin allerdings nicht Experte genug, um zu beurteilen, ob ich da an der richtigen Stelle nachgeschaut habe.
🤔 Ist das ein “temporärer Schluckauf” und ich kann das ignorieren oder habe ich irgendwo einen gravierenderen Fehler? Ich freue mich über Hinweise!
Hallo psycho0verload
in der .env ist die Traefik Image Version ja auf 2.10 fixiert. Muss das noch so bleiben oder kann das wieder auf latest geändert werden. Wie sieht deine Erfahrung mit Traefik 3 im Moment aus.
Gruß Andreas
Ich werde im Heimnetz bei Aufruf meiner Domains immer auf die Login-Seite von MyFritz! weitergeleitet. Sobald ich mich z. B. per VPN oder mobilen Daten außerhalb meines Heimnetzes befinde funktioniert es so wie es sollte.
Selbst lösen können: Der DNS-Rebind Schutz der Fritz!Box griff und ich musste meine DynDNS-URL hinterlegen. Seitdem klappt’s.
An der Stelle aber gefragt: Die Synchronisation der Nextcloud führt ständig dazu, dass meine (öffentliche) IP der Fritz!Box gebannt wird. Ich habe jetzt die URL von Træfik gewhitelistet. Das klingt für mich aber nach einer unschönen Lösung, hat jemand eine gute Idee?
Moin
psycho0verload,
lässt sich dieses Schema für externe Dienste nahtlos mit deiner Strukur verknüpfen?
Edit: Grammatik. 🙃
Puh, endlich klappt es (dritter Versuch). Da hatte ich wohl irgendwo einen Fehler beim kopieren drin. Vielen Dank für die tolle Arbeit!
Hallo,
meine Frage zielt nicht auf die Anleitung zurück. Die ist super.
Ich möchte hinter meiner Fritzbox einen zweiten Reserve-Proxy installierten. Der soll zu Testzwecken sein. Wie kann ich also zwei Proxy mit Traefik wie hier beschrieben installieren. Geht das überhaupt oder habe ich da gerade einen riesen Denkfehler und das geht garnicht weil für diesen Fall gerade ein Reserve-Proxy ist. Wäre Klasse wenn ich Tipps bekomme. Vielen Dank.
Falls jemand wie ich das Problem hatte, dass das Dashboard nicht über die vergeben URL erreichbar war, obwohl alle DynDNS-Einstellungen passten, dem hilft vielleicht der verlinkte Kommentar-Strang und diese Lösung.
TL;DR:
Bei Aufruf der URL/IP-Adresse des Dashboards wird folgender Fehler angezeigt:
Bei Überprüfung der acme_letsencrypt.json und tls_letsencrypt.json stellt man fest, dass diese leer sind.
Problem: Die Größe der Maximum Transmission Units (MTU) von Docker (?) überschreitet die des Netzwerks.
Lösung: Die Größe der MTU des Netzwerks muss ermittelt und in das docker-compose.yml in folgender Form aufgenommen werden:
…
networks:
proxy:
driver_opts:
com.docker.network.driver.mtu: ERMITTELTER_MTU_WERT
…
Hallo!
Crowdsec zeigt bei mir immer folgende Fehlermeldung:”
level=error msg=”while fetching bouncer info: select bouncer: ent: bouncer not found: unable to query” ip=172.31.254.252″
Kleiner Hinweis: Unter 3.2 (Abschnitt 3 – Konfiguration für den Traefik-Service) gibt es eine kleine Abweichung zum unkommentierten Code: Beim proxy Netzwerk ist die IP 172.16.255.254 statt 172.30.255.254 hinterlegt.
Moin . Hab mal eine frage 🙂 Bei mir ist beim update was schief gelaufen.
Besteht eine möglichkeit nochmal an den alten api key ran zu kommen?
Oder bouncer new install?
Mfg
Schöne Anleitung (wie alle die ich mir hier bisher angeschaut habe :D), aber ich stehe ein wenig auf dem Schlauch was ich falsch gemacht haben könnte:
traefik und crowdsec arbeiten beide, diverse dienste sind erreichbar, eine manuelle sperrung über Crowdsec auf meine Lokale IP funktioniert problemlos, gehe ich jedoch raus aus meinem LAN, z.B. via VPN und ich sperre die IP die ich über VPN habe passiert gar nichts.
Die richtige IP muss jedoch übertragen werden, da meine Nextcloud noch von vorher ein fail2ban mit Verbindung via API an cloudflare hat und bei fehlversuchen weiterhin erfolgreich die richtige IP sperrt.
Super anleitung, klappt soweit ohne Probleme.
Nun möchte ich gerne Änderungen vornehmen, hierbei scheitere ich allerdings.
Installation eines immich Docker Containers erfolgt.
https://goneuland.de/immich-mit-docker-und-traefik-installieren
Problem: Sobald die Bilder Sync startet werde ich gebannt.
Lösung whitelists.ymal hinzufügen:
https://goneuland.de/immich-mit-docker-und-traefik-installieren/#comment-3375
Wie ist das korrekte Vorgehen?
Kann ich einfach eine neue Datei unter:
/opt/containers/crowdsec/config/hub/parsers/s02-enrich/crowdsecurity/immich-whitelist.yaml
anlegen und den stack neustarten? Werden alle vorhandenen parser Datein angearbeitet und beim neustart des stacks geladen?
Muss ich unter:
/opt/containers/traefik-crowdsec-stack/config/crowdsec.env
einen Pareser Eintrag ergänzen? Dient der Eintrag nur offiziellen crodsec Parsern aus dem Hub?
Besten Dank für jeden Hinweis!
Gruß,
DocHofer
Spitzen-Anleitung – klappt auf Anhieb 🙂
Ich würde gerne wissen, wie ich diese Konfiguration anpassen muss, um eine Weiterleitung auf einen anderen Server bzw. eine andere IP-Adresse hinzubekommen. Im konkreten Fall soll auf einer Subdomain Homeassistant laufen. Der ist allerdings nicht auf dem Traefik-Server installiert. Ich weiß nicht mal die genauen Begrifflichkeiten, nach denen ich suchen muss. Forwarding, Remote Host, Load Balancer, external Address usw. Irgendwie ist es ja von allem ein bisschen.Kann mir jemand erklären, wie ich so etwas in diesen Stack integrieren kann? Es sollen noch mehrere Dienste auf anderen Adressen integriert werden, daher wäre icn über eine erklärende Anleitung, die man auch an andere Dienste anpassen kann, sehr erfreut.
Vielen lieben Dank schon mal im Voraus 👍
Grüße
Bernd
Top Anleitung, vielen Dank dafür. Ich musste aber auch unter Punkt 6.1.2 die feste IP eintrage, da es sonst Fehlereinträge in der Log Datei gab.
Trotzdem kommt immer ein Timeout beim Aufruf der Seite “ERR_CONNECTION_TIMED_OUT”
Ich benutze einen VServer bei Netcup. Die Domain weist mit A Record auf die IP vom Server. NS-Lookup löst richtig auf.
Ein curl https://traefik.TLD.de -vvv scheint zu funktionieren:
Was mir aufgefallen ist, die Datei “tls_letsencrypt.json” ist leer. Müsste da nicht was drin stehen?
Vielen Dank für die Anleitung. Ich bin mir ziemlich sicher, dass ich alles Schritt für Schritt genauso ausgeführt habe.
Ich habe nur ein seltsames Problem, ich kann mich nicht selber bannen. Bin übrigens auf Synology und verwende nur den Docker CrowdSec-bouncer. Aber bei einem Ban müsste ja zumindest der Zugriff auf die eingebundenen Docker Container verweigert werden (Forbidden). Das passiert aber nicht.
Nach einiger Auswertung der Logs (sorry bin wirklich kein IT Genie) bin ich zu dem Schluss gekommen, dass Crowdsec nur IPs aus dem Proxy Netz und vor allem vom Proxy Gateway (hier 192.31.0.1) sieht.
Wenn ich nun die Proxy Gateway IP (172.31.0.1) temporär banne, dann funktioniert alles wie erwartet. Die eingebundenen Docker Container (z.B. Nextcloud) sagen: Forbidden.
D.h. also, dass IPs irgendwie nicht durchgereicht werden bis zu Crowdsec.
Kann das jemand bestätigen oder bin ich am Holzweg?
Liegt das evtl an dem verwendeten experimentellen real-ip Plugin?
Das verhalten macht dann vor allem Probleme mit Authelia, weil ich ja keinen bypass für lokale IPs machen kann. Authelia sieht ausschließlich die Proxy Gateway IP (172.31.0.1) und nichts anderes.
Danke für die Hilfe!
WordPress config does not work with crowdsec and traefik if you use the root domain https://goneuland.de/wordpress-redis-mit-docker-compose-und-traefik-installieren/. (In my case, this is d**ko.gov.ua). If you deploy it on a subdomain, for example, wp.d**ko.gov.ua, then everything works. And for me the root domain is important 🙁
Hat das schon jemand mit duckdns.org zum Laufen gebracht? Ich habe das Ganze jetzt auf einem Debian Server (Oracle Free Tier) installiert. DuckDNS bekommt auch die richtige Adresse. Doch es können über die Subdomain traefik.SUBDOMAIN.duckdns.org keine Zertifikate erstellt werden.
Erstmal sehr schöne Anleitung leider scheitere ich daran den Firewall-Bouncer mit der API zu connecten aber wo genau es hängt bin ich mir auch nicht sicher einen API KEY habe ich erstellt und eingetragen auch die IP habe ich geändert aber wenn ich den Bouncer dann starte dann passiert das in den Logs
Bouncer log
Crowdsec Container LOG
Vielleicht hat ja wer eine Idee oder Lösung dafür
OS ist Debian 12
mit Docker version 24.0.5
Kurze Frage an die Traefik- / CrowdSec-Spezialisten (
psycho0verload vor allem):
Ich bin gerade dabei meine externen Server durch einen internen Server zu ersetzen. Idealerweise würde ich nach außen nur einen Port öffnen, worüber dann SSH und HTTPS gehen. Geht sowas? Und was müsste ich bei einer lokalen Installation beachten?
Alternativ überlege ich sonst, dass ich alles nur intern mache, sprich der Server ist nur via aktivem VPN erreichbar und gar nicht von außen. Geht dann Traefik überhaupt noch (vermutlich dann ohne Zertifikate), so dass man intern mit Subdomains statt PC-Name und Ports arbeiten kann?
Ich würde das Setup gerne möglichst einfach halten. Sprich: FRITZ!Box und der Server – mehr nicht. Keinen extra DNS-Server oder sonstwas. Wäre über eure Tipps sehr dankbar! 🙂
Vielen Dank für die Anleitung! Ich hatte eine Frage unter der WordPress-Anleitung gepostet, aber hier würde sie wahrscheinlich eher hingehören. Ich komme leider nicht an die IP vom Client heran. Weder über einen WordPress-Container noch mit dem whoami-Container. Kann man die Anleitung irgendwie so erweitern, dass die IP an dem Container durchgereicht wird?
@psycho0verload
Ich hätte da mal eine frage.
Und zwar hab ich noch 2 geräte die als Docker Stand… Laufen.
Kann ich die denn mit dem Docker Agenten mit in das Crowdsec setup mit einbinden?
Wenn ja wie müsste denn so was als Beispiel aussehen? 🙂
Wenn ich die 3 mit dem Docker Agenten auf portainer alle connecte. Kopiert sich auch der komplette crowdsec Stack auf jedes einzelne Geräte
Wünsche noch einen schönen Sonntag 🙂
Ich hoffe bei euch ist es nicht so heiß wie hier !
😅
So alles behoben alles läuft. Hat sich der Tag Urlaub für heute zur Fehlerbehebung wieder mal schön gelohnt 🙂
Das schlimme ist ich bin ein Gewohnheitstier.
So Fundamentale Umstellungen … da tu ich mich immer besonders hart 😀
sudo journalctl -u docker –since=today| tail -n34
Jul 18 13:48:18 *eyez.org systemd[1]: docker.service: Main process exited, code=exited, status=1/FAILURE Jul 18 13:48:18 *eyez.org systemd[1]: docker.service: Failed with result ‘exit-code’. Jul 18 13:48:18 *eyez.org systemd[1]: Failed to start docker.service – Docker Application Container Engine. Jul 18 13:48:20 *eyez.org systemd[1]: docker.service: Scheduled restart job, restart counter is at 3. Jul 18 13:48:20 *-eyez.org systemd[1]: Stopped docker.service – Docker Application Container Engine. Jul 18 13:48:20*-eyez.org systemd[1]: docker.service: Start request repeated too quickly. Jul 18 13:48:20 *eyez.org systemd[1]: docker.service: Failed with result ‘exit-code’. Jul 18 13:48:20 *eyez.org systemd[1]: Failed to start docker.service – Docker Application Container Engine. Jul 18 14:02:14 *eyez.org systemd[1]: Starting docker.service – Docker Application Container Engine… Jul 18 14:02:14 *eyez.org dockerd[3712]: unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character ‘/’ after object key:value pair
***unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character ‘/’ after object key:value pair**** <– das bezieht sich auf die daemon.json wo unser ipv6 bereich drin steht. Hat sich da aktuell was verändet vll von den argumenten? format? ansonsten steh ich jetzt auch auf heiße kohlen 🙁
huhu installation alles top . Geile anleitung
Nur leider hab ich jetzt ein Problem. Plötzlich nach einem neustart.
docker Engine will plötzlich nicht mehr .
loaded (/lib/systemd/system/docker.service; enabled; preset; enabled.
Active failed /result : exit-code
Bin schon am schauen aber find keine logs komischeweise o.O
vll hatte von euch schon jemand das selbe :/
mfg
Hallo zusammen,
die Anleitung läuft direkt nach dem Start super, jedoch kommt es bei mir nach ca. 2 Tagen Serverlaufzeit zu Problemen: Der Server antwortet auf allen Services nur noch mit “Forbidden”, oder Code 500. In den logs des traefik-crowdsec-stacks findet sich dann das Folgende:
Die Warnmeldung “invalid character ‘p’ after top-level value” stammt vom bouncer, und wird dort auch schon erfasst: https://github.com/fbonalair/traefik-crowdsec-bouncer/issues/41 , bisher jedoch noch ohne Lösung. Hat jemand von Euch eine Idee, und wie könnte ich weiter zur Fehlerbehebung vorgehen?