CrowdSec takes a fundamentally different approach to intrusion prevention compared to tools like Fail2Ban. While Fail2Ban operates in isolation, analyzing logs on a single server, CrowdSec adds a collaborative intelligence layer. When one CrowdSec agent detects an attack, the offending IP can be shared with the entire community, allowing every participant to preemptively block known attackers before they even reach your infrastructure.

Think of it as a crowd-sourced threat intelligence network combined with a local intrusion detection system. The architecture separates detection (the Security Engine) from enforcement (Bouncers), allowing flexible deployment across heterogeneous infrastructure.

CrowdSec vs Fail2Ban

Feature CrowdSec Fail2Ban
Architecture Separate engine + bouncers Monolithic daemon
Threat intelligence Community-shared blocklists Local-only detection
Language Go (single binary) Python
Log parsing YAML-based parsers + expr Regex-based filters
Decision types Ban, captcha, throttle Ban only
Console/dashboard Web-based console (free) CLI only
API Full REST API (LAPI) Unix socket CLI
Docker support First-class, native images Manual configuration
Performance High (compiled Go) Moderate (Python)

When to choose CrowdSec over Fail2Ban: CrowdSec is the better choice when you run multiple servers, need community threat intelligence, want flexible response actions beyond simple banning, or prefer a modern API-driven architecture. Fail2Ban is simpler for single-server setups where you just need basic SSH protection.

Architecture Overview

CrowdSec has three main components:

  • Security Engine (crowdsec): Parses logs, evaluates scenarios, and creates decisions (ban/captcha/throttle). Runs the Local API (LAPI).
  • Bouncers: Enforce decisions at the network edge. Multiple bouncer types exist: firewall (iptables/nftables), Nginx, Traefik, Cloudflare, and more.
  • Central API (CAPI): The community hub. Your engine shares attack signals and receives curated community blocklists in return.

Installation

Native Installation

# Add CrowdSec repository (Debian/Ubuntu)
curl -s https://install.crowdsec.net | sudo sh
sudo apt install crowdsec

# RHEL/CentOS/Fedora
curl -s https://install.crowdsec.net | sudo sh
sudo dnf install crowdsec

# Check status
sudo cscli version
sudo cscli metrics

Docker Deployment

services:
  crowdsec:
    image: crowdsecurity/crowdsec:latest
    container_name: crowdsec
    restart: unless-stopped
    environment:
      COLLECTIONS: "crowdsecurity/linux crowdsecurity/nginx crowdsecurity/sshd"
      GID: "${GID:-1000}"
    volumes:
      # CrowdSec configuration and data
      - crowdsec_config:/etc/crowdsec
      - crowdsec_data:/var/lib/crowdsec/data
      # Log sources to analyze
      - /var/log/auth.log:/var/log/auth.log:ro
      - /var/log/syslog:/var/log/syslog:ro
      - nginx_logs:/var/log/nginx:ro
    networks:
      - crowdsec_net

  # Firewall bouncer (runs on host network)
  bouncer-firewall:
    image: crowdsecurity/crowdsec-firewall-bouncer-nftables:latest
    container_name: crowdsec-firewall-bouncer
    restart: unless-stopped
    network_mode: host
    cap_add:
      - NET_ADMIN
      - NET_RAW
    environment:
      CROWDSEC_BOUNCER_API_KEY: "${BOUNCER_API_KEY}"
      CROWDSEC_URL: "http://crowdsec:8080"
    depends_on:
      - crowdsec

volumes:
  crowdsec_config:
  crowdsec_data:
  nginx_logs:

networks:
  crowdsec_net:

Collections, Parsers, and Scenarios

CrowdSec uses a hub system for distributing detection configurations:

# Browse available collections
sudo cscli collections list -a

# Install collections
sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/sshd
sudo cscli collections install crowdsecurity/linux
sudo cscli collections install crowdsecurity/http-cve

# A collection bundles parsers + scenarios:
sudo cscli collections inspect crowdsecurity/nginx
# Parsers:
#   - crowdsecurity/nginx-logs
#   - crowdsecurity/http-logs
# Scenarios:
#   - crowdsecurity/http-crawl-non_statics
#   - crowdsecurity/http-path-traversal-probing
#   - crowdsecurity/http-sqli-probing
#   - crowdsecurity/http-xss-probing

# List installed scenarios
sudo cscli scenarios list

# List installed parsers
sudo cscli parsers list

Configuring Log Sources

# /etc/crowdsec/acquis.yaml (or acquis.d/*.yaml)

# SSH logs
---
filenames:
  - /var/log/auth.log
labels:
  type: syslog

# Nginx access logs
---
filenames:
  - /var/log/nginx/access.log
labels:
  type: nginx

# Nginx error logs
---
filenames:
  - /var/log/nginx/error.log
labels:
  type: nginx

# Docker container logs via journalctl
---
source: journalctl
journalctl_filter:
  - "_SYSTEMD_UNIT=docker.service"
labels:
  type: syslog

# Read from Docker container logs directly
---
source: docker
container_name:
  - nginx-proxy
  - traefik
labels:
  type: nginx

Bouncers: Enforcement Layer

Firewall Bouncer

# Install the firewall bouncer
sudo apt install crowdsec-firewall-bouncer-nftables

# Generate an API key for the bouncer
sudo cscli bouncers add firewall-bouncer
# API key: a1b2c3d4e5f6...

# Configure the bouncer
# /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
api_url: http://127.0.0.1:8080/
api_key: a1b2c3d4e5f6...
mode: nftables
update_frequency: 10s
deny_action: DROP
deny_log: true
deny_log_prefix: "crowdsec: "

