homelab/compose/core/crowdsec/README.md
Eduardo Figueroa 3bf1575ca8 chore: General catchup - service updates and cleanup
Updated service configurations, added new services, removed deprecated
ones, and improved gitignore patterns for better repository hygiene.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-15 05:23:02 +00:00

453 lines
9.6 KiB
Markdown

# CrowdSec - Collaborative Security Engine
CrowdSec is a free, open-source Intrusion Prevention System (IPS) that analyzes logs and blocks malicious IPs based on behavior analysis and community threat intelligence.
## Features
- Behavior-based detection - Detects attacks from log patterns
- Community threat intelligence - Shares & receives IP reputation data
- Traefik integration - Protects all web services via plugin
- SQLite database - No separate database container needed
- Local network whitelist - Prevents self-blocking (10.0.0.0/16)
- Multiple scenarios - HTTP attacks, brute force, scanners, etc.
- Optional dashboard - Web UI at crowdsec.fig.systems
## Access
**Dashboard URL:** https://crowdsec.fig.systems (protected by Authelia)
**LAPI:** http://crowdsec:8080 (internal only, used by Traefik plugin)
## Quick Start
### Initial Deployment
1. **Deploy CrowdSec:**
```bash
cd /home/eduardo_figueroa/homelab/compose/core/crowdsec
docker compose up -d
```
2. **Wait for initialization** (30-60 seconds):
```bash
docker logs crowdsec -f
```
Look for: "CrowdSec service: crowdsec up and running"
3. **Generate Bouncer API Key:**
```bash
docker exec crowdsec cscli bouncers add traefik-bouncer
```
**Important:** Copy the API key shown. It will look like:
```
API key for 'traefik-bouncer':
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
```
4. **Add API key to Traefik:**
```bash
cd /home/eduardo_figueroa/homelab/compose/core/traefik
nano .env
```
Update the line:
```bash
CROWDSEC_BOUNCER_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
```
5. **Restart Traefik to load plugin:**
```bash
docker compose restart
```
6. **Verify plugin connection:**
```bash
docker logs traefik 2>&1 | grep -i crowdsec
```
Should see: "Plugin crowdsec-bouncer-traefik-plugin loaded"
### Apply CrowdSec Middleware to Services
Edit service compose.yaml files to add CrowdSec middleware:
**Example - Jellyfin:**
```yaml
labels:
traefik.http.routers.jellyfin.middlewares: crowdsec
```
**Example - With Authelia chain:**
```yaml
labels:
traefik.http.routers.service.middlewares: crowdsec,authelia
```
**Recommended for:**
- Publicly accessible services (jellyfin, jellyseer, etc.)
- Services without rate limiting
- High-value targets (admin panels, databases)
**Skip for:**
- Traefik dashboard (already has local-only)
- Strictly local services (no external access)
## Management Commands
### View Decisions (Active Bans)
```bash
# List all active bans
docker exec crowdsec cscli decisions list
# List bans with details
docker exec crowdsec cscli decisions list -o json
```
### View Alerts (Detected Attacks)
```bash
# Recent alerts
docker exec crowdsec cscli alerts list
# Detailed alert view
docker exec crowdsec cscli alerts inspect <alert_id>
```
### Whitelist an IP
```bash
# Temporary whitelist
docker exec crowdsec cscli decisions delete --ip 1.2.3.4
# Permanent whitelist - add to config/local_whitelist.yaml:
```
```yaml
whitelist:
reason: "Trusted service"
cidr:
- "1.2.3.4/32"
```
Then restart CrowdSec:
```bash
docker compose restart
```
### Ban an IP Manually
```bash
# Ban for 4 hours
docker exec crowdsec cscli decisions add --ip 1.2.3.4 --duration 4h --reason "Manual ban"
# Permanent ban
docker exec crowdsec cscli decisions add --ip 1.2.3.4 --duration 24h --reason "Malicious actor"
```
### View Installed Collections
```bash
docker exec crowdsec cscli collections list
```
### Install Additional Collections
```bash
# WordPress protection
docker exec crowdsec cscli collections install crowdsecurity/wordpress
# SSH brute force (if exposing SSH)
docker exec crowdsec cscli collections install crowdsecurity/sshd
# Apply changes
docker compose restart
```
### View Bouncer Status
```bash
# List bouncers
docker exec crowdsec cscli bouncers list
# Should show traefik-bouncer with last_pull timestamp
```
### View Metrics
```bash
# CrowdSec metrics
docker exec crowdsec cscli metrics
# Show parser statistics
docker exec crowdsec cscli metrics show parsers
# Show scenario statistics
docker exec crowdsec cscli metrics show scenarios
```
## Configuration Files
### acquis.yaml
Defines log sources for CrowdSec to monitor:
```yaml
filenames:
- /var/log/traefik/access.log
labels:
type: traefik
```
**Modify to add more log sources:**
```yaml
---
filenames:
- /var/log/traefik/access.log
labels:
type: traefik
---
filenames:
- /var/log/nginx/access.log
labels:
type: nginx
```
After changes:
```bash
docker compose restart
```
### local_whitelist.yaml
Whitelists trusted IPs/CIDRs:
```yaml
whitelist:
reason: "Local network and trusted infrastructure"
cidr:
- "10.0.0.0/16"
- "127.0.0.1/32"
```
**Add more entries:**
```yaml
cidr:
- "10.0.0.0/16"
- "192.168.1.100/32" # Trusted admin IP
```
After changes:
```bash
docker compose restart
```
## Installed Collections
### crowdsecurity/traefik
Parsers and scenarios for Traefik-specific attacks:
- Path traversal attempts
- SQLi in query strings
- XSS attempts
- Admin panel scanning
### crowdsecurity/base-http-scenarios
Generic HTTP attack scenarios:
- Brute force (login attempts)
- Credential stuffing
- Directory enumeration
- Sensitive file access attempts
### crowdsecurity/whitelist-good-actors
Whitelists known good actors:
- Search engine bots (Google, Bing, etc.)
- Monitoring services (UptimeRobot, Pingdom)
- CDN providers (Cloudflare, etc.)
## Integration with Traefik
### How It Works
1. **Traefik receives request** → Checks CrowdSec plugin middleware
2. **Plugin queries CrowdSec LAPI** → "Is this IP banned?"
3. **CrowdSec responds:**
- Not banned → Request proceeds to service
- Banned → Returns 403 Forbidden
4. **Traefik logs request** → Saved to /var/log/traefik/access.log
5. **CrowdSec analyzes logs** → Detects attack patterns
6. **CrowdSec makes decision** → Ban IP or alert
7. **Plugin updates cache** → Every 60 seconds (stream mode)
### Stream Mode
The plugin uses **stream mode** for optimal performance:
- **Live mode:** Queries LAPI on every request (high latency)
- **Stream mode:** Maintains local cache, updates every 60s (low latency)
- **Alone mode:** No LAPI connection, local decisions only
**Current config:** Stream mode with 60s updates
### Middleware Chain Order
When chaining middlewares, order matters:
```yaml
# Correct: CrowdSec first, then Authelia
traefik.http.routers.service.middlewares: crowdsec,authelia
# Also valid: CrowdSec after rate limiting
traefik.http.routers.service.middlewares: ratelimit,crowdsec
```
**Recommended order:**
1. Rate limiting (if any)
2. CrowdSec (block banned IPs early)
3. Authelia (authentication for allowed IPs)
## Troubleshooting
### CrowdSec Not Blocking Malicious IPs
**Check decisions:**
```bash
docker exec crowdsec cscli decisions list
```
If empty, CrowdSec isn't detecting attacks.
**Check alerts:**
```bash
docker exec crowdsec cscli alerts list
```
If empty, logs aren't being parsed.
**Verify log parsing:**
```bash
docker exec crowdsec cscli metrics show acquisitions
```
Should show Traefik log file being read.
**Check acquis.yaml:**
```bash
docker exec crowdsec cat /etc/crowdsec/acquis.yaml
```
### Traefik Plugin Not Connecting
**Check Traefik logs:**
```bash
docker logs traefik 2>&1 | grep -i crowdsec
```
**Common issues:**
- API key not set in .env
- CrowdSec container not running
- Network connectivity (both must be on homelab network)
**Test connection:**
```bash
docker exec traefik wget -O- http://crowdsec:8080/v1/decisions/stream
```
Should return JSON (may be unauthorized, but connection works).
### Traefik Not Loading Plugin
**Check Traefik startup logs:**
```bash
docker logs traefik | head -50
```
Look for:
- "Plugin crowdsec-bouncer-traefik-plugin loaded"
- "experimental.plugins" enabled
**Verify traefik.yml:**
```bash
docker exec traefik cat /etc/traefik/traefik.yml
```
Ensure experimental.plugins section exists.
### Accidentally Banned Yourself
**Quick unban:**
```bash
docker exec crowdsec cscli decisions delete --ip YOUR_IP_HERE
```
**Permanent whitelist:**
Edit `/home/eduardo_figueroa/homelab/compose/core/crowdsec/config/local_whitelist.yaml`:
```yaml
whitelist:
cidr:
- "YOUR_IP/32"
```
Restart:
```bash
docker compose restart
```
### Logs Not Being Parsed
**Check log file permissions:**
```bash
ls -la /home/eduardo_figueroa/homelab/compose/core/traefik/logs/
```
**Check CrowdSec can read logs:**
```bash
docker exec crowdsec ls -la /var/log/traefik/
docker exec crowdsec tail /var/log/traefik/access.log
```
**Check acquisitions:**
```bash
docker exec crowdsec cscli metrics show acquisitions
```
Should show lines read from access.log.
## Best Practices
1. **Monitor metrics weekly:**
```bash
docker exec crowdsec cscli metrics
```
2. **Review decisions periodically:**
Check for false positives
3. **Keep collections updated:**
```bash
docker exec crowdsec cscli collections upgrade --all
docker compose restart
```
4. **Backup database:**
```bash
cp -r /home/eduardo_figueroa/homelab/compose/core/crowdsec/db/ /backup/location/
```
5. **Test changes in staging:**
Before applying to production services
6. **Use whitelist liberally:**
Better to whitelist trusted IPs than deal with lockouts
7. **Chain with Authelia:**
Defense in depth - CrowdSec blocks bad actors, Authelia handles authentication
## Links
- **Official Docs:** https://docs.crowdsec.net/
- **Traefik Plugin:** https://plugins.traefik.io/plugins/6335346ca4caa9ddeffda116/crowdsec-bouncer-traefik-plugin
- **Collections Hub:** https://app.crowdsec.net/hub/collections
- **Community Forum:** https://discourse.crowdsec.net/
- **GitHub:** https://github.com/crowdsecurity/crowdsec