Deploy CrowdSec on Linux: Building a Distributed IPS to Block Brute Force and Web Attacks

Security tutorial - IT technology blog
Security tutorial - IT technology blog

At 2:14 AM last Tuesday, PagerDuty lit up my phone with memory alerts across three production nodes. System RAM had surged past 92%, and Nginx worker processes were thrashing under roughly 4,000 incoming requests per second. Digging into /var/log/auth.log and our Nginx access logs revealed a classic low-and-slow coordinated sweep.

An adversary was spraying credential-stuffing payloads against our /api/v1/auth/login route while simultaneously probing SSH on port 22. Instead of blasting traffic from a handful of data center IPs, the attacker cycled through roughly 8,500 residential proxies. Each IP hit our endpoints just once every five minutes—flying well under our standard rate-limiting thresholds.

Approach Comparison: Isolated Defense vs. Collaborative Threat Intelligence

When attacks arrive from thousands of rotating residential addresses, standalone defense tools fail. Examining how traditional log analyzers compare to a modern collaborative intrusion prevention system (IPS) makes the root problem clear.

1. The Standalone Log Watcher (e.g., Fail2Ban)

Tools like Fail2Ban read local log files with regular expressions. When an individual IP exceeds a preset limit—say, five failed SSH attempts within ten minutes—it writes a temporary drop rule into iptables or nftables. That mechanism handles noisy script runs from single VPS instances effectively.

Distributed botnets completely bypass that logic. If an attacker coordinates 10,000 nodes so each attempts just one login per day, Fail2Ban never crosses its threshold. Your server absorbs the attack in isolation. It cannot tell that the same IP targeted five hundred other servers only minutes earlier.

2. The Centralized Enterprise SIEM / Cloud WAF

Cloud edge providers (like Cloudflare or AWS WAF) and managed SIEMs maintain massive global threat feeds. They filter HTTP traffic well before it reaches your origin. But they carry trade-offs. Per-request fees mount quickly when traffic surges, and edge proxies cannot protect raw TCP services like SSH, SFTP, or custom socket listeners running at the kernel level.

3. Collaborative Detection and Remediation (CrowdSec)

CrowdSec splits security into two decoupled roles: detection (the Security Engine) and enforcement (Bouncers). The core daemon parses logs locally using Go routines and declarative YAML scenarios. When your server flags a malicious actor, it blocks the IP locally and forwards an anonymized alert to CrowdSec’s central consensus engine.

That central engine processes signals from tens of thousands of active nodes across 180+ countries. It validates reports through consensus algorithms, weeds out false positives, and pushes curated blocklists back to all participating nodes. Your Linux host drops rogue packets before an attacker ever touches your stack, simply because another server on the network already caught them.

Pros and Cons: Evaluating CrowdSec for Production Workloads

Every architectural choice involves trade-offs. Here is how CrowdSec balances out in production environments.

Advantages

  • Community-Driven Threat Intelligence: You gain proactive protection against 50,000+ active malicious IPs without manual list curation or expensive commercial threat subscriptions.
  • Decoupled Architecture: Log parsing operates independently from firewall enforcement. You can analyze logs on an application server and drop packets at an edge router, or serve an automatic captcha via an Nginx or Traefik bouncer.
  • Minimal Footprint: Built in Go, the CrowdSec daemon typically idles around 40–60 MB of RAM and uses less than 1% CPU under moderate traffic, far lighter than Java-based SIEM agents or Python scrapers.
  • Extensible Hub: Community-maintained parsers and scenarios for Nginx, SSH, Postfix, Docker, and PostgreSQL install in seconds using the cscli package manager.

Drawbacks

  • Multi-Component Setup: The engine merely detects attacks; it will not block anything on its own. You must install a separate remediation bouncer (such as the nftables bouncer) to drop packets. Skipping this step leaves servers unprotected.
  • Outbound Connectivity Required: While local parsing and cached blocklists work fine offline, fetching community consensus updates requires outbound HTTPS access (port 443) to CrowdSec’s central API.