# Start the bouncer
sudo systemctl enable --now crowdsec-firewall-bouncer

# Verify nftables rules
sudo nft list ruleset | grep crowdsec

Nginx Bouncer

# Install the Nginx bouncer (OpenResty/Lua)
sudo apt install crowdsec-openresty-bouncer

# Or for the Nginx module approach:
sudo cscli bouncers add nginx-bouncer

# /etc/crowdsec/bouncers/crowdsec-openresty-bouncer.conf
API_URL=http://127.0.0.1:8080
API_KEY=your_bouncer_api_key
# Show captcha instead of blocking
BOUNCING_ON_TYPE=all
FALLBACK_REMEDIATION=captcha
BAN_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/ban.html
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/captcha.html

Traefik Bouncer

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--experimental.plugins.crowdsec-bouncer-traefik-plugin.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
      - "--experimental.plugins.crowdsec-bouncer-traefik-plugin.version=v1.3.0"
    labels:
      - "traefik.http.middlewares.crowdsec.plugin.crowdsec-bouncer-traefik-plugin.crowdseclapikey=${BOUNCER_API_KEY}"
      - "traefik.http.middlewares.crowdsec.plugin.crowdsec-bouncer-traefik-plugin.crowdseclapischeme=http"
      - "traefik.http.middlewares.crowdsec.plugin.crowdsec-bouncer-traefik-plugin.crowdseclapihost=crowdsec:8080"

  # Apply the middleware to your services
  webapp:
    labels:
      - "traefik.http.routers.webapp.middlewares=crowdsec@docker"

Decisions and Alerts

# View current decisions (active bans)
sudo cscli decisions list

# View alerts (detected attacks)
sudo cscli alerts list

# Inspect a specific alert
sudo cscli alerts inspect 42

# Manually add a decision
sudo cscli decisions add --ip 203.0.113.50 --duration 24h --reason "manual ban"

# Remove a decision
sudo cscli decisions delete --ip 203.0.113.50

# Add a range ban
sudo cscli decisions add --range 203.0.113.0/24 --duration 168h --reason "hostile network"

Community Blocklists

One of CrowdSec's key advantages is community-shared threat intelligence. When you install CrowdSec and register with the console, you automatically receive curated blocklists:

# Enroll with the CrowdSec console
sudo cscli console enroll YOUR_ENROLLMENT_KEY

# View community blocklist status
sudo cscli console status

# The console provides:
# - IP reputation data from the community
# - Curated blocklists for known bad actors
# - Visualization of attacks on your infrastructure
# - Alert management and analytics
Tip: The CrowdSec console at app.crowdsec.net is free for personal use and provides a web dashboard showing attack trends, active decisions, bouncer status, and machine health. It is highly recommended for gaining visibility into your security posture.

Custom Scenarios

Create scenarios for application-specific attack detection:

# /etc/crowdsec/scenarios/my-app-bruteforce.yaml
type: leaky
name: my-company/my-app-bruteforce
description: "Detect brute force on my custom application"
filter: "evt.Meta.log_type == 'myapp' && evt.Meta.http_status == '401'"
groupby: "evt.Meta.source_ip"
capacity: 5
leakspeed: "10s"
blackhole: 5m
labels:
  remediation: true
  type: bruteforce
  service: myapp
# Custom parser for your application logs
# /etc/crowdsec/parsers/s02-enrich/my-app-parser.yaml
name: my-company/my-app-parser
description: "Parse my custom application logs"
filter: "evt.Parsed.program == 'myapp'"
onsuccess: next_stage
statics:
  - meta: log_type
    value: myapp
nodes:
  - grok:
      pattern: '%{IPORHOST:source_ip} - \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATHPARAM:uri} HTTP/%{NUMBER}" %{NUMBER:http_status}'
      apply_on: message
    statics:
      - meta: http_status
        expression: evt.Parsed.http_status
      - meta: source_ip
        expression: evt.Parsed.source_ip

The CrowdSec API (LAPI)

# The Local API provides programmatic access to decisions
# Get current decisions
curl -s http://127.0.0.1:8080/v1/decisions \
  -H "X-Api-Key: ${API_KEY}" | jq .

# Add a decision via API
curl -s -X POST http://127.0.0.1:8080/v1/decisions \
  -H "X-Api-Key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '[{
    "duration": "24h",
    "origin": "manual",
    "scenario": "manual/ban",
    "scope": "Ip",
    "type": "ban",
    "value": "203.0.113.50"
  }]'

# Query if an IP has a decision
curl -s "http://127.0.0.1:8080/v1/decisions?ip=203.0.113.50" \
  -H "X-Api-Key: ${API_KEY}" | jq .

Monitoring and Metrics

# Built-in metrics
sudo cscli metrics

# Output shows:
# - Parsed lines per source
# - Overflow (scenario triggers) per scenario
# - Active decisions by type
# - Bouncer requests

# Prometheus metrics endpoint
# /etc/crowdsec/config.yaml
prometheus:
  enabled: true
  level: full
  listen_addr: 127.0.0.1
  listen_port: 6060

# Scrape with Prometheus
# prometheus.yml
scrape_configs:
  - job_name: crowdsec
    static_configs:
      - targets: ['localhost:6060']

CrowdSec represents a significant evolution in host-based intrusion detection. The combination of local behavior analysis with community threat intelligence provides protection that no single-server solution can match. For self-hosted infrastructure running Docker workloads, deploying CrowdSec alongside your reverse proxy gives you both reactive detection and proactive blocking of known malicious actors.