Photo by Phil Hearing / Unsplash

Protect Pangolin With CrowdSec and Traefik (Complete Setup Guide)

docker Mar 6, 2026

This guide provides an alternative approach to the community guide by using Traefik access logs instead of Syslog or Journalctl. This method allows CrowdSec to analyze requests directly from Traefikโ€™s access log output, which can simplify the setup in containerized environments and avoid relying on host-level logging systems.

1. Make sure Traefik is writing to access.log file

  1. Open your pangolin's traefik's configuration file, for example mine is /docker/pangolin/traefik/traefik.yml
  2. Add this block anywhere:
    accessLog:
      filePath: "/var/log/traefik/access.log"
      bufferingSize: 100
      format: common
    
  3. The block is a first level block, so if you put it near the log block it will look like this:
    log:
      level: INFO
      format: common
    
    accessLog:
      filePath: "/var/log/traefik/access.log"
      bufferingSize: 100
      format: common
    
  4. Create the log folder on the host, for example:
    sudo mkdir /docker/pangolin/traefik/logs
  5. Then map the folder in Traefik compose:
    services:
      traefik:
        volumes:
          - /docker/pangolin/traefik/logs:/var/log/traefik
    
  6. Redeploy with sudo docker compose down and sudo docker compose up so the newly mapped folder work in Traefik
  7. Verify logs exist with sudo docker exec -it traefik ls /var/log/traefik it should return access.log
  8. You can see the logs with sudo docker exec -it traefik tail -f /var/log/traefik/access.log

2. Install CrowdSec

  1. Create the neccessary folders (data and config) for CrowdSec, for example
    sudo mkdir -p /docker/pangolin/crowdsec/{data,config}
  2. Add CrowdSec to your Pangolin compose stack, do not forget to map the Traefik access.log location:
    services:
      crowdsec:
        image: crowdsecurity/crowdsec:latest-debian
        container_name: crowdsec
        restart: unless-stopped
        environment:
          COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules crowdsecurity/linux crowdsecurity/iptables
          ACQUIRE_FILES: /var/log/traefik/access.log
        volumes:
          - /docker/pangolin/crowdsec/data:/var/lib/crowdsec/data
          - /docker/pangolin/crowdsec/config:/etc/crowdsec
          - /docker/pangolin/traefik/logs:/var/log/traefik:ro # this is the trafik log location
    
  3. Run it using sudo docker compose down and sudo docker compose up
๐Ÿ’ก
At this stage, CrowdSec does not see Traefik's traffic just yet. We need it running so it generate the necessary files.

3. Allow CrowdSec to acquire and parse Traefik log file

  1. Stop CrowdSec container
  2. Edit the acquis.yaml file in /docker/pangolin/crowdsec/acquis.yaml
  3. Remove (or comment out) everything then add this:
    filenames:
      - /var/log/traefik/access.log
    labels:
      type: traefik
    
  4. Restart Traefik container
  5. Check if the metrics works:
    sudo docker exec -it crowdsec cscli metrics
  6. You should see something like this:
    Acquisition Metrics
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚ Source                      โ”‚ Lines    โ”‚ Parsed   โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ /var/log/traefik/access.log โ”‚ 1500     โ”‚ 1500     โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    

4. Connect Traefik with CrowdSec

  1. Stop Traefik container
  2. Add CrowdSec bouncer to Traefik static file in /docker/pangolin/traefik/traefik.yml:
    experimental:
      plugins:
        badger:
          moduleName: github.com/fosrl/badger
          version: v1.3.1
        crowdsec-bouncer:
          moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
          version: v1.5.1 # <<<<< latest version when I wrote this guide
    
  3. Also add CrowdSec middleware to the static file in the websecure entrypoint:
    entryPoints:
      web:
        address: ':80'
      websecure:
        address: ':443'
        transport:
          respondingTimeouts:
            readTimeout: 30m
        http:
          tls:
            certResolver: cloudflare
          middlewares: # <<<<< add here
            - crowdsec@file
    
  4. Get a CrowdSec api key for Traefik by running this:
    sudo docker exec -it crowdsec cscli bouncers add traefik
  5. Add CrowdSec bouncer to Traefik's dynamic config, mine is in /docker/pangolin/traefik/rules/dynamic_config.yml:
    http:
      middlewares:
        crowdsec:
          plugin:
            crowdsec-bouncer:
              enabled: true
              crowdsecLapiKey: YOUR_API_KEY
              crowdsecLapiHost: crowdsec:8080
    
  6. Restart them all with sudo docker compose down and sudo docker compose up

5. Testing time!

  1. Test bans with sudo docker exec -it crowdsec cscli decisions list
  2. You will start seeing IP bans like this:
    โ•ญโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
    โ”‚ ID โ”‚  Source  โ”‚    Scope:Value    โ”‚                   Reason                   โ”‚ Action โ”‚ Country โ”‚                AS                โ”‚ Events โ”‚ expiration โ”‚ Alert ID โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ 6  โ”‚ crowdsec โ”‚ Ip:4.204.200.32   โ”‚ crowdsecurity/http-probing                 โ”‚ ban    โ”‚ CA      โ”‚ 8075 MICROSOFT-CORP-MSN-AS-BLOCK โ”‚ 11     โ”‚ 3h59m46s   โ”‚ 6        โ”‚
    โ”‚ 5  โ”‚ crowdsec โ”‚ Ip:136.0.213.103  โ”‚ crowdsecurity/http-probing                 โ”‚ ban    โ”‚ US      โ”‚                                  โ”‚ 11     โ”‚ 3h58m48s   โ”‚ 5        โ”‚
    โ”‚ 1  โ”‚ crowdsec โ”‚ Ip:151.145.54.165 โ”‚ crowdsecurity/http-admin-interface-probing โ”‚ ban    โ”‚ CA      โ”‚ 31898 ORACLE-BMC-31898           โ”‚ 3      โ”‚ 3h19m33s   โ”‚ 1        โ”‚
    โ•ฐโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
    
  3. Try to add your own IP from access, first get your own IP in sites like https://whatismyipaddress.com/
  4. Add your IP to temporary ban:
    sudo docker exec crowdsec cscli decisions add --ip YOUR_IP_HERE -d 5m
  5. You can check that your IP have been added to the ban list with sudo docker exec -it crowdsec cscli decisions list, it should look like this:
    โ•ญโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
    โ”‚  ID โ”‚  Source  โ”‚    Scope:Value    โ”‚                   Reason                   โ”‚ Action โ”‚ Country โ”‚                AS                โ”‚ Events โ”‚ expiration โ”‚ Alert ID โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ 182 โ”‚ cscli    โ”‚ Ip:YOUR_IP_HERE   โ”‚ manual 'ban' from 'localhost'              โ”‚ ban    โ”‚         โ”‚                                  โ”‚ 1      โ”‚ 4m54s      โ”‚ 182      โ”‚
    โ•ฐโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
    
  6. Now your ip is banned for the next 5 minutes. If you open a private browser and try to access any of your subdomain you will get a 403 error.

via GIPHY

Tags