Your self-hosted server is exposed to the internet. Bots, brute-forcers, and scanners hit it constantly. Fail2ban helps, but it only learns from your own logs. What if you could tap into threat intelligence from thousands of other servers?
That’s CrowdSec. It’s like a community-powered immune system for your infrastructure.
What Is CrowdSec?
CrowdSec is an open-source security engine that:
- Parses your logs (Nginx, SSH, Traefik, WordPress, etc.)
- Detects attack patterns using behavioral scenarios
- Blocks attackers via bouncers (firewall rules, Nginx deny, Cloudflare API)
- Shares threat intel — when you block an IP, the community benefits and vice versa
Think of it as Fail2ban + community blocklists + modern architecture.
CrowdSec vs Fail2ban
| Feature | CrowdSec | Fail2ban |
|---|---|---|
| Log parsing | ✅ | ✅ |
| Community blocklists | ✅ | ❌ |
| Dashboard | ✅ (web console) | ❌ |
| API-driven | ✅ | ❌ |
| Multiple bouncer types | ✅ (firewall, Nginx, Cloudflare) | Limited |
| Performance | Go-based, lightweight | Python, heavier |
| Configuration | YAML scenarios | Regex filters |
Prerequisites
- A Linux server (Ubuntu 22.04+, Debian 12+)
- Docker and Docker Compose installed
- A public-facing service generating logs (Nginx, Traefik, SSH)
- Free CrowdSec account (for the console dashboard)
Step 1: Install CrowdSec with Docker
Create a directory for the stack:
mkdir -p ~/crowdsec && cd ~/crowdsec
Create docker-compose.yml:
version: '3.8'
services:
crowdsec:
image: crowdsecurity/crowdsec:latest
container_name: crowdsec
restart: always
environment:
COLLECTIONS: "crowdsecurity/linux crowdsecurity/nginx crowdsecurity/sshd"
GID: "${GID-1000}"
volumes:
- ./config:/etc/crowdsec
- ./data:/var/lib/crowdsec/data
- /var/log:/var/log:ro
- /var/log/nginx:/var/log/nginx:ro
ports:
- "127.0.0.1:8080:8080" # API (local only)
networks:
- crowdsec
networks:
crowdsec:
driver: bridge
Deploy it:
docker compose up -d
CrowdSec starts parsing logs immediately. The COLLECTIONS environment variable installs detection scenarios for Linux, Nginx, and SSH automatically.
Step 2: Verify It’s Working
Check CrowdSec status:
docker exec crowdsec cscli metrics
You’ll see parsers and scenarios processing your logs in real-time:
Check active decisions (blocked IPs):
docker exec crowdsec cscli decisions list
Step 3: Install a Bouncer
CrowdSec detects attacks but needs a bouncer to enforce blocks. The firewall bouncer is the most effective — it blocks at the network level before requests even reach your apps.
Firewall Bouncer (Recommended)
Generate an API key for the bouncer:
docker exec crowdsec cscli bouncers add firewall-bouncer
Save the API key that’s printed. Then install the bouncer on the host (not in Docker):
curl -s https://install.crowdsec.net | sudo bash
sudo apt install crowdsec-firewall-bouncer-iptables
Edit /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml:
api_url: http://127.0.0.1:8080/
api_key: YOUR_API_KEY_HERE
mode: iptables
Start it:
sudo systemctl enable crowdsec-firewall-bouncer
sudo systemctl start crowdsec-firewall-bouncer
Now blocked IPs get dropped at the firewall level. They can’t even establish a TCP connection.
Nginx Bouncer (Alternative)
If you can’t modify firewall rules (shared hosting, some VPS), use the Nginx bouncer instead. It returns 403 to blocked IPs at the web server level.
Cloudflare Bouncer
If you’re behind Cloudflare (like selfhostsetup.com), the Cloudflare bouncer automatically adds blocked IPs to your Cloudflare firewall rules — blocking them before traffic even reaches your server.
docker exec crowdsec cscli bouncers add cloudflare-bouncer
Install and configure:
sudo apt install crowdsec-cloudflare-bouncer
sudo crowdsec-cloudflare-bouncer -g YOUR_CF_TOKEN -o /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
sudo systemctl enable crowdsec-cloudflare-bouncer
sudo systemctl start crowdsec-cloudflare-bouncer
Step 4: Connect to the CrowdSec Console
The free CrowdSec Console gives you a web dashboard to monitor your instance.
- Create an account at app.crowdsec.net
- Enroll your instance:
docker exec crowdsec cscli console enroll YOUR_ENROLLMENT_KEY
- Approve the instance in the web console
You’ll see:
- Real-time alerts and decisions
- Attack origin maps
- Community blocklist stats
- Multi-server overview (if you run CrowdSec on multiple hosts)
Step 5: Add More Collections
Collections are bundles of parsers + scenarios for specific software. Browse the CrowdSec Hub for your stack:
# WordPress brute force detection
docker exec crowdsec cscli collections install crowdsecurity/wordpress
# Traefik (if you use it as reverse proxy)
docker exec crowdsec cscli collections install crowdsecurity/traefik
# Docker exploit detection
docker exec crowdsec cscli collections install crowdsecurity/docker
# HTTP generic attacks (SQL injection, XSS, etc.)
docker exec crowdsec cscli collections install crowdsecurity/http-cve
# Restart to apply
docker restart crowdsec
Step 6: Tune Your Configuration
Whitelist Your IPs
Don’t lock yourself out. Edit ./config/parsers/s02-enrich/whitelist.yaml:
name: my-whitelist
description: "Whitelist my IPs"
whitelist:
reason: "My trusted IPs"
ip:
- "YOUR_HOME_IP"
- "YOUR_VPN_IP"
cidr:
- "10.0.0.0/8"
- "192.168.0.0/16"
Adjust Ban Duration
Default ban is 4 hours. Change it in ./config/profiles.yaml:
profiles:
- name: default_ban
filters:
- Alert.Remediation == true
decisions:
- type: ban
duration: 24h # Changed from 4h
on_success: break
Enable Community Blocklist
This is the killer feature — subscribe to the community blocklist to preemptively block known bad IPs:
docker exec crowdsec cscli console enable blocklist community
This adds tens of thousands of known attacker IPs to your blocklist before they even knock on your door.
Monitoring and Maintenance
Check What’s Being Blocked
# Current bans
docker exec crowdsec cscli decisions list
# Recent alerts
docker exec crowdsec cscli alerts list
# Stats
docker exec crowdsec cscli metrics
Update Scenarios
docker exec crowdsec cscli hub update
docker exec crowdsec cscli hub upgrade
Check Bouncer Status
docker exec crowdsec cscli bouncers list
Troubleshooting
CrowdSec not parsing logs
Check that log paths are mounted correctly:
docker exec crowdsec ls -la /var/log/nginx/
Verify acquisition config:
docker exec crowdsec cat /etc/crowdsec/acquis.yaml
Bouncer not blocking
- Check bouncer is registered:
docker exec crowdsec cscli bouncers list - Check bouncer logs:
journalctl -u crowdsec-firewall-bouncer - Verify API connectivity:
curl http://127.0.0.1:8080/v1/decisions
Locked yourself out
If you accidentally banned your own IP:
# From another connection (console, VPN)
docker exec crowdsec cscli decisions delete --ip YOUR_IP
High memory usage
CrowdSec is lightweight (~50MB typical), but large blocklists can increase usage. Set limits in the compose file:
deploy:
resources:
limits:
memory: 256M
CrowdSec + Your Existing Stack
CrowdSec works alongside your other security tools:
- Behind Cloudflare? Use the Cloudflare bouncer for edge blocking
- Running Traefik? Install the Traefik collection for HTTP attack detection
- Using Authelia/Authentik? CrowdSec catches brute force before it reaches your SSO
- Have Fail2ban? They can coexist, but CrowdSec makes Fail2ban redundant
What to Set Up Next
- Securing Your Home Server — foundational security guide
- SSL Certificates for Self-Hosted Services — HTTPS everywhere
- Uptime Kuma — monitor that everything stays up
CrowdSec turns your server from an isolated target into part of a collective defense network. The more people who run it, the stronger everyone’s protection gets. Set it up, enroll in the community, and stop fighting bots alone.