Pls help with my noob config

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!

Ok, I finally figured out what was wrong: the remediation component couldn’t reach the appsec component because the appsec component was listening only on localhost.
I found this boolean variable called crowdsecAppsecUnreachableBlock in the traefik bouncer middleware. By default it’s set to true. Setting it to false allows requests when the appsec component is unreachable. That’s how I knew the appsec component wasn’t reachable by the bouncer.
docker exec traefik wget crowdsec:7422 confirmed it by giving me a Connection refused error.
So I rushed to the appsec acquisition file (appsec.yaml), replaced 127.0.0.1 with 0.0.0.0 in this line of the appsec acquisition file (appsec.yaml) and restarted crowdsec.
Finally, I could successfully access my website from an external IP instead of getting that pesky 403 forbidden error.