Fail2Ban watches your logs and bans IP addresses that misbehave. It works, but it works alone. Every server running Fail2Ban learns the same lessons independently — the brute-force attack that hit your SSH port at 3 AM was probably hitting thousands of other servers at the same time, yet none of them shared that intelligence with yours. CrowdSec changes this equation entirely by pooling threat detection across more than 200,000 participating servers worldwide.
CrowdSec is an open-source intrusion prevention system that combines local log analysis with a community-driven threat intelligence network. When one server detects an attack, every other server in the network benefits. Think of it as a neighborhood watch for the internet — and your Ubuntu VPS is about to join.
MassiveGRID Ubuntu VPS includes: Ubuntu 24.04 LTS pre-installed · Proxmox HA cluster with automatic failover · Ceph 3x replicated NVMe storage · Independent CPU/RAM/storage scaling · 12 Tbps DDoS protection · 4 global datacenter locations · 100% uptime SLA · 24/7 human support rated 9.5/10
Deploy a self-managed VPS — from $1.99/mo
Need dedicated resources? — from $19.80/mo
Want fully managed hosting? — we handle everything
How CrowdSec Works: Three Components
CrowdSec's architecture separates detection from enforcement, which is a fundamentally different approach from Fail2Ban's monolithic design. Understanding these three components clarifies why CrowdSec is so effective:
The Security Engine (Agent) parses your log files in real time and matches patterns against scenarios — predefined behavioral rules. When a scenario triggers (for example, 10 failed SSH login attempts in 30 seconds), the engine creates a decision — a record that says "block this IP for 4 hours."
Bouncers are enforcement plugins that act on decisions. A firewall bouncer adds iptables rules. An Nginx bouncer returns 403 responses. A WordPress bouncer blocks at the application level. You can run multiple bouncers simultaneously, each protecting a different layer.
The Central API and Community Blocklists are what make CrowdSec unique. Your engine reports aggressive IPs to the CrowdSec Central API (with your consent). In return, you receive a curated blocklist of IPs that are actively attacking other servers. This means your server blocks known attackers before they even send their first packet to you.
CrowdSec vs Fail2Ban: Complementary, Not Replacement
A common misconception is that CrowdSec replaces Fail2Ban. In practice, they serve different roles and work well together:
- Fail2Ban excels at simple, immediate reactions — ban an IP after N failed attempts. It is battle-tested, has filters for hundreds of applications, and requires minimal resources.
- CrowdSec excels at behavioral analysis and collective intelligence — detecting sophisticated attack patterns and sharing threat data across a global network.
- Together, Fail2Ban handles basic brute-force protection with near-zero overhead while CrowdSec layers on community intelligence and more nuanced detection scenarios.
Running both is not redundant. Fail2Ban catches the simple cases fast. CrowdSec catches the clever cases and blocks known-bad actors preemptively.
Prerequisites
Before installing CrowdSec, ensure your Ubuntu VPS has a baseline security configuration in place. If you haven't already, follow our Ubuntu VPS security hardening guide to set up SSH key authentication, disable root login, and configure UFW.
You'll need:
- Ubuntu 24.04 LTS with root or sudo access
- A running web server (Nginx or Apache) generating access logs
- At least 1 vCPU and 512 MB RAM (CrowdSec is lightweight)
- Basic familiarity with log file locations on your system
Installing the CrowdSec Security Engine
CrowdSec provides an official APT repository for Ubuntu. Install the engine with:
curl -s https://install.crowdsec.net | sudo bash
sudo apt install crowdsec
During installation, CrowdSec automatically detects services running on your server and installs appropriate log parsers (called "collections"). Verify what was detected:
sudo cscli collections list
You should see collections like crowdsecurity/linux, crowdsecurity/sshd, and if Nginx is running, crowdsecurity/nginx. If a collection is missing, install it manually:
# Install Nginx collection if not auto-detected
sudo cscli collections install crowdsecurity/nginx
# Install base HTTP scenarios
sudo cscli collections install crowdsecurity/base-http-scenarios
Check that the CrowdSec engine is running:
sudo systemctl status crowdsec
sudo cscli metrics
The cscli metrics command shows parsed log lines, active decisions, and scenario triggers. On a fresh install, these numbers will be low — they grow as the engine processes logs.
Installing the Firewall Bouncer
The engine detects threats but does not block them by itself. You need a bouncer to enforce decisions. The firewall bouncer is the most common choice — it adds iptables/nftables rules to drop traffic from banned IPs:
sudo apt install crowdsec-firewall-bouncer-iptables
Verify the bouncer is registered:
sudo cscli bouncers list
You should see a bouncer entry with a status of "validated." The firewall bouncer runs as a separate systemd service and polls the CrowdSec Local API for new decisions every 10 seconds by default.
Installing the Nginx Bouncer (Optional but Recommended)
If you run Nginx, adding the Nginx bouncer provides application-layer blocking with more granular responses — you can serve CAPTCHAs instead of outright bans, or return custom error pages:
sudo apt install crowdsec-nginx-bouncer
After installation, add the bouncer directives to your Nginx configuration. Edit your server block:
server {
listen 80;
server_name example.com;
# CrowdSec Nginx bouncer
lua_shared_dict crowdsec_cache 50m;
resolver 127.0.0.1 ipv6=off;
access_by_lua_file /usr/lib/crowdsec/lua/plugins/crowdsec/access.lua;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
Reload Nginx after making changes:
sudo nginx -t && sudo systemctl reload nginx
On a MassiveGRID Cloud VPS, you already have network-level protection (12 Tbps DDoS mitigation). CrowdSec adds application-level threat intelligence shared across 200,000+ servers.
Configuring Log Parsing
CrowdSec needs to know which log files to watch. The acquisition configuration lives in /etc/crowdsec/acquis.yaml. Review the auto-generated configuration:
sudo cat /etc/crowdsec/acquis.yaml
A typical configuration for Nginx and SSH looks like:
filenames:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
labels:
type: nginx
---
filenames:
- /var/log/auth.log
labels:
type: syslog
For WordPress sites, add a dedicated section. First install the WordPress collection:
sudo cscli collections install crowdsecurity/wordpress
Then add WordPress logs to your acquisition file:
---
filenames:
- /var/log/nginx/access.log
labels:
type: nginx
# WordPress-specific scenarios will match wp-login.php patterns
For custom applications that write structured logs, you can create custom parsers. But in most cases, the built-in HTTP and SSH scenarios cover the major attack vectors. After modifying acquis.yaml, restart CrowdSec:
sudo systemctl restart crowdsec
Enrolling in the CrowdSec Console
The CrowdSec Console is a free web dashboard that lets you monitor your instances, view alerts, manage blocklists, and — most importantly — subscribe to the community blocklist. Sign up at app.crowdsec.net and enroll your instance:
# The console will give you an enrollment key
sudo cscli console enroll YOUR_ENROLLMENT_KEY
After enrolling, approve the instance in the web console. Then enable the community blocklist:
sudo cscli console enable community-blocklist
sudo systemctl restart crowdsec
With the community blocklist active, your server immediately starts blocking IPs that are currently attacking other CrowdSec participants. This typically adds thousands of blocked IPs on day one — attackers that have never touched your server but are known threats globally.
Verify the blocklist is active:
sudo cscli decisions list --origin CAPI | head -20
Testing Detection Safely
Never test CrowdSec by launching real attacks against your own server from your current IP — you'll lock yourself out. Instead, use CrowdSec's built-in testing tools and controlled simulations.
Test the SSH brute-force scenario from a non-critical IP or a disposable VM:
# From a DIFFERENT machine (not your main connection):
for i in $(seq 1 15); do ssh invalid@YOUR_SERVER_IP; done
Then check if a decision was created:
sudo cscli decisions list
You should see the attacking IP with a "ban" decision type and a duration. To test HTTP scenarios, you can simulate path scanning:
# From a different machine:
for i in $(seq 1 50); do curl -s "http://YOUR_SERVER_IP/.env" > /dev/null; done
If CrowdSec catches it, you'll see a decision for the "http-sensitive-files" or "http-probing" scenario. You can also manually add and remove decisions for testing:
# Manually ban an IP (for testing bouncer behavior)
sudo cscli decisions add --ip 192.0.2.100 --duration 1h --reason "manual test"
# Remove the test ban
sudo cscli decisions delete --ip 192.0.2.100
Whitelisting and False Positive Management
False positives happen. Legitimate monitoring services, search engine crawlers, or your own scripts can trigger scenarios. CrowdSec handles whitelisting through parser-level configuration.
Create a whitelist file:
sudo nano /etc/crowdsec/parsers/s02-enrich/my-whitelists.yaml
Add your trusted IPs and ranges:
name: my-whitelists
description: "Whitelist internal and trusted IPs"
whitelist:
reason: "Internal and monitoring IPs"
ip:
- "YOUR_HOME_IP"
- "10.0.0.0/8"
- "172.16.0.0/12"
cidr:
- "YOUR_OFFICE_CIDR/28"
Restart CrowdSec after adding whitelists:
sudo systemctl restart crowdsec
To investigate a potential false positive, check which scenario triggered and review the alert details:
# View recent alerts
sudo cscli alerts list
# Inspect a specific alert
sudo cscli alerts inspect ALERT_ID
If you find a scenario that's too aggressive for your environment, you can adjust its threshold or disable it entirely:
# Remove a noisy scenario
sudo cscli scenarios remove crowdsecurity/http-bad-user-agent
Running CrowdSec Alongside Fail2Ban
Running both systems simultaneously is straightforward because they operate independently. Fail2Ban reads logs and manages its own iptables chain. CrowdSec reads the same logs (which is fine — reading doesn't create contention) and manages a separate iptables chain via its bouncer.
The recommended complementary setup:
- Fail2Ban: Keep it for SSH (fast ban after 3-5 failures), and any custom jails you've already configured
- CrowdSec: Handle HTTP-level scenarios (path probing, credential stuffing, scanner detection) and provide the community blocklist
CrowdSec's detection engine parses every log line in real time. On a dedicated VPS with guaranteed CPU, this analysis runs without slowdown even during heavy traffic spikes — dedicated CPU ensures detection doesn't lag under load.
To avoid double-banning the same IP for the same offense (which is harmless but clutters your logs), you can disable CrowdSec's SSH collection if Fail2Ban already handles it:
# Optional: let Fail2Ban handle SSH, CrowdSec handle everything else
sudo cscli collections remove crowdsecurity/sshd
Or keep both running for SSH — the redundancy doesn't hurt, and CrowdSec's SSH scenarios detect patterns that Fail2Ban's simple threshold doesn't catch.
Monitoring Decisions and Alerts
CrowdSec provides several ways to monitor what it's catching. The cscli command-line tool is the primary interface:
# Active bans
sudo cscli decisions list
# Recent alerts (with scenario breakdown)
sudo cscli alerts list
# Performance metrics
sudo cscli metrics
# Top attacking IPs
sudo cscli decisions list -o json | jq -r '.[].value' | sort | uniq -c | sort -rn | head -10
For real-time notifications, integrate CrowdSec alerts with your notification system. If you've set up ntfy on your Ubuntu VPS, you can create a simple script that forwards new alerts:
#!/bin/bash
# /usr/local/bin/crowdsec-notify.sh
# Run via cron every 5 minutes
LAST_CHECK_FILE="/tmp/crowdsec-last-check"
NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
if [ -f "$LAST_CHECK_FILE" ]; then
SINCE=$(cat "$LAST_CHECK_FILE")
else
SINCE=$(date -u -d '5 minutes ago' +"%Y-%m-%dT%H:%M:%SZ")
fi
ALERT_COUNT=$(sudo cscli alerts list --since "$SINCE" -o json 2>/dev/null | jq 'length')
if [ "$ALERT_COUNT" -gt 0 ]; then
curl -s \
-H "Title: CrowdSec Alert" \
-H "Priority: high" \
-H "Tags: shield" \
-d "$ALERT_COUNT new CrowdSec alerts in the last 5 minutes" \
http://localhost:8080/security
fi
echo "$NOW" > "$LAST_CHECK_FILE"
Add to cron:
*/5 * * * * /usr/local/bin/crowdsec-notify.sh
The Three-Layer Security Stack
Security works best in layers, where each layer compensates for the blind spots of the others. With CrowdSec running on a MassiveGRID VPS, you have three distinct protection layers:
Network layer (MassiveGRID infrastructure): 12 Tbps DDoS mitigation absorbs volumetric attacks before they reach your VPS. This handles the attacks that would overwhelm any software-based solution.
Application layer (CrowdSec + Fail2Ban): Log-based detection catches brute-force attempts, credential stuffing, path scanning, and application-specific attacks. The community blocklist preemptively blocks known threats.
OS layer (UFW + SSH hardening): Firewall rules limit exposed ports. SSH key authentication eliminates password-based attacks. Fail2Ban catches anything that slips through.
No single layer is sufficient. DDoS protection doesn't stop credential stuffing. CrowdSec doesn't stop volumetric floods. UFW doesn't detect application-level attacks. Together, they cover the full spectrum of common threats.
Prefer Managed Threat Response?
CrowdSec improves your security posture automatically through community intelligence, but you still manage the installation, configuration, whitelist maintenance, and false positive investigation. When security is business-critical and you need guaranteed response times, MassiveGRID's fully managed hosting handles intrusion detection, firewall management, security patching, and incident response — so you can focus on building your application instead of defending it.