CrowdSec Console and Bouncer Management
CrowdSec is a collaborative, open-source security engine that uses crowd-sourced threat intelligence to block malicious IPs across all participating servers. This guide covers installing CrowdSec bouncers (firewall and Nginx), enrolling in the CrowdSec Console, tuning scenarios, managing allow/blocklists, and integrating with the API.
Prerequisites
- Ubuntu 20.04+/Debian 11+ or CentOS 8+/Rocky Linux 8+
- CrowdSec agent installed
- Root or sudo access
- A free CrowdSec Console account (optional but recommended)
Install the CrowdSec agent if not already done:
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install -y crowdsec
sudo systemctl enable --now crowdsec
cscli version
CrowdSec Installation Overview
CrowdSec has two main components:
- Agent: Analyzes logs and detects attacks (installed above)
- Bouncers: Act on decisions (block IPs at the firewall, web server, etc.)
Decisions from the agent are consumed by bouncers. Multiple bouncers can share the same agent.
Check the current state:
# View active decisions
cscli decisions list
# View installed collections (detection scenarios)
cscli collections list
# View hub items
cscli hub list
Installing the Firewall Bouncer
The firewall bouncer uses nftables or iptables to block malicious IPs:
# Install the bouncer
sudo apt install -y crowdsec-firewall-bouncer-nftables
# Or for iptables:
# sudo apt install -y crowdsec-firewall-bouncer-iptables
# Check the configuration
cat /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
Key configuration file:
# /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
mode: nftables # or iptables
update_frequency: 10s # How often to refresh the blocklist
log_mode: file
log_dir: /var/log/crowdsec/
log_level: info
# API connection (auto-configured during install)
api_url: http://127.0.0.1:8080/
api_key: YOUR_BOUNCER_API_KEY
# nftables table configuration
nftables:
ipv4:
enabled: true
set-only: false
table: crowdsec
chain: crowdsec-chain
ipv6:
enabled: true
set-only: false
table: crowdsec6
chain: crowdsec6-chain
sudo systemctl enable --now crowdsec-firewall-bouncer
# Verify it's working
sudo nft list ruleset | grep crowdsec
cscli decisions list # Active blocks should be visible
Test a block manually:
# Add a test decision
cscli decisions add --ip 192.168.1.100 --reason "test block" --duration 1m
# Verify nftables set was updated
sudo nft list set ip crowdsec crowdsec-blacklists
# Remove the test decision
cscli decisions delete --ip 192.168.1.100
Installing the Nginx Bouncer
The Nginx bouncer blocks IPs at the web server layer, returning 403 before requests reach your application:
# Add CrowdSec nginx bouncer repo
sudo apt install -y crowdsec-nginx-bouncer
# Configuration
cat /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf
Edit the Nginx bouncer config:
# /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf
API_URL=http://127.0.0.1:8080
API_KEY=YOUR_BOUNCER_API_KEY
# Custom ban page
BAN_TEMPLATE_PATH=/etc/crowdsec/bouncers/ban.html
# Modes: ban (block), captcha (CAPTCHA challenge), or none
MODE=ban
# Return code for banned IPs
RET_CODE=403
# Request timeout
REQUEST_TIMEOUT=500
Configure Nginx to use the bouncer:
# In /etc/nginx/nginx.conf, within the http {} block
lua_package_path '/usr/lib/crowdsec/lua/nginx/?.lua;;';
lua_shared_dict crowdsec_cache 50m;
init_by_lua_block {
cs = require "crowdsec"
local ok, err = cs.init("/etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf")
if ok == nil then
ngx.log(ngx.ERR, "[crowdsec] Failed to init: ", err)
end
}
# In each server {} block where you want protection:
access_by_lua_block {
local crowdsec = require "crowdsec"
crowdsec.Allow()
}
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl enable --now crowdsec-nginx-bouncer
CrowdSec Console Enrollment
The CrowdSec Console provides a web interface for managing multiple CrowdSec instances:
- Create a free account at app.crowdsec.net
- Get your enrollment key from the Console
# Enroll your server
cscli console enroll ENROLLMENT_KEY_FROM_CONSOLE
# Confirm enrollment
sudo systemctl restart crowdsec
# Check status in the Console at https://app.crowdsec.net
cscli console status
Console features:
- View all decisions across all enrolled servers
- Access premium blocklists
- Centralized alert management
- Threat intelligence sharing
Scenario Tuning and Allowlisting
Adjust detection thresholds to reduce false positives:
# List installed scenarios
cscli scenarios list
# Install new scenarios
cscli scenarios install crowdsecurity/http-bad-user-agent
cscli scenarios install crowdsecurity/http-path-traversal-probing
cscli scenarios install crowdsecurity/http-sqli-probing
# Reload after changes
sudo systemctl reload crowdsec
Create a custom allowlist (whitelist):
sudo nano /etc/crowdsec/parsers/s02-enrich/whitelist.yaml
name: crowdsecurity/whitelists
description: "Whitelist legitimate IPs and user agents"
whitelist:
reason: "Internal infrastructure"
ip:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
- "203.0.113.50" # Your monitoring service
cidr:
- "198.51.100.0/24" # Partner network
expression:
# Whitelist Googlebot
- "evt.Parsed.http_user_agent contains 'Googlebot'"
- "evt.Parsed.http_user_agent contains 'bingbot'"
sudo systemctl reload crowdsec
# Verify whitelist is loaded
cscli parsers list | grep whitelist
Blocklist Management
CrowdSec has a community blocklist (CTI feed). Add third-party blocklists:
# Subscribe to the CrowdSec community blocklist (requires Console enrollment)
cscli hub update
cscli cti status
# Add a CAPI blocklist source
cscli hub list --type blocklists
# View your current decisions
cscli decisions list
# Manually add an IP to the blocklist
cscli decisions add --ip 198.51.100.100 --type ban --duration 24h --reason "manual block"
# Block a range
cscli decisions add --range 198.51.100.0/24 --type ban --duration 24h
# Remove a specific decision
cscli decisions delete --ip 198.51.100.100
# Remove all current decisions
cscli decisions delete --all
# Export current blocklist
cscli decisions list -o json > current-blocklist.json
API Integration
CrowdSec has a REST API for integration with other tools:
# Get the local API key
cat /etc/crowdsec/local_api_credentials.yaml
# Query decisions via API
curl -s -H "X-Api-Key: YOUR_API_KEY" \
http://localhost:8080/v1/decisions \
| python3 -m json.tool
# Check if a specific IP has a decision
curl -s -H "X-Api-Key: YOUR_API_KEY" \
"http://localhost:8080/v1/decisions?ip=198.51.100.100"
# Push a signal (for custom integrations)
curl -X POST -H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
http://localhost:8080/v1/decisions \
-d '[{
"duration": "24h",
"ip": "198.51.100.100",
"reason": "custom ban",
"type": "ban"
}]'
Integration with Fail2ban (run both side-by-side):
# CrowdSec can replace Fail2ban, or complement it
# If migrating, export Fail2ban bans to CrowdSec:
fail2ban-client banned | \
python3 -c "
import sys, json
for line in sys.stdin:
data = json.loads(line)
for jail, ips in data.items():
for ip in ips:
print(f'cscli decisions add --ip {ip} --reason fail2ban-migration --type ban --duration 24h')
" | bash
Monitoring and Alerts
# Real-time metrics
cscli metrics
# View recent alerts
cscli alerts list
# Alert details
cscli alerts inspect ID
# Monitor in real-time
sudo journalctl -u crowdsec -f
# Check bouncer activity
sudo journalctl -u crowdsec-firewall-bouncer -f | grep -i "block\|ban"
# Statistics
cscli decisions list | wc -l # Total active decisions
Set up email notifications for new attacks:
# /etc/crowdsec/notifications/email.yaml
type: email
name: email_default
log_level: info
format: |
Alert from CrowdSec on {{.MachineID}}:
{{range .Decisions}}
- {{.Scenario}} triggered for {{.Value}} ({{.Type}})
{{end}}
smtp_host: smtp.yourdomain.com
smtp_username: [email protected]
smtp_password: your_smtp_password
smtp_port: 587
sender_email: [email protected]
receiver_emails:
- [email protected]
# Register the notification plugin
cscli notifications add /etc/crowdsec/notifications/email.yaml
# Test notification
cscli notifications test email_default
# Attach notification to a profile
sudo nano /etc/crowdsec/profiles.yaml
# Add: notifications: [email_default] to the relevant profile
Troubleshooting
Bouncer not blocking IPs:
# Check if bouncer is connected to the agent
cscli bouncers list
# Verify API key is correct
cat /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml | grep api_key
# Check nftables rules are present
sudo nft list ruleset | grep -A5 crowdsec
# Restart both services
sudo systemctl restart crowdsec
sudo systemctl restart crowdsec-firewall-bouncer
Too many false positives:
# See which scenarios are triggering most
cscli alerts list | sort | uniq -c | sort -rn | head -20
# Remove a specific scenario
cscli scenarios remove crowdsecurity/too-aggressive-scenario
# Reduce threshold by editing the scenario config
ls /etc/crowdsec/scenarios/
Console enrollment not working:
# Verify outbound connectivity
curl -I https://api.crowdsec.net
# Re-enroll
cscli console unenroll
cscli console enroll NEW_ENROLLMENT_KEY
sudo systemctl restart crowdsec
Conclusion
CrowdSec provides collaborative threat protection where every blocked attack contributes to community-wide threat intelligence. The combination of firewall bouncers for IP-level blocking and Nginx bouncers for application-layer protection gives you defense in depth with minimal performance overhead. Enroll in the Console for access to premium blocklists and centralized management across multiple servers, and tune your allowlists early to avoid blocking legitimate traffic.


