The Problem
Organizations need a participative way to detect and block malicious IP addresses across diverse environments. CrowdSec provides crowdsourced threat intelligence, allowing each node to contribute observed bad behaviour and receive community blocklists in real time.
What This Does
CrowdSec is an open‑source security engine that functions as an IDS/IPS and WAF. It ingests log sources and HTTP requests, evaluates detection rules, and triggers remediation through bouncers that firewall, reverse‑proxy, or container runtimes can consume. The core detection logic lives in pkg/acquisition/modules/, where parsers and buckets collect and score events. Remediation components such as bouncers are defined in cmd/crowdsec-cli/clibouncer/. The Security Engine’s rule evaluation is orchestrated from cmd/crowdsec/serve.go:307 (Serve) and cmd/crowdsec/main.go:212 (main), which start the API server, metric provider, and output routines. Configuration is driven by YAML files under config/ and parsed by pkg/csconfig/. The community blocklist is fetched via the central API and merged into the in‑memory allow/deny state.
How It Is Wired
Execution starts at cmd/crowdsec/main.go:212 (main), which reaches 399 internal functions and is called from nothing else in the repo. From main the flow proceeds to Serve (cmd/crowdsec/serve.go:307), which loads configuration, initialises the API server (apiserver.go), and spawns metric, bucket, and output routines. The internal call graph shows Alert is invoked from 334 places, New from 229, Context from 209, and Run from 103 – these are the functions with the widest blast radius. Traced paths to external effects are short: main → Serve → Load reads files via os.ReadFile; Execute → LoadConfig → Init → loadConfig opens config files with os.Open; run → getLineCountForFile also uses os.Open. The repository touches the filesystem in 84 functions, a database in 4, makes 3 outbound network calls, performs 3 cryptographic operations, and runs 1 external command. The module graph contains 1 internal module with no circular dependencies, so changes to a top‑level function ripple broadly but without hidden cycles.
How To Use It
- Setup: Clone the repo verbatim:
git clone https://github.com/moses-y/crowdsec. Build with the provided Makefiles (cmd/crowdsec/Makefile,cmd/crowdsec-cli/Makefile) or use Docker:docker build -t crowdsec -f build/docker/Dockerfile .. - Configuration: Primary config lives in
config/. Environment variables and secrets are referenced in workflow files under.github/workflows/. Ensurego.moddependencies are up‑to‑date (go mod tidy). - Running it: Start the daemon with
go run ./cmd/crowdsecor, after building,./crowdsec. For Windows services useExecutefromcmd/crowdsec/win_service.go:27. The CLI entryadd(cmd/crowdsec-cli/cliallowlists/allowlists.go:454) can register allow‑list entries.
Real‑World Use
A security team deploys CrowdSec on a fleet of web servers. Logs from nginx are tailed by the file acquisition module (pkg/acquisition/modules/file/). The Security Engine flags repeated failed login attempts, creates a bucket, and after the threshold is met, emits an alert. The bouncer (cmd/crowdsec-cli/clibouncer/) automatically updates the host’s iptables or Nginx deny directive, blocking the offending IP. The same alert also pushes the IP to the community blocklist, benefiting all other participants.
Code Health & Issues
Measured static‑analysis findings (120 total)
- High – cognitive load: deep nesting x56 in
cmd/crowdsec-cli/clisetup/setup/detect_test.go,pkg/acquisition/config_test.go,pkg/acquisition/modules/file/file_test.go(max indentation depth 9). - High – duplicated code blocks: 1359 repeated 6‑line patterns across 337 files, notably in
cmd/crowdsec/api.go,cmd/crowdsec/win_service.go,cmd/crowdsec/parse.go,cmd/crowdsec/pour.go. - High – oversized files: 1393‑line files
pkg/database/ent/client.go,pkg/database/ent/mutation.go,pkg/exprhelpers/exprlib_test.go. - Medium – other: 103 medium‑severity issues (not listed individually here).
- Low – 4 issues (not listed individually).
Code‑health audit (5 findings)
- MEDIUM – Declare least‑privilege permissions for GITHUB_TOKEN in
.github/workflows/docker-tests.yml(no permissions declared; 2 workflows reference secrets). - MEDIUM – Pin container base image by digest in
build/docker/Dockerfile(docker.io/golang:1.25-alpine3.21,docker.io/alpine:3.21). - MEDIUM – Gate pull requests on a dependency vulnerability scan (no scan in CI).
- MEDIUM – Add a non‑root USER to the Docker image (
build/docker/Dockerfileruns as root). - LOW – Set
timeout-minuteson workflow jobs in.github/workflows/ci_release-drafter.yml(3 jobs have no timeout).
The Bottom Line
CrowdSec delivers a functional, crowdsourced security engine with solid Docker and Kubernetes integration, but the codebase shows signs of cognitive‑load hotspots, duplicated logic, and oversized files that hinder maintainability. The CI hygiene gaps (missing dependency scans, root‑as‑default container user, untokenled GITHUB_TOKEN) are easy to remediate. It is well‑suited for teams that want participative IP blocking and are comfortable contributing to, and consuming from, the community blocklist.