If you check the authentication log on any public-facing Linux server, you will likely find hundreds of failed login attempts recorded within the first hour. Bots cycle through stolen credential lists, scanners look for outdated software, and automated toolkits try common exploits against every open port they can reach. The question is not whether your machine gets probed. The question is how fast you notice and how quickly you shut the door.
For a long time, the standard answer was Fail2Ban: a Python script that watches log files, counts failed attempts, and adds firewall rules to ban repeat offenders. It works, and millions of servers still rely on it. However, Fail2Ban operates in a bubble. It only knows about the attacks it has personally witnessed on that one particular machine. An IP address that just hammered a thousand other hosts walks up to yours as a complete stranger.
CrowdSec flips this limitation on its head. It is a free, open-source security engine that not only monitors your logs and blocks bad actors locally, but also participates in a global intelligence network. When your instance catches someone misbehaving, that information goes to a shared pool. In return, you receive a constantly refreshed list of IPs that other participants have already flagged. Your server starts rejecting known threats before they even send their first packet.
This guide covers the entire setup process on Ubuntu and Debian. We will go from a clean server to a fully working CrowdSec installation with active firewall enforcement in about 15 minutes.
What Is CrowdSec and Why It Exists
CrowdSec was born in 2020 out of frustration with the state of open-source server protection. Its founders had spent years running a managed hosting business where Fail2Ban was a daily companion. They knew its strengths, but they also ran into its ceiling: no shared intelligence, sluggish performance on busy log streams, and regex-based configuration that scaled poorly across dozens of machines. They decided to rebuild the concept from scratch, choosing Go for speed and designing a modular architecture that keeps detection separate from enforcement.
The project is released under the MIT license, has collected over 12,000 stars on GitHub, and ships packages for every major Linux distribution, plus Docker, Kubernetes, and Windows.
To understand how CrowdSec protects a server, picture a real scenario. A bot starts guessing SSH passwords on your machine. Here is what happens behind the scenes:
- Log reading. The CrowdSec agent watches /var/log/auth.log (or journald, depending on your setup). It picks up each failed authentication line the moment it appears.
- Parsing and enrichment. A chain of parsers extracts the source IP, the attempted username, the timestamp, and the protocol. A GeoIP module tags the IP with its country and autonomous system number.
- Scenario evaluation. The parsed event lands in a "leaky bucket" tied to the ssh-bf scenario. If the same IP fills the bucket (for example, 5 failures within 30 seconds), the scenario overflows and generates an alert.
- Verdict. LAPI receives the alert, consults its profile rules, and records a verdict in its local database. The default outcome for SSH abuse is a four-hour ban.
- Firewall update. A bouncer daemon running alongside the engine checks LAPI for new verdicts on a short polling interval. When it finds the fresh ban, it immediately writes an nftables (or iptables) drop rule for the offending address.
- Community contribution. In the background, LAPI transmits a stripped-down report (just the timestamp, the IP, and the scenario label) to the CrowdSec Central API. After validation, this data point becomes part of the community blocklist distributed to every enrolled instance worldwide.
Three building blocks make this pipeline possible:
The Security Engine is responsible for the first four stages. It ingests raw log output, transforms it into structured records through a parser chain, compares those records to behavioral templates, and notifies LAPI when something looks wrong. If you deploy everything on a single machine, the engine and LAPI share one system process.
The Local API (LAPI) acts as the brain of the operation. It takes incoming alerts, decides what to do about them (block, challenge with a CAPTCHA, or throttle), persists those verdicts in a database, and synchronizes with the global CrowdSec network so your intelligence stays current.
Bouncers carry out the actual punishment. Each bouncer is a small service that periodically asks LAPI for fresh verdicts and enforces them at a specific chokepoint. One bouncer might manage nftables rules on the host, another might inject HTTP 403 responses into your Nginx config, and a third might create IP-level blocks at your CDN provider. You are free to run as many as your architecture requires.
This decoupled design is one of CrowdSec's strongest selling points. Log analysis can happen on one host while enforcement takes effect across a dozen others. Whether you manage a single virtual server or coordinate security across a multi-region deployment, the architecture adapts without structural changes.
How CrowdSec Compares to Fail2Ban
The table below highlights the practical differences that matter when choosing between the two tools.
| Criteria | Fail2Ban | CrowdSec |
|---|---|---|
| Written in | Python | Go (significantly faster on heavy log volume) |
| How it spots attacks | Regex patterns matched against log lines | Behavioral scenarios using a leaky bucket model |
| Shared intelligence | None; each server is on its own | Global community blocklist refreshed in real time |
| Internal design | Single process, tightly coupled | Separate engine, API, and bouncers |
| Running on many servers | Copy configs manually between hosts | Native multi-server mode with central LAPI |
| IPv6 | Partial, depends on backend | Full, including CIDR-based decisions |
| Web application firewall | Not available | AppSec module for HTTP-layer inspection |
| Adding new rules | Write regex, manage jail files | Install YAML-based collections from the Hub |
| Footprint | Minimal CPU and RAM | Slightly more, still comfortable on a 1 GB VPS |
Prerequisites
Gather the following before you start:
- A server running Ubuntu 22.04, Ubuntu 24.04, or Debian 12. This guide uses apt; equivalent packages exist for RHEL, CentOS, Fedora, and SUSE via yum/dnf/zypper.
- Root access or a user with sudo privileges.
- At least one running service whose logs you want to monitor. SSH is present on virtually every Linux machine; add Nginx or Apache if you host websites.
- Roughly 20 minutes and a terminal window.
Need a server? Serverspace provides Linux VPS instances with Ubuntu and Debian images ready to go. Deployment takes under a minute, and you can start the installation right after receiving your SSH credentials.
Step 1. Prepare the System and Add the Repository
Begin by refreshing the package index and applying any pending security patches:
Next, run the official repository setup script. It imports the GPG signing key and creates the apt source entry for CrowdSec packages:
Refresh the index one more time so that apt picks up the new source:
A note for Ubuntu Pro or ESM subscribers. Ubuntu's own universe repository ships CrowdSec 1.4.6, which is heavily outdated. If you run apt policy crowdsec and see 1.4.6 as the candidate, create a pinning override to prefer the official repo:
Pin: origin packagecloud.io Pin-Priority: 900 EOF
Run sudo apt update again and confirm the candidate now points to a more recent release.
Step 2. Install the Security Engine
With the repository in place, one command handles the installation:
The package does a fair amount of work during setup. It registers the machine with the local API, downloads a baseline set of parsers and scenarios from the CrowdSec Hub, and starts the service. Make sure it survives a reboot and check its health:
Look for "active (running)" in the output. You can also print the installed version to confirm everything went smoothly:
At this stage, CrowdSec is already reading your logs and matching events against its default scenarios. But it will not take any action yet, because no remediation component is running. Think of it as a surveillance camera with no security guard at the door.
Step 3. Install a Firewall Bouncer
The bouncer is the guard. It asks LAPI "who should I block right now?" every few seconds and translates the answers into firewall rules.
On Ubuntu 24.04 and Debian 12, nftables is the default firewall framework:
On older systems where iptables is the primary backend:
Start the bouncer and enable it for automatic startup:
crowdsec-firewall-bouncer
Confirm registration:
The output should display one entry with a valid status. From this point forward, every IP that overflows a scenario bucket will automatically end up in a firewall drop rule.
Watch out for UFW conflicts. If UFW is active on your server, it manages its own nftables/iptables chains. Running both UFW and the CrowdSec nftables bouncer at the same time can produce unexpected results. Either disable UFW and let CrowdSec own the blocking rules, or use the iptables bouncer variant, which tends to coexist more peacefully.
Step 4. Add Detection Collections
A collection is a ready-made bundle containing the parsers ("how to read this log format") and scenarios ("what counts as suspicious activity") for a given service. The installer usually picks up a few automatically, but explicitly installing the ones you need ensures nothing falls through the cracks.
Start with the Linux baseline. It covers syslog parsing, GeoIP enrichment, and date normalization:
Add SSH protection:
For Nginx:
For Apache:
Other frequently used collections cover WordPress, MySQL, and Postfix. Browse the full catalog with:
After adding new collections, reload the engine so it picks them up:
Step 5. Tell CrowdSec Where Your Logs Live
The acquisition layer defines which files (or streams) CrowdSec reads. Its configuration sits in /etc/crowdsec/acquis.yaml and any YAML file inside /etc/crowdsec/acquis.d/. The installer populates sensible defaults, but non-standard setups often require manual tweaks.
Inspect the current sources:
A working configuration for SSH and Nginx typically looks like this:
- /var/log/nginx/access.log
- /var/log/nginx/error.log labels: type: nginx
Each block declares one or more file paths and a label that tells CrowdSec which parser chain to apply. If your web server writes logs to a non-default directory, update the paths accordingly. After editing, restart the service:
sudo systemctl restart crowdsec
Step 6. Confirm Everything Works
With the engine running, the bouncer connected, and acquisition configured, run a quick health check.
Pull up the parsing metrics:
This prints a table showing how many lines each source produced, how many were successfully parsed, and how many were skipped. A large number of skipped lines usually means a parser or collection is missing for that log type.
Check whether any alerts have already fired:
On a public server, SSH-related alerts often appear within minutes of installation.
List active decisions:
To verify end-to-end enforcement, add a temporary ban for a test address and confirm it appears in the firewall:
ruleset | grep 198.51.100.77
For iptables-based setups, replace the second line with:
Clean up the test ban afterwards:
Step 7. Connect to the CrowdSec Console (Optional)
CrowdSec offers a free web dashboard at app.crowdsec.net where you can view alerts, decisions, and engine health in a graphical interface. To link your instance, create an account on the Console website and copy the enrollment key. Then run:
Approve the enrollment in the web interface, then enable context sharing for richer alert details:
The free tier covers basic visibility. Paid plans unlock extra blocklists, advanced dashboards, and team features, but the complimentary version is perfectly adequate for most configurations.
Whitelisting Trusted IP Addresses
Before you close the terminal and move on, protect yourself from accidental lockout. A few mistyped SSH passwords or an aggressive health check tool could trigger a scenario and ban your own address.
Create a personal whitelist file:
Paste the following structure, replacing the placeholder with your actual IP:
banned" whitelist: reason: "Admin and monitoring addresses" ip:
- "YOUR.IP.ADDRESS.HERE"
You can list multiple addresses or CIDR ranges. Restart CrowdSec to apply:
Six Mistakes That Trip Up First-Time Users
Running the engine without a bouncer. This is the single most frequent oversight. CrowdSec happily logs alerts all day long, but unless a bouncer is installed and connected, nothing actually gets blocked. Always pair the engine with at least one firewall bouncer.
Skipping the whitelist. Locking yourself out of your own server is embarrassing and potentially expensive. Add your address (and the addresses of any monitoring tools) to the whitelist before you walk away from the keyboard.
Mixing firewall managers. UFW and the nftables bouncer both manipulate the same underlying framework. Unless you know exactly how their rule chains interact, pick one. On a freshly provisioned server, letting the CrowdSec bouncer own the blocking rules is usually the cleaner option.
Ignoring unparsed log lines. Run sudo cscli metrics periodically. If you see thousands of lines labeled "unparsed" for a particular source, CrowdSec has no idea what is happening in those logs. Install the matching collection or write a custom parser.
Leaving LAPI open to the world. The local API listens on port 8080 by default. On a single-machine setup it binds to localhost, which is fine. But if you reconfigure it for multi-server use, restrict access to known agent and bouncer IPs, and put TLS in front of it.
Forgetting to refresh Hub content. New detection rules and parser improvements land on the Hub regularly. Running sudo cscli hub update followed by sudo cscli hub upgrade every few weeks keeps your rule set current without a full reinstallation.
Conclusion
From a bare server to a fully armed CrowdSec deployment, the whole procedure fits into a short terminal session. Repository, engine, bouncer, collections, done. Once the service is running, it immediately starts matching incoming log events to known attack patterns and dropping offenders at the firewall.
Where CrowdSec really earns its keep is the network effect. Thousands of installations around the world continuously report hostile addresses. That collective effort means your machine can reject an attacker who was first spotted on a server in another country just moments earlier. The larger the community grows, the narrower the window of opportunity for any single bad actor.
We suggest beginning with the straightforward setup from this guide: SSH scenario coverage plus a firewall bouncer. As you gain confidence, layer on more protection. Pair the engine with an Nginx bouncer to serve CAPTCHA challenges to suspicious visitors. Route verdicts through a Cloudflare bouncer to stop unwanted traffic at the CDN perimeter before it touches your origin. If you operate multiple hosts, connect them all to a shared LAPI so one detection protects every machine simultaneously.
Refresh your Hub content on a regular schedule, glance at the metrics dashboard now and then, and the system will take care of the rest on its own.