Your CrowdSec is running, connected — and completely blind
The console flagged one of my Security Engines: “no activity — hasn’t pushed alerts in 48 hours.” Odd, because everything else looked fine. The container was healthy, cscli lapi status was happy, it was enrolled in the console, and the reverse-proxy bouncer was pulling decisions. Green across the board.
It was also reading exactly zero logs. Had been for weeks.
“Connected” is not “working”
CrowdSec has a few moving parts, and they can all be healthy while the one that matters does nothing:
- LAPI — the local API.
cscli lapi status→ fine. - CAPI / console — the central API and web console.
cscli capi status→ enrolled, sharing signals. Fine. - Bouncers — the things that enforce decisions (your reverse proxy, a firewall).
cscli bouncers list→ connected, pulling. Fine. - Acquisition — the part that actually reads your logs so it can detect anything. This is the one that was dead.
With a valid CAPI enrollment and a working bouncer, CrowdSec will happily pull the community blocklist and enforce it. That looks like protection. But if acquisition is broken, it does no detection of its own — nothing about attacks against your services. It’s a blocklist enforcer wearing an IDS costume.
How to tell in ten seconds
cscli metrics
Look at the Acquisition table. The number that matters is Lines read. Mine:
+--------+------------+--------------+
| Source | Lines read | Lines parsed |
+--------+------------+--------------+
+--------+------------+--------------+
Empty. No sources, no lines. If that table is empty or “Lines read” is 0, CrowdSec is blind — full stop. Corroborate with:
cscli alerts list # any detections, ever?
alerts list returning “No active alerts” on a public-facing box that’s been up for weeks is the other giveaway. A real IDS on the internet sees scanner noise within hours, not never.
The smoking gun
$ cat /etc/crowdsec/acquis.yaml
{"source": "file", "filename": "/does/not/exist", "labels": {"type": "syslog"}}
/does/not/exist. That is the CrowdSec container image’s do-nothing placeholder — what it ships when nothing has told it which logs to read. The log spelled it out too:
level=warning msg="No matching files for pattern /does/not/exist"
No one had ever wired up a log source. It had been “protecting” nothing since day one.
Fixing it: feed it your reverse proxy
CrowdSec detects by parsing logs, so give it the richest web source you have — the reverse proxy’s access log. With Traefik, three pieces:
1. Make Traefik write a JSON access log to a file (shared with the CrowdSec container via a volume):
# traefik command
- "--accesslog=true"
- "--accesslog.filepath=/var/log/traefik/access.log"
- "--accesslog.format=json"
2. Point CrowdSec at it — replace the placeholder acquis.yaml:
filenames:
- /var/log/traefik/access.log
labels:
type: traefik
3. Install the parser + scenarios so it knows what to do with those lines:
cscli collections install crowdsecurity/traefik
# pulls base-http-scenarios + http-cve as dependencies
Restart, generate a little traffic, and check the same table:
| Source | Lines read | Lines parsed |
| file:/var/log/traefik/access.log | 122 | 122 |
122 read, 122 parsed. Now it’s actually looking.
The takeaway
A green dashboard tells you CrowdSec is up, not that it’s watching anything. The single source of truth is cscli metrics → Lines read. Go run it on your own box right now — you might be surprised what your “protected” server has been quietly ignoring.