Recommended Setup: Architecture and Topology

For a resilient Linux bastion or single-node production server, run the following stack:

  1. CrowdSec Security Engine: Reads systemd journals, SSH auth logs, and web server logs (Nginx/Caddy) to track behavioral patterns.
  2. Firewall Remediation Bouncer (nftables / iptables): Communicates with the Local API (LAPI) over port 8080 and writes drop rules straight into the Linux kernel packet filter.
  3. CrowdSec Hub Collections: Pre-packaged detection profiles such as crowdsecurity/linux, crowdsecurity/sshd, and crowdsecurity/nginx.

Lock down administrative credentials before exposing new intrusion tools on public interfaces. Whenever I spin up new nodes or rotate operational credentials during an incident, I generate high-entropy root and service passwords with the browser-based password generator at toolcraft.app/en/tools/security/password-generator. It operates purely client-side without transmitting credentials over the wire. Once baseline access is locked down, we can configure automated defenses.

Implementation Guide: Step-by-Step Deployment on Linux

The following deployment steps target Ubuntu 22.04 / 24.04 and Debian 12 systems.

Step 1: Install the CrowdSec Repository and Engine

Add the official package repository using CrowdSec’s automated setup script, then install the core daemon:

# Download and register the official repository package
curl -s https://install.crowdsec.net | sudo bash

# Install the CrowdSec security engine
sudo apt-get update
sudo apt-get install -y crowdsec

During installation, the engine scans /var/log for running services like OpenSSH or Nginx. It automatically generates the initial log acquisition paths inside /etc/crowdsec/acquis.yaml.

Step 2: Verify Log Acquisition and Collections

Check which services CrowdSec detected and view your installed detection scenarios:

# Verify detected log sources and parser throughput
sudo cscli metrics

# Review active collections
sudo cscli collections list

If you run Nginx or another reverse proxy, install the relevant scenario collections directly from the CrowdSec Hub:

# Install standard Nginx and HTTP protection scenarios
sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/http-cve

# Reload CrowdSec to apply new scenarios
sudo systemctl reload crowdsec

Step 3: Install the Firewall Remediation Bouncer

The core engine only detects attacks. You need a remediation component to execute blocks. On modern Linux distributions running nftables, install the native bouncer package:

# Install the firewall remediation bouncer
sudo apt-get install -y crowdsec-firewall-bouncer-nftables

Confirm that the bouncer registered itself with the Local API (LAPI):

# List registered bouncers
sudo cscli bouncers list

The output will show crowdsec-firewall-bouncer-nftables with a valid API key and active status.

Step 4: Test and Inspect Active Decisions

CrowdSec pulls community consensus blocklists right after starting up. You can inspect the local decision database to confirm active bans:

# View current active bans and community consensus blocks
sudo cscli decisions list

To verify that local blocking functions under real conditions, simulate a temporary manual ban against an RFC 5737 test address:

# Apply a 15-minute test ban on a test IP
sudo cscli decisions add --ip 192.0.2.1 --duration 15m --reason "manual test ban"

# Confirm the rule is registered
sudo cscli decisions list --ip 192.0.2.1

# Remove the test decision
sudo cscli decisions delete --ip 192.0.2.1

Step 5: Enrolling in the Central Console

To gain visibility across an entire server fleet and monitor inbound attacks from a single dashboard, link your node to the CrowdSec Console (free for individual operators):

# Enroll your instance using your console enrollment token
sudo cscli console enroll <YOUR_ENROLLMENT_KEY>

# Restart the service to establish synchronization
sudo systemctl restart crowdsec

Back on that 2 AM triage call, CrowdSec cut through the noise in under twenty minutes. As soon as the nftables bouncer came online, it dropped over 3,200 rogue residential IP connections directly at the Linux kernel packet filter. Nginx worker CPU loads plunged from 98% down to 4%, freeing up RAM and keeping legitimate customer traffic flowing uninterrupted.

Share: