I’ve been experimenting with crowdsec but some things are still unclear to me.
My homelab consists mainly of docker containers:
- traefik reverse proxy with maxlerebourg’s crowdsec-bouncer-traefik-plugin
- crowdsec
- traefik/whoami, etc.
I have added the crowdsec labels to a traefik/whoami docker container.
services:
whoami:
image: traefik/whoami
container_name: whoami
labels:
traefik.http.routers.whoami.tls: true
traefik.http.routers.whoami.middlewares: crowdsec@file
crowdsec.enable: true
crowdsec.labels.type: nginx
networks:
traefik:
networks:
traefik:
external: true
Issue #1: loading the web page https://whoami.mydomain.com from an IP that isn’t whitelisted gives me a 403 error (forbidden), whereas I expect the page to load.
Issue #2: loading this other test webpage https://whoami.mydomain.com/crowdsec-test-NtktlJHV4TfBSK3wvlhiOBnl also gives me a 403 error (forbidden). That strange URL is a crowdsec health check I learned about here (nice!).
I expected both alert types to be triggered, whereas the appsec alert isn’t triggered.
$ docker exec crowdsec cscli alerts list -s crowdsecurity/appsec-generic-test
No active alerts
$ docker exec crowdsec cscli alerts list -s crowdsecurity/http-generic-test
+------+------------------+---------------------------------+---------+---------------+-----------+----------------------+
| ID | value | reason | country | as | decisions | created_at |
+------+------------------+---------------------------------+---------+---------------+-----------+----------------------+
| 1145 | Ip:123.123.12.34 | crowdsecurity/http-generic-test | ES | 8560 IONOS SE | | 2025-12-30T17:32:43Z |
Crowdsec bouncer plugin in traefik.yml (traefik’s static configuration file)
# Crowdsec bouncer plugin
experimental:
plugins:
bouncer:
moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
version: v1.4.6
Crowdsec bouncer middleware in config.yml(traefik’s dynamic configuration file)
middlewares:
# Crowdsec bouncer middleware
crowdsec:
plugin:
bouncer:
enabled: true
logLevel: debug
logFilePath: /var/log/traefik/bouncer.log
crowdsecMode: appsec
crowdsecAppsecEnabled: true
crowdsecAppsecHost: crowdsec:7422
CrowdsecAppsecTlsInsecureVerify: true
crowdsecLapiKeyFile: /crowdsec_lapi_key.txt
crowdsecLapiHost: crowdsec:8080
crowdsecLapiScheme: http
crowdsecLapiTLSInsecureVerify: true
clientTrustedIPs:
- 10.0.0.0/8
- 172.16.0.0/12
Crowdsec’s compose.yml
services:
crowdsec:
image: crowdsecurity/crowdsec
container_name: crowdsec
hostname: crowdsec
restart: unless-stopped
environment:
TZ: ${TZ}
UID: 1000
GID: 1000
COLLECTIONS: >-
crowdsecurity/traefik
LePresidente/authelia
Jgigantino31/ntfy
crowdsecurity/http-cve
crowdsecurity/http-dos
crowdsecurity/base-http-scenarios
crowdsecurity/appsec-virtual-patching
crowdsecurity/appsec-generic-rules
CUSTOM_HOSTNAME: crowdsec
BOUNCER_KEY_TRAEFIK: ${BOUNCER_KEY_TRAEFIK}
DOCKER_HOST: tcp://docker-socket-proxy:2375
expose:
- 8080 # http api for bouncers
- 7422 # Appsec WAF endpoint
- 6060 # Metrics endpoint for Prometheus
volumes:
- ./config:/etc/crowdsec/
- ./db:/var/lib/crowdsec/data/
- ../traefik/logs/access.log:/var/log/traefik/access.log:ro
labels:
traefik.enable: false
networks:
docker-socket-proxy:
networks:
docker-socket-proxy:
external: true
Acquisition files:
traefik.yaml
source: file
filename: /var/log/traefik/access.log
labels:
type: traefik
appsec.yaml
appsec_configs:
- crowdsecurity/appsec-default # In-band virtual patching
- crowdsecurity/crs # Out-of-band detection based on ModSec CRS
labels:
type: appsec
listen_addr: 127.0.0.1:7422
source: appsec
name: appsec
docker.yaml
source: docker
use_container_labels: true
I guess this is just the beginning of a descent into a rabbit hole… For now I’d be content to load the web page successfully rather than getting that pesky 403 error…
Thank you!