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 metricsLines read. Go run it on your own box right now — you might be surprised what your “protected” server has been quietly ignoring.