Context & Why It Is Needed
At 2:00 AM, my phone buzzed violently with a PagerDuty alert. CPU usage on our SSH bastion cluster spiked to 96%. I rushed to open the terminal and inspect the logs:
sudo journalctl -u ssh -f
Lines reading Failed password for invalid user were pouring in like a waterfall—nearly 300 requests per second. A distributed brute-force attack was targeting the cluster. Fail2ban on the host began to choke. Relying on Python-based regex log parsing, it chewed up an entire CPU core as traffic skyrocketed.
An even bigger issue was the botnet’s strategy. The attackers rotated through a pool of tens of thousands of IPs. Each IP attempted only a single authentication before switching. Fail2ban’s familiar threshold of maxretry = 5 was rendered completely useless.
That is what drove me to switch to CrowdSec. Written in Go, CrowdSec consumes negligible RAM and CPU. More importantly, it operates on a Collaborative Threat Intelligence model. Whenever any node in the global network spots an IP scanning for vulnerabilities, that IP is submitted to the central network. Your server automatically pulls down these blocklists and drops traffic straight at the network layer.
CrowdSec’s architecture is cleanly decoupled into two components:
- Security Engine: Ingests logs, analyzes behavior against predefined scenarios, and issues remediation decisions (IP bans, captchas).
- Remediation Component (Bouncer): Enforces decisions from the Engine by directly dropping packets via nftables, iptables, Nginx, or Cloudflare.
Installation
To prevent firewall rule conflicts on Ubuntu/Debian, stop Fail2ban before adding the CrowdSec repository.
# Stop and disable Fail2ban
sudo systemctl stop fail2ban
sudo systemctl disable fail2ban
# Add official CrowdSec repository
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
# Install Security Engine
sudo apt-get update
sudo apt-get install -y crowdsec
Right after installation, the Security Engine automatically detects running services (such as OpenSSH and Nginx) and loads matching parsers. However, the Engine only detects threats—it does not drop packets on its own. You need to install a Firewall Bouncer to turn decisions into action:
# Install Firewall Bouncer (auto-detects nftables or iptables)
sudo apt-get install -y crowdsec-firewall-bouncer-iptables
Verify the status of both services:
sudo systemctl status crowdsec
sudo systemctl status crowdsec-firewall-bouncer
Detailed Configuration
1. Configure Log Sources (Acquisition)
The default acquisition configuration file is located at /etc/crowdsec/acquis.yaml. Open it to review settings:
sudo nano /etc/crowdsec/acquis.yaml
Make sure CrowdSec is tailing the correct system log files:
filenames:
- /var/log/auth.log
- /var/log/syslog
labels:
type: syslog
---
filenames:
- /var/log/nginx/*.log
labels:
type: nginx
2. Install Detection Scenarios (Collections)
CrowdSec bundles parsers and detection scenarios into collections. The cscli tool makes managing them effortless. Install the standard rule collections for SSH and Nginx:
# Update hub index to latest version
sudo cscli hub update
# Install protection collections for SSH and Nginx
sudo cscli collections install crowdsecurity/sshd
sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/http-cve
# Reload configuration
sudo systemctl reload crowdsec
While auditing and resetting service account passwords, you can use the utility at toolcraft.app/en/tools/security/password-generator to generate high-entropy random credentials. The logic executes entirely via client-side JavaScript in the browser without transmitting data over the wire, making it safe to paste into your terminal.
3. Connect to CrowdSec Console
CrowdSec provides a free web dashboard to visualize attacks across multiple servers simultaneously. Sign up at app.crowdsec.net, grab your enrollment key, and register your server:
# Enroll node with your console account
sudo cscli console enroll [YOUR_ENROLL_KEY]
# Restart the engine
sudo systemctl restart crowdsec
Testing & Monitoring
Just minutes after running, you can verify protection directly from the terminal.
1. Inspect Attack Alerts
Run the following command to display scans that recently triggered alerts:
sudo cscli alerts list
The returned table provides a clean overview:
+----+------------------+-------------------------------+--------+---------+----+--------+--------------------------------+
| ID | scope | value | reason | country | as | events | created_at |
+----+------------------+-------------------------------+--------+---------+----+--------+--------------------------------+
| 1 | Ip:194.26.29.112 | crowdsecurity/ssh-bf | ban | RU | .. | 6 | 2026-10-30 02:22:15 +0000 UTC |
| 2 | Ip:45.154.255.89 | crowdsecurity/http-crawl-non_ | ban | NL | .. | 42 | 2026-10-30 02:35:40 +0000 UTC |
+----+------------------+-------------------------------+--------+---------+----+--------+--------------------------------+
2. Manage Banned IPs (Decisions)
View currently banned IP addresses:
sudo cscli decisions list
You can also manually ban or unban addresses:
# Manually ban a suspicious IP for 24 hours
sudo cscli decisions add --ip 198.51.100.25 --duration 24h --reason "Manual ban suspicious IP"
# Unban an IP when needed
sudo cscli decisions delete --ip 198.51.100.25
3. Verify Kernel Firewall Rules
The Bouncer synchronizes blocklists directly into an ipset or nftables set. Verify active rules with:
sudo nft list set inet crowdsec crowdsec-blacklists
# Or with iptables:
sudo iptables -L -n -v | grep crowdsec
Thousands of malicious IPs reside efficiently in kernel memory. Malicious packets get dropped at the network interface level without ever touching Nginx or the SSH daemon.
4. Monitor Real-Time Metrics
To inspect log ingestion throughput, run:
sudo cscli metrics
On our server cluster, migrating to CrowdSec dropped CPU load from 95% down to under 6%, even in the middle of active overnight botnet scans.

