Traefik stops working with crowdsec bouncer - invalid character 'i' in lliteral true

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.

So the error:

time="07-01-2024 19:14:17" level=error msg="UnmarshalJSON : invalid character 'i' in literal true (expecting 'r')" line="time=\"2024-01-07T19:14:17Z\" level=error msg=\"Error while starting server: accept tcp [::]:80: use of closed network connection\" entryPointName=web

Is because the log line gained from traefik was not a CLF format or a JSON log line. So it first tries to parse using the CLF format, if that fails it then tries JSON to which if it isnt JSON it will log it. So best to check your logs as it seems it logging invalid formats.

So if they all exists on the docker network you dont need to map ports to the host as if you dont firewall them anyone can access them. However, I would suggest dropping fbonalair container in favour of the traefik plugin there a few pros here EG no need to run another container to enforce decisions.

The access.log seems to be in CLF format. Maybe it’s complaining about traefik.log (error log of the traefik server) ?

About port mapping … So if I have let’s say 4 containers using all the same port 8080, then I can just refer to http://containername:8080 without having to remap those ports ? It doesn’t create a traffic conflict (multiple ports being open on the same host) ?

About the plugin it seems interesting, but how much work is it really to get starteed with some basic configuration ? Is it mainly a matter of issueing a self-signed CA+Key+Cert or running examples/tls-auth/gencerts.sh (I see in the documentation that this script must be in the same directory as the inputs for the PKI creation).

By the way @iiAmLoz , I finally managed to try the traefik crowdsec plugin instead of the additional bouncer container.

Unfortunately it didn’t work for me, maybe some configuration issue is at play …

Here is the issue: [BUG] Not working - Probably configuration issue ? · Issue #136 · maxlerebourg/crowdsec-bouncer-traefik-plugin · GitHub