تخطَّ إلى المحتوى

CrowdSec Bouncer Cheat Sheet

Overview

CrowdSec Bouncers are remediation components that enforce decisions made by the CrowdSec Security Engine. When CrowdSec detects malicious behavior (brute force, scanning, crawling, CVE exploitation), it generates alerts and decisions. Bouncers consume these decisions and take action — blocking IPs at the firewall level, presenting CAPTCHA challenges, rate limiting requests, or modifying application behavior. Bouncers query the CrowdSec Local API (LAPI) to fetch active decisions and apply them in real-time.

The bouncer ecosystem covers multiple enforcement points: firewall bouncers (iptables, nftables, ipset, pf) block at the network layer, reverse proxy bouncers (Nginx, Traefik, HAProxy, Caddy) block at the application layer, and WAF bouncers integrate with web application firewalls. CrowdSec also provides the CrowdSec Blocklist Mirror for integrating with third-party firewalls that support blocklist feeds. Bouncers can operate in multiple modes — blocking (deny), captcha (challenge), or allow/passthrough — and support IP, range, AS, and country-level decisions from both local detections and the CrowdSec Central API threat intelligence feed.

Installation

Firewall Bouncer (iptables/nftables)

# Install via package manager
curl -s https://install.crowdsec.net | sudo bash
sudo apt install crowdsec-firewall-bouncer-iptables
# or for nftables
sudo apt install crowdsec-firewall-bouncer-nftables

# Register bouncer with CrowdSec LAPI
sudo cscli bouncers add firewall-bouncer
# Save the displayed API key

# Configure the bouncer
sudo nano /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml

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

Nginx Bouncer

# Install the Nginx bouncer
sudo apt install crowdsec-nginx-bouncer

# Register bouncer
sudo cscli bouncers add nginx-bouncer
# Configure with the returned API key

# Restart Nginx to load the module
sudo systemctl restart nginx

Traefik Bouncer (Docker)

# docker-compose.yml
services:
  traefik-bouncer:
    image: fbonalair/traefik-crowdsec-bouncer:latest
    environment:
      - CROWDSEC_BOUNCER_API_KEY=<your-api-key>
      - CROWDSEC_AGENT_HOST=crowdsec:8080
    restart: unless-stopped
    networks:
      - traefik

WordPress / PHP Bouncer

# Install via Composer
composer require crowdsec/bouncer

# Or install WordPress plugin from WP admin panel
# Search for "CrowdSec" in Plugins > Add New

Core Commands

Bouncer Management

CommandDescription
cscli bouncers add <name>Register a new bouncer
cscli bouncers listList all registered bouncers
cscli bouncers delete <name>Remove a bouncer
cscli decisions listList all active decisions
cscli decisions add --ip <ip> --type banManually ban an IP
cscli decisions delete --ip <ip>Remove a ban decision
# List registered bouncers
sudo cscli bouncers list

# Check bouncer connectivity
sudo cscli bouncers list -o json | jq '.[] | {name, last_pull}'

# Add bouncer and get API key
sudo cscli bouncers add my-nginx-bouncer

# View active decisions being enforced
sudo cscli decisions list

# Manually ban an IP for 24 hours
sudo cscli decisions add --ip 192.168.1.100 --duration 24h --type ban --reason "manual block"

# Ban a CIDR range
sudo cscli decisions add --range 10.0.0.0/24 --duration 48h --type ban --reason "scanning activity"

# Add captcha decision instead of ban
sudo cscli decisions add --ip 192.168.1.100 --duration 4h --type captcha --reason "suspicious behavior"

# Remove specific decision
sudo cscli decisions delete --ip 192.168.1.100

# Remove all decisions
sudo cscli decisions delete --all

Configuration

Firewall Bouncer Configuration

# /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
mode: iptables  # iptables, nftables, ipset, pf
update_frequency: 10s
daemonize: true
log_mode: file
log_dir: /var/log/
log_level: info

api_url: http://localhost:8080/
api_key: <your-bouncer-api-key>

# Disable IPv6 if not needed
disable_ipv6: false

# iptables-specific settings
iptables_chains:
  - INPUT
  - FORWARD

# nftables-specific settings
nftables:
  ipv4:
    table: crowdsec
    chain: crowdsec-chain
    set: crowdsec-blacklists
  ipv6:
    table: crowdsec6
    chain: crowdsec6-chain
    set: crowdsec6-blacklists

# Deny action (DROP or REJECT)
deny_action: DROP
deny_log: false
deny_log_prefix: "crowdsec: "

# Blacklist type
blacklists_ipv4: crowdsec-blacklists
blacklists_ipv6: crowdsec6-blacklists

