Debian trixie LXC running systemd traefik .yaml configs. Working for several CloudFlare proxies for several years. I'm having difficulty getting the syntax right to add crowdsec-bouncer-traefik-plugin middleware to a previously working dynamic.
I've read the github docs and tried their example.
I've searched the web and reviewed several Github issues and blog posts.
I changed my logs from common to json trying for an easier parse...
I've set traefik.log to DEBUG but it doesn't seem to influnce the verbosity of this specific plugin.
I implemented the github.com/Paxxs/traefik-get-real-ip plugin just to assure myself I can wire in a plugin. It works. Only used to verify plugin syntax.
The following configs are as best as I have gotten it so far. With this configuration I have a green check in the dashboard:routers but a failure on the router middleware "crowdsec@file" does not exist
Check comments in .yaml files for more relevant testing attempts.
-
I'd like to find the correct key / syntax for v3 # plugins-storage: "/etc/traefik/plugins-storage" to include in traefik.yaml. (a WAG but maybe some systemd permissions or location).
-
I'd like to learn if it's possible to increase the verbosity of logging for the crowdsec-bouncer-traefik-plugin plugin.
I hope some knowledgeable and eagle eyed DevOps admin can find my error. I've RTFM'ed and searched for days.
tree
root@traefik:/etc/traefik# tree
.
|-- acme
|-- certs
| |-- cf-acme.json
| `-- rodawio-acme.json
|-- cfenv
|-- config
| |-- [...]
| |-- gitea.rodaw.net.yaml
| |-- middlewares.yaml.nope
| |-- [...]
|-- jreadme.md
|-- plugins-storage
|-- secrets
| `-- tsig.env
|-- traefik.yaml
`-- www
Versions;
root@traefik:/var/log/traefik# uname -a
Linux traefik 7.0.14-12-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.14-12 (2026-08-11T11:05Z) x86_64 GNU/Linux
root@traefik:/var/log/traefik# traefik version
Version: 3.7.13
Codename: langres
Go version: go1.26.8
Built: 2026-09-04T12:31:42Z
OS/Arch: linux/amd64
root@traefik:/var/log/traefik#
traefik.yaml
global:
checkNewVersion: true
sendAnonymousUsage: true
api:
dashboard: true
insecure: true # safe if only bound internally; remove if exposing externally
log:
level: DEBUG
filePath: "/var/log/traefik/traefik.log"
format: json
accessLog:
# level: DEBUG # ?? crashed systemctl restart
filePath: "/var/log/traefik/access.log"
format: json
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
forwardedHeaders:
trustedIPs:
- "173.245.48.0/20"
- "103.21.244.0/22"
- "103.22.200.0/22"
- "103.31.4.0/22"
- "141.101.64.0/18"
- "108.162.192.0/18"
- "190.93.240.0/20"
- "188.114.96.0/20"
- "197.234.240.0/22"
- "198.41.128.0/17"
- "162.158.0.0/15"
- "104.16.0.0/13"
- "104.24.0.0/14"
- "172.64.0.0/13"
- "131.0.72.0/22"
traefik:
address: ":8080"
providers:
file:
directory: /etc/traefik/config
watch: true
certificatesResolvers:
cfresolver:
acme:
caServer: https://acme-v02.api.letsencrypt.org/directory
storage: /etc/traefik/certs/cf-acme.json
email: "redacted@rodaw.com"
keyType: EC256
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 4
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
rodawio:
acme:
email: "redacted@rodaw.com"
storage: /etc/traefik/certs/rodawio-acme.json
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
keyType: EC256
dnsChallenge:
provider: rfc2136
delayBeforeCheck: 4
resolvers:
- "192.168.1.254:5354"
experimental:
plugins:
# i used real-ip: to see if i could wire it all up. I did and it works. only used to pvove plugin syntax working...
real-ip:
moduleName: "github.com/Paxxs/traefik-get-real-ip"
version: "v1.0.4"
# must it be named; crowdsec-bouncer-traefik-plugin:? (update documentation) ?
# https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/issues/219
crowdsec-bouncer-traefik-plugin:
moduleName: github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
version: "v1.7.1"
# version: v1.4.6
# plugins-storage: "/etc/traefik/plugins-storage"
gitea.rodaw.net.yaml (dynamic)
# /etc/traefik/config/gitea.rodaw.net.yaml
http:
routers:
gitea:
entryPoints:
- websecure
rule: Host(`gitea.rodaw.net`)
tls:
certResolver: cfresolver
service: gitea
middlewares:
- gitea-headers
# - crowdsec
# - crowdsec-bouncer-traefik-plugin
# - crowdsec@file
services:
gitea:
loadBalancer:
passHostHeader: true
servers:
- url: "http://192.168.1.77:3000"
middlewares:
gitea-headers:
headers:
customRequestHeaders:
X-Forwarded-Proto: "https"
X-Forwarded-Host: "gitea.rodaw.net"
real-ip-test: # used to test if I can wire up a plugin. it works. - when erroring crowdsec commented out...
plugin:
real-ip:
enableLog: true
Proxy:
- proxyHeadername: X-From-Cdn
proxyHeadervalue: mf-fun
realIP: X-Forwarded-For
# # crowdsec:
# crowdsec-bouncer-traefik-plugin:
# plugin:
# crowdsec-bouncer-traefik-plugin:
# enabled: true
# logLevel: DEBUG
# crowdsecMode: live
# crowdsecLapiHost: 127.0.0.1:8085
# crowdsecLapiKey: redacted
# clientTrustedIPs:
# - "192.168.1.0/24"
# jha 9/23/26 cleanup and describe problem for posting help plea
# This configuration is the only one so far that in the dashboard/Middleware is green status with "- crowdsec" in the routers:middleware section.
# In the dashboard I still get; 'middleware "crowdsec@file" does not exist"' in the HTTP Routers which reflects the error in logs. If I could get this more verbose it would help my troubleshooting debugging.
# The router has worked for months. it errors when I try to add the traefik crowdsec bouncer middleware.
# :-) Well which is it? Is it a invalid middleware type or is it middleware does not exist? Is there a way to get a little more verbose logging?
# {
# "level": "error",
# "entryPointName": "websecure",
# "routerName": "gitea@file",
# "error": "invalid middleware \"crowdsec@file\" configuration: invalid middleware type or middleware does not exist",
# "time": "2026-09-23T11:44:13-07:00",
# "caller": "github.com/traefik/traefik/v3/pkg/server/router/router.go:265"
# }
crowdsec-bouncer-traefik-plugin:
plugin:
crowdsec:
clientTrustedIPs:
- "192.168.1.0/24"
crowdsecLapiHost: "127.0.0.1:8085"
crowdsecLapiKey: "redacted"
crowdsecMode: "live"
enabled: "true"
logLevel: "DEBUG"
# crowdsec:
# plugin:
# crowdsec-bouncer-traefik-plugin:
# enabled: true
# logLevel: DEBUG
# crowdsecMode: live
# crowdsecLapiHost: 127.0.0.1:8085
# crowdsecLapiKey: redacted
# clientTrustedIPs:
# - "192.168.1.0/24"
# crowdsec:
# plugin:
# crowdsec-bouncer-traefik-plugin:
# enabled: true
# logLevel: DEBUG
# crowdsecMode: live
# crowdsecLapiHost: "127.0.0.1:8085"
# crowdsecLapiKey: "redacted"
# clientTrustedIPs:
# - "192.168.1.0/24"
systemd service
root@traefik:~# systemctl cat traefik --no-pager
/etc/systemd/system/traefik.service
[Unit]
Description=traefik proxy
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
Restart=on-abnormal
; User and group the process will run as.
User=traefik
Group=traefik
; Always set "-root" to something safe in case it gets forgotten in the traefikfile.
ExecStart=/usr/local/bin/traefik --configfile=/etc/traefik/traefik.toml
ExecStart=/usr/local/bin/traefik --configfile=/etc/traefik/traefik.yaml
; Limit the number of file descriptors; see man systemd.exec for more limit settings.
LimitNOFILE=1048576
; Use private /tmp and /var/tmp, which are discarded after traefik stops.
PrivateTmp=true
; Use a minimal /dev (May bring additional security if switched to 'true', but it may not work on Raspberry Pi's or other devices, so it has been disabled in this dist.)
PrivateDevices=false
; Hide /home, /root, and /run/user. Nobody will steal your SSH-keys.
ProtectHome=true
; Make /usr, /boot, /etc and possibly some more folders read-only.
ProtectSystem=full
; … except /etc/ssl/traefik, because we want Letsencrypt-certificates there.
; This merely retains r/w access rights, it does not add any new. Must still be writable on the host!
; ReadWriteDirectories=/etc/traefik/acme
ReadWriteDirectories=/etc/traefik/certs
; The following additional security directives only work with systemd v229 or later.
; They further restrict privileges that can be gained by traefik. Uncomment if you like.
; Note that you may have to add capabilities required by any plugins in use.
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
/etc/systemd/system/traefik.service.d/override.conf
[Service]
Environment=CLOUDFLARE_API_KEY=redacted
Environment=CF_TRAEFIK_BOUNCER_API=redacted
ReadWriteDirectories=/etc/traefik/plugins-storage
Environment=RFC2136_NAMESERVER=192.168.1.254:5354
Environment=RFC2136_TSIG_KEYNAME=tsig-key
Environment=RFC2136_TSIG_SECRET=redacted
Environment=RFC2136_TSIG_ALGORITHM=hmac-sha256
Environment=RFC2136_ZONE=rodaw.io.
Environment="RFC2136_ZONE=rodaw.io"
Environment="LEGO_DISABLE_CNAME_SUPPORT=true"
Environment="LEGO_DNS_PROPAGATION_DISABLE_ANS=true"
root@traefik:~#