I just wanted to give crowdsec a try, to see how it could help improve security for my homelab services.
Unfortunately however, after enabling it, traefik would stop working completely on the sites that use the bouncer.
It is possible it’s some networking / ports issues within docker, i.e. I might mix up ports of crowdsec and bouncer-traefik (why does everyone use port 8080 ?), but it could be something else entirely.
I enabled the API key for bouncer-traefik so that should be OK.
log
crowdsec/compose.yml
version: '3.8'
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
environment:
GID: "${GID-1000}"
COLLECTIONS: "crowdsecurity/linux crowdsecurity/traefik"
volumes:
# - ~/config/acquis.yaml:/etc/crowdsec/acquis.yaml # ~/config/ is already mounted to /etc/crowdsec - Not needed
- ~/data/crowdsec:/var/lib/crowdsec/data/
- ~/config/crowdsec:/etc/crowdsec/
- ~/log/traefik:/var/log/traefik/:ro
networks:
- traefik
ports:
- 8083:8080
depends_on:
- traefik
security_opt:
- no-new-privileges:true
restart: unless-stopped
bouncer-traefik:
image: docker.io/fbonalair/traefik-crowdsec-bouncer:latest
container_name: bouncer-traefik
environment:
PORT: 8082
CROWDSEC_BOUNCER_API_KEY: XXXXXXXXXXXXXXXXXXXXXX
CROWDSEC_AGENT_HOST: crowdsec:8083
networks:
- traefik
ports:
- 8082:8080
depends_on:
- crowdsec
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
traefik:
external: true
traefik/compose.yml
version: '3.9'
networks:
traefik:
external: true
services:
traefik:
image: traefik:latest
hostname: traefik.XXXXXXXX
domainname: XXXXXXXX
restart: unless-stopped
container_name: traefik
ports:
- 80:80
- 443:443
# - 8080:8080
# - 8443:8443
networks:
- traefik
volumes:
- /run/user/1001/podman/podman.sock:/var/run/docker.sock:ro
- ~/data/traefik/letsencrypt:/letsencrypt
- ~/config/traefik:/config
- ~/certificates/traefik:/certificates
- ~/log/traefik:/log
command:
## Logging
# Server Log
# - "--log.level=DEBUG"
- "--log.level=INFO"
- "--log.filePath=/log/traefik.log"
# Error Log
- "--accesslog=true"
- "--accesslog.filePath=/log/access.log"
## Dashboard & API
- "--api"
- "--api.insecure=false" # production = false , development = true
- "--api.dashboard=true"
## EntryPoints
# Unsecure Connection - Redirect to Secure
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entryPoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
# Secure Connection
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
- "--entrypoints.websecure.http.tls.certresolver=letsencrypt"
## Letsencrypt Configuration
# - "--certificatesresolvers.lets-encrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" # For testing only
- "--certificatesresolvers.letsencrypt.acme.caserver=https://acme-v02.api.letsencrypt.org/directory" # Production - Rated limited !!!
- "--certificatesresolvers.letsencrypt.acme.email=XXXXXXXXXX"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" # Not sure if needed
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=websecure" # Not sure if needed
## Docker / Podman Intergration
- "--providers.docker=true"
- "--providers.docker.exposedByDefault=false"
- "--providers.docker.watch=false"
- "--providers.docker.swarmMode=false"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
# - "--providers.docker.network=proxy" # From Tutorial
# - "--providers.docker.exposedByDefault=false" # From Tutorial
# Crowdsec Integration
#- "--providers.file=true"
#- "--providers.file.filename=/config/config.yml"
## Other
# ...
- "--serversTransport.insecureSkipVerify=true"
# No Telemetry
- "--global.sendAnonymousUsage=false"
labels:
# Enable Traefik
- traefik.enable=true
# Dashboard
# - "traefik.http.routers.dashboard.entrypoint=websecure" # !! If enabled, this line causes a 404 page not found for the dashboard !!
# - "traefik.http.routers.dashboard.rule=Host(`traefik.XXXXXXXX`)"
- "traefik.http.routers.dashboard.rule=Host(`traefik.XXXXXXXX`) && PathPrefix(`/api` , `/dashboard`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=authtraefik , crowdsec-bouncer@docker"
# Authentication for Dashboard access
# - "traefik.http.middlewares.authtraefik.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/"
- "traefik.http.middlewares.authtraefik.basicauth.usersfile=/config/users"
# Use crowdsec
#- "traefik.http.middlewares.crowdsec-bouncer.forwardauth=http://bouncer-traefik:8080/api/v1/forwardAuth"
#- "traefik.http.middlewares.crowdsec-bouncer.trustForwardHeader=true"
# Create bouncer middleware
- "traefik.http.middlewares.crowdsec-bouncer.forwardauth.address=http://bouncer-traefik:8082/api/v1/forwardAuth"
- "traefik.http.middlewares.crowdsec-bouncer.forwardauth.trustForwardHeader=true"
Any idea what is going on ?
Switching between port 8082 and 8083 for “traefik.http.middlewares.crowdsec-bouncer.forwardauth.address” can just result in a “Forbidden” error message.
Authentication to traefik dashboard requires already a simple authentication (like htpasswd) username+password. That’s what’s indicated in the line traefik.http.routers.dashboard.middlewares=authtraefik , crowdsec-bouncer@docker
.