Skip to content
Go back

Fail2ban vs CrowdSec: Blocking the Bots Actually Smartly

By SumGuy 6 min read
Fail2ban vs CrowdSec: Blocking the Bots Actually Smartly

Your server wakes up one morning with 47,000 SSH login attempts from three continents. You didn’t sleep. Your logs are screaming. Sound familiar?

Welcome to self-hosting in 2026. The bots are relentless, and they’re not even trying to be subtle. Brute-force attacks on SSH, web scrapers hammering your WordPress REST API, credential stuffing against your Nextcloud login — this is Tuesday.

Two tools have your back here: Fail2ban and CrowdSec. They’re not enemies. They’re not even quite the same thing. But understanding the difference between “blocking IPs that attacked you” and “blocking IPs before they attack you” will save your sanity.

The Threat Landscape: Why You Need Anything At All

Let me paint the picture. Right now, thousands of IP addresses are running automated scans. They’re looking for:

These aren’t sophisticated. They’re not targeting you specifically. They’re just scanning the entire internet, throwing spaghetti at walls, and checking what sticks. But they’re persistent. And they’re everywhere.

The goal of any intrusion prevention system: stop the noise before it drains your server, and ideally, stop the attack before it even gets close.

Fail2ban: The Classic Approach

Fail2ban’s been around since 2004, and it does one thing very well: it reads your logs, spots patterns of bad behavior, and bans the IP address doing it.

Here’s the flow:

  1. Attacker tries SSH brute force → creates failed login entries in /var/log/auth.log
  2. Fail2ban regex watches that log in real-time
  3. After 5 failed attempts in 10 minutes → ban the IP for 24 hours
  4. Ban = firewall rule (iptables/nftables) or Cloudflare API call

It’s reactive. It waits for the attack, detects it, then hits the kill switch. By that point, your server’s already been poked. Not ideal, but effective.

Installing and Configuring Fail2ban

Terminal window
sudo apt update && sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Create a local override for the default SSH jail:

jail.local
[DEFAULT]
bantime = 86400
findtime = 600
maxretry = 5
destemail = your-email@example.com
sendername = Fail2ban
action = %(action_mwl)s
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s

This says: “If someone fails SSH auth 5 times in 10 minutes, ban them for 24 hours and email me about it.”

Check what’s been banned:

Terminal window
sudo fail2ban-client status sshd
sudo iptables -L -n | grep DROP # see the actual firewall rules

Unban an IP if you fat-fingered it:

Terminal window
sudo fail2ban-client set sshd unbanip 203.0.113.45

The catch: Fail2ban only knows about attacks it sees on your server. If a botnet is scanning the world and 10,000 servers are blocking them, Fail2ban doesn’t benefit from that collective intelligence. You’re flying blind, learning only from your own traffic.

CrowdSec: The Evolution

CrowdSec is what Fail2ban would build if it had friends.

Same core idea — parse logs, detect attacks, ban IPs. But with a twist: CrowdSec agents send anonymized attack telemetry back to a central community network. You get the global blocklist in return. You’re not just blocking attackers after they hit you; you’re blocking IPs that attacked someone else in Tokyo before they get to your server in Toronto.

How CrowdSec Works

┌─────────────────────────────────────────────────┐
│ Your Server │
│ ├─ CrowdSec Agent (reads logs) │
│ └─ Bouncer (applies blocks: firewall/WAF) │
└──────────────┬──────────────────────────────────┘
┌───────▼────────┐
│ Central LAPI │
│ (community) │
└───────┬────────┘
┌──────────┴──────────┐
│ Global blocklist │
│ + threat intel │
└─────────────────────┘

Three pieces:

  1. Agent: Runs on your server, reads logs (SSH, Nginx, Apache, anything), detects attacks, shares telemetry
  2. LAPI (Local API): Central repository that syncs global threat intel to your local installation
  3. Bouncer: Enforces blocks (Nginx plugin, iptables, Cloudflare API, whatever)

Installing CrowdSec

Terminal window
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install crowdsec crowdsec-firewall-bouncer
sudo systemctl enable crowdsec
sudo systemctl start crowdsec

Enroll to the community (free, optional, but recommended):

Terminal window
sudo cscli console enroll --overwrite <enrollment-key>

Check what’s being blocked:

Terminal window
sudo cscli decisions list
sudo cscli metrics show

CrowdSec + Nginx Bouncer

If you’re running Nginx, install the bouncer:

Terminal window
sudo apt install crowdsec-nginx-bouncer

Configure Nginx to use it:

/etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf
ENABLED=true
API_URL=http://localhost:8080
API_KEY=<your-api-key>
BOUNCER_LOG_LEVEL=info

Add this to your Nginx config:

location / {
access_by_lua_file /usr/local/lua/crowdsec_nginx_bouncer.lua;
proxy_pass http://backend;
}

Reload Nginx:

Terminal window
sudo nginx -t && sudo systemctl reload nginx

Now Nginx will block requests from IPs in the CrowdSec decision list before they even hit your app.

CrowdSec Dashboard and CLI

The community dashboard shows you global attacks:

Terminal window
sudo cscli dashboard

Runs on http://localhost:3000 by default.

View active decisions:

Terminal window
sudo cscli decisions list
sudo cscli alerts list

Manually add an IP to the blocklist:

Terminal window
sudo cscli decisions add --ip 203.0.113.99 --duration 24h --reason "manual block"

Fail2ban + CrowdSec: Can You Run Both?

Absolutely. They don’t fight. Fail2ban bans locally, CrowdSec shares globally. In fact, they’re complementary:

Run both. Fail2ban first (it’s lighter), CrowdSec second (it’s smarter).

Handling False Positives

Fail2ban:

CrowdSec:

Decision Guide

Use Fail2ban alone if:

Add CrowdSec if:

Run both if:

The Reality

Here’s the thing: bots are dumb. They’re not targeting you. They’re just running through IP ranges like a telemarketer dialing phone numbers. Fail2ban stops the ones that get to you. CrowdSec stops the ones that didn’t need to reach you at all.

Neither is magic. A real attacker with patience and a botnet spanning thousands of IPs will eventually get through any blacklist. But for the 99.9% of attacks — the commodity brute-force noise that wakes you up at 3 AM — both tools are brutally effective.

Set one up tonight. You’ll sleep better tomorrow.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Linux Capabilities: Drop Root Without Breaking Everything
Next Post
Sysctl Tuning: The Linux Kernel Knobs That Actually Matter

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts