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

9.6 KiB

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:

    cd /home/eduardo_figueroa/homelab/compose/core/crowdsec
    docker compose up -d
    
  2. Wait for initialization (30-60 seconds):

    docker logs crowdsec -f
    

    Look for: "CrowdSec service: crowdsec up and running"

  3. Generate Bouncer API Key:

    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:

    cd /home/eduardo_figueroa/homelab/compose/core/traefik
    nano .env
    

    Update the line:

    CROWDSEC_BOUNCER_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
    
  5. Restart Traefik to load plugin:

    docker compose restart
    
  6. Verify plugin connection:

    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:

labels:
  traefik.http.routers.jellyfin.middlewares: crowdsec

Example - With Authelia chain:

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)

# 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)

# Recent alerts
docker exec crowdsec cscli alerts list

# Detailed alert view
docker exec crowdsec cscli alerts inspect <alert_id>

Whitelist an IP

# Temporary whitelist
docker exec crowdsec cscli decisions delete --ip 1.2.3.4

# Permanent whitelist - add to config/local_whitelist.yaml:
whitelist:
  reason: "Trusted service"
  cidr:
    - "1.2.3.4/32"

Then restart CrowdSec:

docker compose restart

Ban an IP Manually

# 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

docker exec crowdsec cscli collections list

Install Additional Collections

# 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

# List bouncers
docker exec crowdsec cscli bouncers list

# Should show traefik-bouncer with last_pull timestamp

View Metrics

# 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:

filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik

Modify to add more log sources:

---
filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik
---
filenames:
  - /var/log/nginx/access.log
labels:
  type: nginx

After changes:

docker compose restart

local_whitelist.yaml

Whitelists trusted IPs/CIDRs:

whitelist:
  reason: "Local network and trusted infrastructure"
  cidr:
    - "10.0.0.0/16"
    - "127.0.0.1/32"

Add more entries:

  cidr:
    - "10.0.0.0/16"
    - "192.168.1.100/32"  # Trusted admin IP

After changes:

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:

# 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:

docker exec crowdsec cscli decisions list

If empty, CrowdSec isn't detecting attacks.

Check alerts:

docker exec crowdsec cscli alerts list

If empty, logs aren't being parsed.

Verify log parsing:

docker exec crowdsec cscli metrics show acquisitions

Should show Traefik log file being read.

Check acquis.yaml:

docker exec crowdsec cat /etc/crowdsec/acquis.yaml

Traefik Plugin Not Connecting

Check Traefik logs:

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:

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:

docker logs traefik | head -50

Look for:

  • "Plugin crowdsec-bouncer-traefik-plugin loaded"
  • "experimental.plugins" enabled

Verify traefik.yml:

docker exec traefik cat /etc/traefik/traefik.yml

Ensure experimental.plugins section exists.

Accidentally Banned Yourself

Quick unban:

docker exec crowdsec cscli decisions delete --ip YOUR_IP_HERE

Permanent whitelist:

Edit /home/eduardo_figueroa/homelab/compose/core/crowdsec/config/local_whitelist.yaml:

whitelist:
  cidr:
    - "YOUR_IP/32"

Restart:

docker compose restart

Logs Not Being Parsed

Check log file permissions:

ls -la /home/eduardo_figueroa/homelab/compose/core/traefik/logs/

Check CrowdSec can read logs:

docker exec crowdsec ls -la /var/log/traefik/
docker exec crowdsec tail /var/log/traefik/access.log

Check acquisitions:

docker exec crowdsec cscli metrics show acquisitions

Should show lines read from access.log.

Best Practices

  1. Monitor metrics weekly:

    docker exec crowdsec cscli metrics
    
  2. Review decisions periodically: Check for false positives

  3. Keep collections updated:

    docker exec crowdsec cscli collections upgrade --all
    docker compose restart
    
  4. Backup database:

    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