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:

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:

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:

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.