Introduction
CrowdSec is a modern, open-source intrusion prevention system that takes a fundamentally different approach to threat blocking. Rather than relying solely on static rule sets, it builds a collaborative threat intelligence network: when one node detects and blocks an attacker, that IP reputation is shared across the entire CrowdSec community. Every server running CrowdSec benefits from blocks that every other member has already learned.
Under the hood, CrowdSec has three distinct layers:
| Component | Role |
|---|---|
| Agent | Reads logs, runs detection scenarios, raises alerts |
| Local API (LAPI) | Stores decisions, exposes REST API to bouncers |
| Bouncer | Enforces decisions — blocks at the firewall, nginx, Cloudflare, etc. |
This separation means you can have multiple bouncers enforcing a single set of decisions, and the agent itself never touches the firewall.
By the end of this guide you will have:
- CrowdSec agent installed and processing logs
cs-firewall-bouncerblocking malicious IPs via nftables/iptables- Your node enrolled in the CrowdSec console for centralized visibility
- Scenario tuning to eliminate false positives
Prerequisites
Before you start, verify the following:
# Confirm OS and kernel
uname -r
cat /etc/os-release
# Confirm you have a supported firewall backend
nft --version # nftables (preferred)
iptables --version # fallback
# Confirm systemd
systemctl --version
# Check a log source exists (SSH is universal)
ls -lh /var/log/auth.log /var/log/secure 2>/dev/null
journalctl -u ssh --no-pager -n 5You will also need outbound HTTPS (443) to reach the CrowdSec Central API at api.crowdsec.net for community threat intelligence. Airgapped installs are possible but not covered here.
Step 1 — Install the CrowdSec Agent
CrowdSec maintains an official APT/YUM repository. Do not install from generic package managers — the distro-packaged versions are often months behind.
Debian / Ubuntu
# Add the CrowdSec repository
curl -s https://install.crowdsec.net | sudo sh
# Install the agent
sudo apt-get update && sudo apt-get install -y crowdsecRHEL / Rocky / AlmaLinux
curl -s https://install.crowdsec.net | sudo sh
sudo dnf install -y crowdsecVerify the service started
sudo systemctl status crowdsec
sudo cscli versionExpected output includes the agent version and a confirmation that the Local API is running on 127.0.0.1:8080.
Step 2 — Review Detected Log Sources
CrowdSec auto-detects running services during installation and configures matching log parsers (called acquisitions). Verify what was detected:
sudo cscli collections list
sudo cat /etc/crowdsec/acquis.yamlIf your web server or application logs are missing, add them manually:
# Example: add nginx access logs
sudo tee -a /etc/crowdsec/acquis.yaml <<'EOF'
---
filenames:
- /var/log/nginx/access.log
labels:
type: nginx
EOF
sudo systemctl reload crowdsecAvailable log types (labels): syslog, nginx, apache2, traefik, postfix, mysql, postgresql, ssh, and many more from the CrowdSec Hub.
Step 3 — Install the Firewall Bouncer
The agent detects threats; the bouncer enforces blocks. Install the firewall bouncer which integrates with nftables or iptables:
# Debian/Ubuntu
sudo apt-get install -y crowdsec-firewall-bouncer-nftables
# RHEL/Rocky
sudo dnf install -y crowdsec-firewall-bouncer-nftablesThe bouncer registers itself with the local API automatically. Confirm it is enrolled:
sudo cscli bouncers listYou should see cs-firewall-bouncer listed with an API key and a recent Last Pull timestamp.
Bouncer configuration
The bouncer config lives at /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml. Review the firewall mode:
# /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml (relevant section)
mode: nftables # or 'iptables' — nftables preferred on modern kernels
deny_action: DROP
deny_log: true # log blocked packets to syslogRestart the bouncer after any config change:
sudo systemctl restart crowdsec-firewall-bouncer
sudo systemctl enable crowdsec-firewall-bouncerStep 4 — Enroll in the CrowdSec Console
The CrowdSec Console (app.crowdsec.net) gives you a dashboard over all your nodes, centralized alert management, and access to the Threat Intelligence blocklist subscriptions.
- Create a free account at
https://app.crowdsec.net - Click Add Instance → copy your enrollment token
- Enroll your agent:
sudo cscli console enroll <YOUR_ENROLLMENT_TOKEN>
sudo systemctl reload crowdsec- Accept the instance in the Console UI (it appears under Instances → Pending)
Once enrolled, alerts and metrics from your node are visible in the dashboard and you gain access to community threat intelligence feeds.
Step 5 — Install Additional Detection Collections
CrowdSec Hub hosts pre-built collections (parsers + scenarios) for hundreds of services. Install what matches your stack:
# Browse available collections
sudo cscli hub list
# Install collections for your services
sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/linux
sudo cscli collections install crowdsecurity/mysql
sudo cscli collections install crowdsecurity/postfix
# Update all installed hub items
sudo cscli hub update
sudo cscli hub upgrade
# Reload after changes
sudo systemctl reload crowdsecEach collection bundles together the parser (log format understanding) and relevant scenarios (attack patterns like brute-force, scanning, credential stuffing).
Step 6 — Tune Decisions and Whitelists
View active decisions (currently blocked IPs)
# List all active bans
sudo cscli decisions list
# Filter by scenario
sudo cscli decisions list --scenario crowdsecurity/ssh-bf
# Filter by a specific IP
sudo cscli decisions list --ip 198.51.100.42Manually ban or unban an IP
# Ban an IP for 24 hours
sudo cscli decisions add --ip 198.51.100.42 --duration 24h --reason "manual ban"
# Remove a specific ban (e.g. false positive)
sudo cscli decisions delete --ip 198.51.100.42
# Remove all bans (use with care)
sudo cscli decisions delete --allCreate a whitelist to prevent false positives
If your monitoring system, backup server, or VPN exit node is getting banned, whitelist it:
sudo tee /etc/crowdsec/parsers/s02-enrich/whitelist.yaml <<'EOF'
name: company/mywhitelist
description: Whitelist trusted internal hosts
whitelist:
reason: "Trusted internal source"
ip:
- "10.0.0.0/8"
- "192.168.1.0/24"
cidr:
- "172.16.0.0/12"
EOF
sudo systemctl reload crowdsecStep 7 — Configure Notification Alerts (Optional)
CrowdSec supports alerting via email, Slack, Splunk, and custom HTTP webhooks. Configure a Slack notification:
# Install the Slack plugin
sudo cscli notifications install slack
# Edit the plugin config
sudo nano /etc/crowdsec/notifications/slack.yaml# /etc/crowdsec/notifications/slack.yaml
type: slack
name: slack_default
log_level: info
format: |
{{range . -}}
🚨 *CrowdSec Alert* — `{{.Scenario}}`
IP: `{{.Source.Ip}}` | Decisions: {{.Decisions | len}}
{{end}}
url: https://hooks.slack.com/services/YOUR/SLACK/WEBHOOKWire it into your profile:
# /etc/crowdsec/profiles.yaml — add to the existing ban profile
sudo nano /etc/crowdsec/profiles.yaml# Add under the existing profile's 'notifications:' block
notifications:
- slack_defaultsudo systemctl reload crowdsec
# Send a test notification
sudo cscli notifications test slack_defaultVerification and Testing
Check the agent is processing logs and raising alerts
# Tail live alerts
sudo cscli alerts list --limit 20
# Watch the agent log in real time
sudo journalctl -u crowdsec -f
# Check parsing metrics (should show lines read/parsed/unparsed)
sudo cscli metricsSimulate a brute-force to confirm detection and blocking
From a separate machine (or a VM you control), simulate a brute-force attempt:
# On a test machine — this will trigger the ssh-bf scenario
for i in $(seq 1 12); do
ssh invalid_user@<YOUR_SERVER_IP> 2>/dev/null || true
sleep 0.5
doneBack on your server, within 30–60 seconds:
# Confirm alert was raised
sudo cscli alerts list --limit 5
# Confirm the IP was banned
sudo cscli decisions list
# Confirm nftables has the block rule
sudo nft list ruleset | grep -A5 crowdsecYou should see the test machine's IP in the decision list and in the nftables ruleset.
Verify the bouncer is enforcing blocks
# Check bouncer metrics
sudo cscli metrics --scenario crowdsecurity/ssh-bf
# Confirm nftables CrowdSec sets are populated
sudo nft list set inet crowdsec crowdsec-blacklistsTroubleshooting
Agent not parsing logs
# Check acquis.yaml file paths exist
sudo cscli explain --log "/var/log/auth.log" --type syslog --verboseThis runs a line through the parser pipeline and shows exactly where it fails.
Bouncer not blocking despite active decisions
sudo systemctl status crowdsec-firewall-bouncer
sudo journalctl -u crowdsec-firewall-bouncer -n 50
# Confirm the API key is valid
sudo cscli bouncers listToo many false positives (legitimate scanners, monitoring) Check which scenario is triggering and raise its threshold:
sudo cscli scenarios inspect crowdsecurity/http-crawl-non_statics
# Edit /etc/crowdsec/scenarios/ to adjust min_count or leakspeedCannot enroll in Console (firewall blocking API)
# Test outbound connectivity
curl -s https://api.crowdsec.net/v2/ping
# Should return {"message":"pong"}Ensure TCP 443 outbound to api.crowdsec.net is permitted.
High CPU on agent This usually means a very high log throughput. Tune acquisitions to skip verbose debug logs:
# acquis.yaml — exclude noisy paths
filenames:
- /var/log/nginx/access.log
exclude_regexps:
- "GET /healthz"
- "GET /metrics"
labels:
type: nginxSummary
You now have a fully operational CrowdSec stack:
- Agent reading logs and detecting attack patterns via community-maintained scenarios
- Firewall bouncer dropping malicious IPs at the nftables level before they reach your application
- Console enrollment giving you centralized visibility and community threat intelligence
- Whitelists protecting trusted IPs from accidental bans
- Notification alerts sending real-time Slack messages on new bans
CrowdSec's key advantage over traditional IPS tools is that every server in the network strengthens every other — when an attacker probes one CrowdSec node, the resulting reputation signal is shared globally within minutes. Combined with its modular bouncer architecture (Cloudflare, nginx, HAProxy, pfSense, and dozens more are available on the Hub), it is a strong foundation for any internet-facing Linux server.
Next steps:
- Subscribe to premium blocklists in the Console (Firehol, FullBogons, etc.)
- Deploy the
crowdsec-nginx-bouncerorcrowdsec-traefik-bouncerfor application-layer enforcement - Set up multi-server high availability using a remote LAPI with a shared PostgreSQL backend
- Explore
cscli hubtestto validate custom scenarios before deploying them to production