Nginx Bouncer Configuration

# /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf
API_URL=http://127.0.0.1:8080
API_KEY=<your-bouncer-api-key>

# Cache configuration
CACHE_EXPIRATION=1
CACHE_SIZE=1000

# Bouncer mode
BOUNCING_ON_TYPE=ban  # ban, captcha, all

# Ban template
BAN_TEMPLATE_PATH=/var/lib/crowdsec/lua/templates/ban.html

# Captcha configuration
CAPTCHA_PROVIDER=recaptcha  # recaptcha, hcaptcha, turnstile
CAPTCHA_SITE_KEY=<your-site-key>
CAPTCHA_SECRET_KEY=<your-secret-key>

# Exclusions
EXCLUDE_LOCATION=/health,/api/status

# SSL verification
SSL_VERIFY=true

Nginx Server Block Integration

# /etc/nginx/conf.d/crowdsec.conf
lua_shared_dict crowdsec_cache 50m;
lua_package_path '/usr/lib/crowdsec/lua/?.lua;;';

init_by_lua_block {
    cs = require "crowdsec"
    local ok, err = cs.init("/etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf", "crowdsec-nginx-bouncer/v1.0")
    if ok == nil then
        ngx.log(ngx.ERR, "[Crowdsec] " .. err)
        error()
    end
    ngx.log(ngx.ALERT, "[Crowdsec] Initialization done")
}

access_by_lua_block {
    local cs = require "crowdsec"
    cs.Allow(ngx.var.remote_addr)
}

Advanced Usage

Blocklist Mirror

# Install blocklist mirror for third-party firewall integration
sudo apt install crowdsec-blocklist-mirror

# Configure mirror
sudo nano /etc/crowdsec/bouncers/crowdsec-blocklist-mirror.yaml
# /etc/crowdsec/bouncers/crowdsec-blocklist-mirror.yaml
crowdsec_config:
  lapi_key: <your-api-key>
  lapi_url: http://localhost:8080

listen_uri: 0.0.0.0:41412
tls:
  cert_file: ""
  key_file: ""

blocklists:
  - format: plain_text  # plain_text, mikrotik, f5
    path: /security/blocklist
    authentication:
      type: basic
      user: admin
      password: secretpassword
# Fetch blocklist from mirror
curl http://localhost:41412/security/blocklist

# Use with external firewall (e.g., pfSense, OPNsense)
# Configure firewall to pull from: http://crowdsec-host:41412/security/blocklist

Custom Ban Pages

<!-- /var/lib/crowdsec/lua/templates/ban.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Access Denied</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
        .container { max-width: 600px; margin: 0 auto; }
        h1 { color: #e74c3c; }
    </style>
</head>
<body>
    <div class="container">
        <h1>Access Denied</h1>
        <p>Your IP address has been blocked due to suspicious activity.</p>
        <p>If you believe this is an error, contact support.</p>
    </div>
</body>
</html>

Monitoring Bouncer Performance

# Check firewall bouncer status
sudo systemctl status crowdsec-firewall-bouncer

# View bouncer logs
sudo tail -f /var/log/crowdsec-firewall-bouncer.log

# Check iptables rules created by bouncer
sudo iptables -L INPUT -n | grep -i crowdsec
sudo ipset list crowdsec-blacklists | head -20

# Count blocked IPs
sudo ipset list crowdsec-blacklists | wc -l

# Check nftables rules
sudo nft list table inet crowdsec

# Monitor decision sync
sudo cscli bouncers list -o json | jq '.[].last_pull'

Multi-Server Deployment

# On central LAPI server
sudo cscli bouncers add edge-bouncer-01
sudo cscli bouncers add edge-bouncer-02

# On edge servers, configure bouncer to point to central LAPI
# /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
# api_url: http://central-lapi:8080/
# api_key: <edge-specific-key>

Troubleshooting

IssueSolution
Bouncer not pulling decisionsCheck API key and URL in config, verify LAPI is running: cscli lapi status
IPs not being blockedVerify firewall bouncer is running: systemctl status crowdsec-firewall-bouncer
False positive blocksRemove decision: cscli decisions delete --ip <ip>, add to whitelist
Nginx bouncer 500 errorsCheck Lua module installation and config file path
High memory usageReduce CACHE_SIZE or update_frequency in bouncer config
Bouncer registration failsEnsure LAPI is accessible on port 8080, check firewall rules
ipset errorsVerify ipset module is loaded: lsmod | grep ip_set
Decisions not syncingCheck time synchronization between LAPI and bouncer hosts