CrowdSec: Collaborative Intrusion Prevention for Your Self-Hosted Services
The moment you expose a service to the internet, bots start knocking. SSH brute force attempts, WordPress login hammering, vulnerability scanners probing every known CVE. If you're self-hosting with any public-facing services, you need something watching the door.
CrowdSec is an open-source intrusion prevention system that reads your logs, detects attacks, and blocks malicious IPs — but with a twist. It shares threat intelligence across its entire user community. When someone attacks another CrowdSec user, your instance learns about it and blocks the attacker preemptively.
CrowdSec vs Fail2ban
Fail2ban has been the go-to for log-based intrusion prevention for over 20 years. CrowdSec is its modern replacement. Here's how they compare:
| Feature | Fail2ban | CrowdSec |
|---|---|---|
| Language | Python | Go |
| Architecture | Monolithic | Agent + Bouncer (modular) |
| Log parsing | Regex (failregex) | Grok patterns + YAML scenarios |
| Crowd intelligence | No | Yes (shared blocklists) |
| Console/dashboard | No | Web console (free) |
| API | No | REST API |
| Performance | Single-threaded | Multi-threaded |
| Memory usage | Low | Low-moderate |
| Ban mechanism | iptables/firewalld direct | Bouncers (firewall, reverse proxy, etc.) |
| Community scenarios | Regex patterns | Curated Hub (collections, parsers, scenarios) |
| IPv6 support | Yes | Yes |
| Appeal system | No | Yes (false positive reporting) |
The fundamental architecture difference: Fail2ban both detects and blocks in one process. CrowdSec splits these into an agent (reads logs, makes decisions) and bouncers (enforce those decisions at the firewall, reverse proxy, or application level). This separation means you can run the agent on one machine and have bouncers on multiple machines sharing the same decisions.
How CrowdSec Works
- Log Analysis — The CrowdSec agent tails your log files (syslog, Nginx, Traefik, SSH, etc.) and parses them using community-maintained parsers
- Scenario Matching — Parsed events are evaluated against scenarios (e.g., "5 failed SSH logins in 30 seconds from the same IP")
- Decision — When a scenario triggers, the agent creates a decision (ban, captcha, throttle) for a configurable duration
- Enforcement — Bouncers poll the agent's API and enforce decisions (drop packets, return 403, show captcha)
- Sharing — Anonymized attack signals are shared with the CrowdSec network, and you receive a curated community blocklist in return
Installation
Agent
# Debian/Ubuntu
curl -s https://install.crowdsec.net | sudo sh
sudo apt install crowdsec
# Fedora
curl -s https://install.crowdsec.net | sudo sh
sudo dnf install crowdsec
# Docker
docker run -d \
--name crowdsec \
-v /var/log:/var/log:ro \
-v ./crowdsec-db:/var/lib/crowdsec/data \
-v ./crowdsec-config:/etc/crowdsec \
-p 8080:8080 \
crowdsecurity/crowdsec
Install collections for your services
CrowdSec's Hub has pre-built collections for common services:
# SSH protection
sudo cscli collections install crowdsecurity/sshd
# Nginx
sudo cscli collections install crowdsecurity/nginx
# Traefik
sudo cscli collections install crowdsecurity/traefik
# Linux base (syslog, PAM)
sudo cscli collections install crowdsecurity/linux
# List what's installed
sudo cscli collections list
Firewall Bouncer
The most common bouncer blocks IPs at the firewall level:
# Install
sudo apt install crowdsec-firewall-bouncer-iptables
# or for nftables:
sudo apt install crowdsec-firewall-bouncer-nftables
The bouncer automatically registers with the local agent and starts enforcing decisions.
Docker Compose Setup
For a typical Docker homelab with Traefik:
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
environment:
COLLECTIONS: >-
crowdsecurity/traefik
crowdsecurity/http-cve
crowdsecurity/linux
volumes:
- ./crowdsec-config:/etc/crowdsec
- ./crowdsec-db:/var/lib/crowdsec/data
- /var/log:/var/log:ro
# Share Traefik's access logs
- traefik-logs:/var/log/traefik:ro
restart: unless-stopped
traefik-bouncer:
image: fbonalair/traefik-crowdsec-bouncer:latest
environment:
CROWDSEC_BOUNCER_API_KEY: your-bouncer-api-key
CROWDSEC_AGENT_HOST: crowdsec:8080
restart: unless-stopped
Generate the bouncer API key:
docker exec crowdsec cscli bouncers add traefik-bouncer
Then configure Traefik to use the bouncer as middleware.
Useful Commands
# See current decisions (bans)
sudo cscli decisions list
# See what's been detected
sudo cscli alerts list
# Manually ban an IP
sudo cscli decisions add --ip 1.2.3.4 --duration 24h --reason "manual ban"
# Remove a ban
sudo cscli decisions delete --ip 1.2.3.4
# Check what scenarios are loaded
sudo cscli scenarios list
# View metrics
sudo cscli metrics
# Update Hub components
sudo cscli hub update
sudo cscli hub upgrade
The Community Blocklist
This is CrowdSec's main differentiator. When your instance detects an attack, it shares an anonymized signal (attacking IP + scenario triggered) with the CrowdSec network. In return, you receive a curated blocklist of IPs that have attacked other CrowdSec users.
The result: your server proactively blocks known attackers before they even reach your services. It's like having a neighborhood watch for the internet.
Privacy note: CrowdSec only shares the attacking IP address and the type of attack detected. Your logs, your server details, and your traffic are never sent.
Console Dashboard
CrowdSec provides a free web console at app.crowdsec.net where you can:
- View all your CrowdSec instances in one place
- See attack statistics and trends
- Manage blocklist subscriptions
- Monitor bouncer status
- Get alerts on unusual activity
Enrollment is optional but useful for monitoring multiple machines:
sudo cscli console enroll your-enrollment-key
Custom Scenarios
Beyond the Hub's pre-built scenarios, you can write your own. Scenarios are YAML files that describe attack patterns:
# /etc/crowdsec/scenarios/my-app-bruteforce.yaml
type: leaky
name: my-company/my-app-bruteforce
description: "Detect brute force on my custom app"
filter: "evt.Meta.log_type == 'my-app' && evt.Meta.http_status == '401'"
groupby: evt.Meta.source_ip
capacity: 5
leakspeed: 30s
blackhole: 5m
labels:
type: bruteforce
This triggers when an IP generates 5 HTTP 401 responses within 30 seconds — a classic brute force pattern.
Integration with Reverse Proxies
Traefik
Use the Traefik bouncer as forward-auth middleware. Blocked IPs get a 403 before reaching any backend service.
Nginx
Use the crowdsec-openresty-bouncer or the Lua bouncer. It integrates directly into Nginx's request processing.
Caddy
The Caddy bouncer plugin adds CrowdSec checking at the web server level.
Cloudflare
CrowdSec has a Cloudflare bouncer that pushes decisions to Cloudflare's firewall rules, blocking attackers at the CDN edge before they even reach your server.
Common Mistakes
Not monitoring alerts — CrowdSec is fire-and-forget for blocking, but you should periodically review alerts to understand your threat landscape.
Banning your own IP — Add your home IP and local subnets to the whitelist at
/etc/crowdsec/parsers/s02-enrich/whitelist.yaml.Log format mismatches — If CrowdSec can't parse your logs, it can't detect attacks. Check
cscli metricsto verify logs are being processed.Forgetting to restart after config changes —
sudo systemctl restart crowdsecafter modifying scenarios or parsers.
The Bottom Line
CrowdSec is what Fail2ban would be if it were designed today. The modular architecture, community threat sharing, and pre-built scenario Hub make it significantly easier to deploy and maintain. The crowd-sourced blocklist alone is worth the setup — proactive blocking of known attackers is something Fail2ban simply can't do.
For any self-hosted setup with public-facing services, CrowdSec should be one of the first things you install. It's free, lightweight, and the community blocklist gets more valuable as more people use it. Combined with a reverse proxy and proper firewall rules, it significantly reduces your attack surface.