CrowdSec: The Modern Collaborative Security Engine to Replace Fail2ban on Linux
🎯 Key Takeaways
- CrowdSec vs Fail2ban: The Core Differences
- Installing CrowdSec on Ubuntu and Debian
- Installing CrowdSec on RHEL, Rocky Linux, and AlmaLinux
- Understanding the Configuration Structure
- Installing and Configuring Collections
📑 Table of Contents
- CrowdSec vs Fail2ban: The Core Differences
- Installing CrowdSec on Ubuntu and Debian
- Installing CrowdSec on RHEL, Rocky Linux, and AlmaLinux
- Understanding the Configuration Structure
- Installing and Configuring Collections
- Installing the Firewall Bouncer
- Installing the Nginx Bouncer
- Monitoring and Managing CrowdSec
- Real-World Example: Blocking SSH Brute Force
- Testing That CrowdSec Is Working
- Advanced CrowdSec Configuration: Custom Parsers and Notifications
If you have been running Linux servers for any length of time, you are almost certainly familiar with Fail2ban — the venerable log-parsing daemon that watches for repeated authentication failures and blocks offending IPs with firewall rules. Fail2ban has served the community well for nearly two decades, but it was designed in an era before the modern threat landscape. It is reactive, it only knows about attacks it has personally witnessed, and its configuration XML can be famously finicky. CrowdSec is the tool built for 2026: it does everything Fail2ban does, adds crowdsourced threat intelligence shared across hundreds of thousands of servers, and separates the detection logic from the remediation layer so you can block attackers at the firewall, application, or CDN level independently.
📑 Table of Contents
- CrowdSec vs Fail2ban: The Core Differences
- Installing CrowdSec on Ubuntu and Debian
- Installing CrowdSec on RHEL, Rocky Linux, and AlmaLinux
- Understanding the Configuration Structure
- Configuring Log Acquisition (acquis.yaml)
- Understanding Profiles (profiles.yaml)
- Installing and Configuring Collections
- Installing the Firewall Bouncer
- Installing the Nginx Bouncer
- Monitoring and Managing CrowdSec
- The CrowdSec Dashboard
- Real-World Example: Blocking SSH Brute Force
- Testing That CrowdSec Is Working
- Advanced CrowdSec Configuration: Custom Parsers and Notifications
- Custom Parsers for Non-Standard Log Formats
- Setting Up Notification Plugins
- Whitelisting Trusted Sources
CrowdSec vs Fail2ban: The Core Differences
Before installing anything, it is worth understanding the architectural differences between the two tools.
Fail2ban is a monolithic daemon. It reads logs, identifies attack patterns using regex, and then directly issues firewall commands (iptables, nftables, etc.) to block the attacker. The entire pipeline — detection and remediation — happens in one process. Its threat intelligence is entirely local: it only knows about an IP after that IP has attacked your specific server.
CrowdSec separates the pipeline into two distinct components:
- The Security Engine (Agent): Parses logs, applies behavior scenarios, and makes blocking decisions. This is what runs on your server.
- Bouncers: Separate lightweight processes that connect to the security engine and actually enforce the decisions — at the firewall, at the web server, at the application layer, or at a CDN.
Additionally, CrowdSec participates in a global threat intelligence network. When your CrowdSec instance detects an attack, it shares the attacker’s IP (in hashed, privacy-preserving form) with the CrowdSec Central API. In return, your instance receives a constantly updated blocklist of IPs that have been attacking other CrowdSec users around the world. This means your server is protected against known attackers from the moment they send their first packet, even before they have targeted you directly.
ubuntu-and-debian">Installing CrowdSec on Ubuntu and Debian
CrowdSec provides official packages for all major distributions. On Ubuntu 22.04, 24.04, or Debian 12:
# Add the CrowdSec repository
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
# Install the security engine
sudo apt-get install crowdsec
# Verify the service is running
sudo systemctl status crowdsec
The installer is reasonably smart about auto-detecting services running on your server. If it finds nginx, Apache, SSH, or other common services, it will automatically configure log acquisition for those services.
rhel-rocky-linux-and-almalinux">Installing CrowdSec on RHEL, Rocky Linux, and AlmaLinux
# Add the CrowdSec repository
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.rpm.sh | sudo bash
# Install the security engine
sudo dnf install crowdsec
# Enable and start the service
sudo systemctl enable --now crowdsec
# Verify the installation
sudo cscli version
Understanding the Configuration Structure
CrowdSec’s configuration lives in /etc/crowdsec/. The files you will interact with most frequently are:
/etc/crowdsec/config.yaml— Main configuration file/etc/crowdsec/acquis.yaml— Log acquisition sources/etc/crowdsec/profiles.yaml— Decision profiles (what to do when an attack is detected)/etc/crowdsec/parsers/— Log parsers for different services/etc/crowdsec/scenarios/— Attack detection scenarios
Configuring Log Acquisition (acquis.yaml)
The acquis.yaml file tells CrowdSec which log files to monitor and what type of log they contain:
# /etc/crowdsec/acquis.yaml
# Monitor SSH authentication logs
- filenames:
- /var/log/auth.log
labels:
type: syslog
# Monitor nginx access logs
- filenames:
- /var/log/nginx/access.log
labels:
type: nginx
# Monitor nginx error logs
- filenames:
- /var/log/nginx/error.log
labels:
type: nginx
# Monitor Apache logs
- filenames:
- /var/log/apache2/access.log
labels:
type: apache2
# Use journald for systems without traditional log files
- source: journalctl
journalctl_filter:
- "_SYSTEMD_UNIT=sshd.service"
labels:
type: syslog
After modifying acquis.yaml, restart the service:
sudo systemctl restart crowdsec
Understanding Profiles (profiles.yaml)
Profiles define what action CrowdSec takes when a scenario fires. The default profile blocks the attacker’s IP for a set duration:
# /etc/crowdsec/profiles.yaml
name: default_ip_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
- type: ban
duration: 4h
on_success: break
You can customize the ban duration, create different profiles for different scenario severities, or even configure notifications via email or Slack when certain scenarios trigger.
Installing and Configuring Collections
CrowdSec uses "collections" — bundles of parsers and scenarios for specific services. Install the ones you need using the cscli command-line tool:
# List available collections
sudo cscli collections list
# Install collections for common services
sudo cscli collections install crowdsecurity/linux
sudo cscli collections install crowdsecurity/sshd
sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/apache2
sudo cscli collections install crowdsecurity/wordpress
# Reload CrowdSec after installing collections
sudo systemctl reload crowdsec
Installing the Firewall Bouncer
The bouncer is what actually blocks attackers. The firewall bouncer integrates with nftables or iptables and is the most common choice for server protection:
# On Ubuntu/Debian
sudo apt-get install crowdsec-firewall-bouncer-nftables
# On RHEL/Rocky/AlmaLinux
sudo dnf install crowdsec-firewall-bouncer-nftables
# Enable and start the bouncer
sudo systemctl enable --now crowdsec-firewall-bouncer
The bouncer configuration is at /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml. The default configuration works out of the box for most setups, but you may want to review the mode setting (nftables vs iptables) to match your system.
Installing the Nginx Bouncer
For web servers, the nginx bouncer provides application-level blocking — it can return a 403 response or a CAPTCHA challenge instead of a TCP-level drop, which is better for certain use cases like bot mitigation:
# Install the nginx bouncer
sudo apt-get install crowdsec-nginx-bouncer
# Edit the bouncer configuration
sudo nano /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf
In your nginx configuration, include the crowdsec module:
server {
listen 80;
server_name example.com;
# CrowdSec nginx integration
access_by_lua_file /usr/lib/crowdsec/lua/nginx/access.lua;
location / {
proxy_pass http://localhost:3000;
}
}
Monitoring and Managing CrowdSec
The cscli tool is your primary interface for managing and monitoring CrowdSec:
# View current active decisions (blocked IPs)
sudo cscli decisions list
# View recent alerts
sudo cscli alerts list
# View alerts for a specific scenario
sudo cscli alerts list --scenario crowdsecurity/ssh-bf
# Check the status of all components
sudo cscli metrics
# View installed parsers
sudo cscli parsers list
# View installed scenarios
sudo cscli scenarios list
The CrowdSec Dashboard
CrowdSec offers a web-based dashboard via their cloud console at app.crowdsec.net. You can enroll your instance to get a visual overview of decisions, alerts, and threat intelligence:
# Enroll your instance in the CrowdSec console
# (get your enrollment key from app.crowdsec.net)
sudo cscli console enroll YOUR_ENROLLMENT_KEY
# Enable all console features
sudo cscli console enable all
sudo systemctl reload crowdsec
Real-World Example: Blocking SSH Brute Force
Let us walk through what happens when a bot attempts to brute-force SSH on your server.
First, ensure the SSH collection is installed and you are monitoring /var/log/auth.log (or journald on systems without it). When a bot starts hammering your SSH port, CrowdSec parses the authentication failure messages using the crowdsecurity/sshd-logs parser. The crowdsecurity/ssh-bf (brute force) scenario watches for more than 6 failed authentication attempts within a 20-minute window from the same IP.
When the threshold is crossed, CrowdSec creates a decision to ban the IP for 4 hours (based on the default profile). The firewall bouncer picks up this decision within seconds and adds a rule to nftables:
# Watch the decisions appear in real-time
sudo cscli decisions list -o human
# You should see output like:
# +--------+----------+------------------+------------------------------------+--------+---------+--------------------------------+--------+--------------------+--------+
# | ID | Source | Scope:Value | Reason | Action | Country | AS | Events | expiration | Alert |
# +--------+----------+------------------+------------------------------------+--------+---------+--------------------------------+--------+--------------------+--------+
# | 112233 | crowdsec | Ip:203.0.113.42 | crowdsecurity/ssh-bf | ban | CN | AS4134 CHINANET-BACKBONE | 12 | 3h59m | 1234 |
# +--------+----------+------------------+------------------------------------+--------+---------+--------------------------------+--------+--------------------+--------+
To manually add a decision (useful for testing or blocking a known bad actor):
# Block an IP manually for 24 hours
sudo cscli decisions add --ip 203.0.113.42 --duration 24h --reason "manual block"
# Remove a decision
sudo cscli decisions delete --ip 203.0.113.42
Testing That CrowdSec Is Working
You can simulate an attack against yourself to verify the pipeline is functioning correctly. From a test machine (not the same server), run repeated failed SSH logins:
# From a different machine - run multiple failed logins
for i in $(seq 1 10); do
ssh invalid_user@YOUR_SERVER_IP 2>/dev/null || true
done
Back on your server, watch for the decision to appear:
sudo cscli decisions list
# The test machine's IP should appear as banned after ~7 failures
CrowdSec represents a genuine evolution in Linux server security tooling. Its separation of detection and enforcement, combined with crowdsourced threat intelligence, makes it substantially more effective than Fail2ban for most server operators. The learning curve is slightly higher than Fail2ban’s, but the payoff in visibility, flexibility, and protection depth makes it the right choice for any serious Linux server in 2026.
Advanced CrowdSec Configuration: Custom Parsers and Notifications
Once you have CrowdSec running with the basic setup, you can extend it significantly with custom parsers, notification plugins, and integration with your existing monitoring stack.
Custom Parsers for Non-Standard Log Formats
CrowdSec parsers are YAML files that describe how to extract structured information from log lines. If you have an application with a custom log format, you can write a parser for it:
# /etc/crowdsec/parsers/s01-parse/my-app-logs.yaml
filter: "evt.Parsed.program == 'my-app'"
name: my-org/my-app-logs
description: "Parser for my custom application logs"
grok:
name: MY_APP_LOG
pattern: '%{IPORHOST:source_ip} - %{WORD:username} [%{HTTPDATE:timestamp}] "%{WORD:action} %{DATA:resource}" %{INT:status_code}'
apply_on: message
statics:
- meta: log_type
value: http
- meta: service
value: my-app
- parsed: source_ip
expression: "evt.Parsed.source_ip"
Setting Up Notification Plugins
CrowdSec can send alerts to Slack, email, PagerDuty, and other services when it makes a ban decision. The notification system uses plugins:
# Install the Slack notification plugin
sudo cscli notifications install crowdsecurity/slack-plugin
# Configure it at /etc/crowdsec/notifications/slack.yaml
type: slack
name: slack_default
log_level: info
format: |
{{range . -}}
{{$alert := .}}
🚨 CrowdSec Alert
*Scenario:* {{$alert.Scenario}}
*Source IP:* {{range $alert.Source.Range}}{{.}}{{end}}
*Decision:* {{$alert.Decisions | len}} ban(s)
*Reason:* {{$alert.Message}}
{{end -}}
slack_webhook_url: https://hooks.slack.com/services/YOUR/WEBHOOK/URL
# Configure which notifications fire for which decisions in profiles.yaml
# /etc/crowdsec/profiles.yaml
- name: default_ip_remediation
filters:
- Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
- type: ban
duration: 4h
notifications:
- slack_default # Send to Slack when banning
on_success: break
Whitelisting Trusted Sources
Production deployments need whitelist rules to prevent false positives from monitoring systems, internal scanners, and trusted networks:
# /etc/crowdsec/parsers/s02-enrich/my-whitelist.yaml
name: my-org/my-whitelist
description: "Whitelist trusted internal networks and monitoring IPs"
filter: "evt.Meta.source_ip != ''"
whitelist:
reason: "Trusted internal networks"
ip:
- "10.0.0.1" # Gateway
- "192.168.1.100" # Monitoring server
cidr:
- "10.0.0.0/8" # Internal networks
- "172.16.0.0/12"
expression:
- "evt.Meta.source_ip startsWith '192.168.'"
# Test your whitelist is working
sudo cscli decisions list
# Your whitelisted IPs should never appear here
# Manually test a decision
sudo cscli decisions add --ip 1.2.3.4 --duration 1h --reason "manual test"
sudo cscli decisions list
sudo cscli decisions delete --ip 1.2.3.4
Was this article helpful?
About Ramesh Sundararamaiah
Red Hat Certified Architect
Expert in Linux system administration, DevOps automation, and cloud infrastructure. Specializing in Red Hat Enterprise Linux, CentOS, Ubuntu, Docker, Ansible, and enterprise IT solutions.