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>
453 lines
9.6 KiB
Markdown
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
|