Every homelab exposed to the internet collects unwanted traffic. Port scanners, credential stuffers, botnets probing for vulnerabilities. Fail2ban helps, but it works in isolation — one server learns nothing from another, and your firewall only knows what it has seen.
CrowdSec replaces this model with a collaborative, behavior-based approach. When your CrowdSec agent detects a brute-force attempt on your SSH server, it shares the attacker’s IP with the community. You get the same benefit — your agent pulls the global blocklist and blocks attackers your neighbors have already seen.
This guide covers a full CrowdSec deployment with Docker Compose and Traefik, including the LAPI agent, the Traefik bouncer (plugin), a firewall bouncer for host-level blocking, collections for common services, and custom scenarios. The result is an intrusion prevention system that gets smarter the more nodes you add.
How CrowdSec Works
CrowdSec is three components working together:
- Agent (LAPI) — Reads logs, parses them with parsers, runs them through scenarios, and decides if an IP is malicious. Runs the Local API (LAPI) that bouncers query to check IP reputations.
- Bouncers — The enforcement layer. Bouncers query the LAPI periodically or on each request. If the IP is on the blocklist, the bouncer drops the connection. Traefik has a native plugin bouncer. The firewall bouncer adds nftables/iptables rules at the host level.
- CrowdSec Console — Optional web dashboard showing alerts, decisions, and community signals. Self-hosted or cloud.
Decisions flow through a remediation pipeline: logs → parsers → scenarios → alert → decision → bouncer → block. The same pipeline can also trigger CAPTCHA challenges, rate limiting, or country-based filtering through the AppSec component.
Step 1: Deploy CrowdSec with Docker Compose
Create the project directory and compose file:
|
|
/opt/crowdsec/docker-compose.yml:
|
|
The agent mounts host log directories so it can parse Nginx, SSH, and
system logs. The firewall bouncer runs in network_mode: host with
NET_ADMIN to install nftables rules. The LAPI port binds to localhost
only — the Traefik bouncer plugin accesses it through the Docker
network.
Environment file — /opt/crowdsec/.env:
|
|
Start CrowdSec first, then generate the bouncer key:
|
|
Step 2: Install the Traefik CrowdSec Bouncer Plugin
The Traefik plugin bouncer checks every incoming HTTP request against the CrowdSec LAPI before forwarding it to your service. If the requester’s IP is on the blocklist, Traefik returns a 403 without touching your backend.
Enable the plugin in your Traefik static config (traefik.yml or CLI
args):
|
|
Generate a dedicated bouncer key for Traefik:
|
|
Add the middleware in Traefik dynamic config or file provider:
|
|
Apply the middleware to any router that should be protected:
|
|
Traefik now checks every incoming request against CrowdSec before
reaching your application. The defaultDecision: bypass setting means
requests get through if the LAPI is unreachable — fail open, not closed.
Step 3: Collections — Ready-Made Detection Rules
Collections bundle parsers and scenarios for specific services. The
environment variable COLLECTIONS in the compose file already pulls:
|
|
Add more collections after deployment:
|
|
When running in a Docker homelab, start with these:
| Collection | What it detects |
|---|---|
crowdsecurity/nginx |
HTTP scans, directory brute-force, 404 probing, SQL injection probes |
crowdsecurity/linux |
SSH brute-force, sudo failures, system log anomalies |
crowdsecurity/http-cve |
Known CVE exploitation attempts on HTTP services |
crowdsecurity/sshd |
SSH dictionary attacks, connection floods |
crowdsecurity/base-http-scenarios |
Generic HTTP abuse (rate limiting, path traversal) |
crowdsecurity/whitelist-good-actors |
Avoid false positives from known good IPs (Googlebot, Cloudflare, your home IP) |
After installing new collections, reload CrowdSec:
|
|
Step 4: Custom Scenarios for Your Lab
Scenarios define the conditions that trigger an alert. Default collections cover common attacks, but your homelab has unique traffic patterns. Custom scenarios let you tune detection to your environment.
Example — Block IPs that hit non-existent subdomains:
|
|
This scenario triggers when a single IP hits 10 different 404 paths
within 30 seconds. The blackhole: 5m means the IP is blocked for
5 minutes. Adjust the threshold based on your legitimate traffic.
Mount custom scenarios:
Add a volume mount in the compose file:
|
|
Test the scenario with:
|
|
Step 5: The Remediation Pipeline — What Happens When CrowdSec Fires
Understanding the alert → decision → remediation flow helps you troubleshoot and tune.
1. An IP triggers a scenario
Example: SSH brute-force from 198.51.100.50 triggers
crowdsecurity/ssh-bf after 5 failed logins in 10 seconds.
2. CrowdSec creates an alert
|
|
3. CrowdSec creates a decision
|
|
4. Bouncers enforce the decision
- Traefik bouncer: Checks each HTTP request against the LAPI. If the IP is banned, Traefik returns 403 before the request reaches your service. Latency impact: ~5ms per request.
- Firewall bouncer: Adds an nftables drop rule for the IP. The kernel drops the packet before any application sees it.
5. The IP is shared with the CrowdSec community
If you opt in to the community blocklist (default), your alerts from public-facing services are shared. In exchange, your agent receives the global blocklist updates.
Check what CrowdSec is sharing:
|
|
These are community-sourced blocks — IPs other CrowdSec users have reported.
Step 6: Monitoring and Observability
CrowdSec exposes metrics that integrate with your homelab monitoring stack.
Built-in metrics endpoint:
|
|
|
|
Prometheus scraping config:
|
|
Grafana dashboard for CrowdSec:
Import the community dashboard (ID from Grafana.com or build your own with these panels):
- Active decisions gauge — How many IPs are currently blocked
- Alerts by scenario — Which attacks are hitting your setup
- Top blocked IPs — Worst offenders by alert count
- Parsed logs rate — Log throughput (should match your service volume)
- Bouncer latency — LAPI response time (should be under 10ms)
Quick health check:
|
|
Step 7: Whitelisting and Tuning
False positives happen. The whitelist allows you to exclude trusted sources from enforcement.
Whitelist your home IP or VPN range:
|
|
Whitelist Cloudflare IPs (if you use Cloudflare Tunnel):
|
|
Tune scenario sensitivity per service:
|
|
If you run a staging environment that generates intentional traffic anomalies (deploy pipelines, test harnesses), whitelist those source IPs first before troubleshooting “CrowdSec is blocking my DeployBot.”
Step 8: Alert Notifications
CrowdSec sends notifications through plugins. Telegram is the most useful for the homelab — you get a message when an IP is blocked.
Enable the Telegram notification plugin:
|
|
Create the notification config file:
|
|
Create a profile that uses this notification:
|
|
Reload config:
|
|
When CrowdSec blocks an IP, the Telegram notification fires immediately. You can also set up email, Slack, Discord, or webhook notifications through the same plugin system.
Integrating with the Larger Homelab
CrowdSec in a single stack is useful. CrowdSec across multiple hosts is transformative. If you run several Proxmox VMs or physical machines:
Multi-agent setup with a central LAPI:
- One host runs the CrowdSec agent with LAPI enabled (the setup above)
- Other hosts run CrowdSec agents in send-only mode — they parse logs and send alerts to the central LAPI, but don’t host bouncers directly
- The central LAPI keeps the single source of truth for decisions
- All bouncers query the central LAPI
|
|
This setup means a scanner hitting any of your machines gets blocked across all of them — the first host to detect it shares the decision with every bouncer in the lab.
Summary
CrowdSec replaces the isolated, reactive security model of Fail2ban with a collaborative IPS that detects, shares, and blocks threats at the application and network layers.
The Docker Compose deployment in this guide gives you:
- Automatic threat detection — Pre-built collections for Nginx, SSH, HTTP CVEs, and more, with community blocklist enrichment
- Dual-layer enforcement — Traefik plugin bouncer blocks at the reverse proxy level, firewall bouncer blocks at the kernel level
- Custom detection rules — Write scenarios tuned to your specific homelab traffic patterns
- Real-time notifications — Telegram alerts when incidents are detected
- Multi-host sharing — One LAPI instance serves all your machines, sharing intelligence across the lab
CrowdSec doesn’t replace good firewall rules or regular updates. It adds a behavioral detection layer on top of them. The community blocklist means you benefit from attacks other homelabs have already seen, and your blocked IPs help protect the rest of the community in return.
The compose stack from this guide protects every exposed service. Traefik middleware catches web-based attacks before they reach your applications. The firewall bouncer drops SSH scanners, port probes, and any other connection from a known malicious IP. And when something new hits one of your services, CrowdSec learns from it — and the rest of your lab is protected within seconds.