CrowdSec is an open-source intrusion prevention engine: it reads your logs, detects attacks such as SSH brute force or web scanning, and shares signals with a community blocklist. The engine only decides; a separate component called a bouncer enforces those decisions, for example by dropping traffic in the firewall. In this tutorial you will install CrowdSec on Ubuntu 24.04, add the nftables firewall bouncer, enroll the server in the CrowdSec Console, and learn to manage bouncers, decisions and allowlists from the command line.
Prerequisites
To follow this guide you need:
- A server running Ubuntu 24.04 LTS, for example a CubePath VPS.
- A non-root user with
sudoprivileges. - Console or out-of-band access to the server in case a test ban locks you out of SSH.
- A free account at app.crowdsec.net for the Console steps (optional for the rest of the guide).
Step 1 - Installing the CrowdSec engine
Ubuntu ships an old CrowdSec package in universe. Use the official CrowdSec repository instead, which receives current releases and matching bouncers. CrowdSec distributes the repository setup as a script, so download it first and read it before running it:
curl -fsSL https://install.crowdsec.net -o crowdsec-repo.sh
less crowdsec-repo.sh
The script adds the CrowdSec apt repository and its signing key. Run it, then install the engine:
sudo sh crowdsec-repo.sh
sudo apt install crowdsec
During installation CrowdSec detects running services (SSH, Nginx, Apache and others), installs the matching collections and configures the log sources in /etc/crowdsec/acquis.yaml and /etc/crowdsec/acquis.d/. Check that the service is running:
sudo systemctl status crowdsec
● crowdsec.service - Crowdsec agent
Loaded: loaded (/usr/lib/systemd/system/crowdsec.service; enabled; preset: enabled)
Active: active (running) since ...
List the installed collections to see what CrowdSec is watching:
sudo cscli collections list
You should see at least crowdsecurity/linux and crowdsecurity/sshd. If you run a web server that was installed after CrowdSec, add its collection and reload the engine, for example for Nginx:
sudo cscli collections install crowdsecurity/nginx
sudo systemctl reload crowdsec
Step 2 - Installing the firewall bouncer
At this point CrowdSec detects attacks but blocks nothing. The firewall bouncer pulls decisions from the local API (LAPI) and adds the banned addresses to nftables sets. Install the nftables variant, which matches Ubuntu 24.04's default firewall backend:
sudo apt install crowdsec-firewall-bouncer-nftables
When the bouncer is installed on the same machine as the engine, the package registers itself with the local API and writes its API key to /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml. You do not need to edit that file for a standard setup. Confirm the service is running and connected:
sudo systemctl status crowdsec-firewall-bouncer
sudo cscli bouncers list
Name IP Address Valid Last API pull Type Version
cs-firewall-bouncer-1727260000 127.0.0.1 ✔️ 2026-09-25T10:02:11Z crowdsec-firewall-bouncer v0.0.31
A recent Last API pull timestamp means the bouncer is fetching decisions. The bouncer keeps its rules in a dedicated nftables table, so it does not interfere with UFW rules:
sudo nft list tables | grep crowdsec
table ip crowdsec
table ip6 crowdsec6
Step 3 - Allowlisting your own addresses
Before testing bans, make sure you cannot block yourself. The default crowdsecurity/whitelists parser already ignores loopback and private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Add your office IP, monitoring service or VPN range in a separate parser file so package updates never overwrite it:
sudo nano /etc/crowdsec/parsers/s02-enrich/my-allowlist.yaml
name: my/allowlist
description: "Trusted addresses that must never be banned"
whitelist:
reason: "trusted infrastructure"
ip:
- "203.0.113.50"
cidr:
- "198.51.100.0/24"
Use ip for single addresses and cidr for ranges. Replace the example values with your own addresses, then reload CrowdSec and confirm the parser is loaded:
sudo systemctl reload crowdsec
sudo cscli parsers list | grep allowlist
my/allowlist 🏠 enabled,local /etc/crowdsec/parsers/s02-enrich/my-allowlist.yaml
Events from these addresses are now discarded before any scenario can trigger a ban.
Step 4 - Managing decisions with cscli
A decision is an action (usually ban) applied to an IP or range for a limited time. Add a short test ban against a documentation address to confirm the full chain works:
sudo cscli decisions add --ip 192.0.2.10 --duration 5m --reason "bouncer test"
Within a few seconds the bouncer applies it. List the active decisions and search the nftables ruleset for the address:
sudo cscli decisions list
sudo nft list ruleset | grep 192.0.2.10
elements = { 192.0.2.10 timeout 5m expires 4m51s }
Remove the test decision when you are done:
sudo cscli decisions delete --ip 192.0.2.10
The same commands cover everyday operations:
- Ban a range for a day:
sudo cscli decisions add --range 198.51.100.0/24 --duration 24h --reason "abuse". - Lift every decision on one IP after a false positive:
sudo cscli decisions delete --ip 203.0.113.7. - Review what triggered bans:
sudo cscli alerts list, thensudo cscli alerts inspect -d <alert_id>for the matched events.
Note
sudo cscli decisions listshows local decisions only. Add--allto include the community blocklist entries pulled from the Central API, which can be tens of thousands of lines.
Step 5 - Enrolling the server in the CrowdSec Console
The Console gives you a web view of alerts and decisions across all your servers and lets you subscribe engines to additional blocklists. In the Console, open Security Engines, choose to enroll a new engine and copy the enrollment key. Then run on the server:
sudo cscli console enroll your_enrollment_key
INFO Enrollment request sent to CrowdSec Console. Accept it at https://app.crowdsec.net
Go back to the Console and accept the pending engine. Then restart CrowdSec so it picks up the new state and check which data it shares with the Console:
sudo systemctl restart crowdsec
sudo cscli console status
The status table lists options such as custom, manual and tainted, which control whether alerts from custom scenarios, manual decisions and modified scenarios are sent. Enable an option only if you want that data visible in the Console, for example:
sudo cscli console enable manual
sudo systemctl reload crowdsec
Blocklists you subscribe to in the Console are delivered to the engine through the Central API and enforced by the same firewall bouncer; no extra configuration is needed on the server.
Step 6 - Managing bouncers
Each bouncer authenticates to the local API with its own key. You can register bouncers for other machines or services, for example a reverse proxy on another host that queries this LAPI:
sudo cscli bouncers add proxy-01
The command prints an API key once; store it in that bouncer's configuration. Remove bouncers you no longer use so stale keys cannot query your decisions:
sudo cscli bouncers delete proxy-01
To see what the engine is processing and what each bouncer has blocked, use the metrics view:
sudo cscli metrics
The Acquisition Metrics table shows how many log lines each source read and parsed. If a file shows lines read but none parsed, the matching collection is missing.
Step 7 - Sending alerts by email (optional)
CrowdSec includes notification plugins. The email plugin's configuration already exists at /etc/crowdsec/notifications/email.yaml; edit the SMTP settings:
sudo nano /etc/crowdsec/notifications/email.yaml
smtp_host: smtp.your_domain
smtp_port: 587
smtp_username: alerts@your_domain
smtp_password: your_smtp_password
sender_email: crowdsec@your_domain
receiver_emails:
- admin@your_domain
encryption_type: starttls
auth_type: login
Keep the rest of the file (type, name: email_default, format) as shipped. Then enable the notification in the default profile:
sudo nano /etc/crowdsec/profiles.yaml
In the first profile, uncomment the notifications block so it reads:
notifications:
- email_default
Reload CrowdSec and send a test message:
sudo systemctl reload crowdsec
sudo cscli notifications test email_default
Troubleshooting
The bouncer shows no recent API pull. Check its log with sudo journalctl -u crowdsec-firewall-bouncer -n 50. An authentication error usually means the key in /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml no longer exists in sudo cscli bouncers list; generate a new one with sudo cscli bouncers add firewall-bouncer, paste it as api_key and restart the bouncer.
No alerts ever appear. Run sudo cscli metrics and look at the acquisition table. If your log files are missing, add them to /etc/crowdsec/acquis.d/ and reload. If lines are read but not parsed, install the collection for that service.
A legitimate user was banned. Remove the decision with sudo cscli decisions delete --ip <address>, then add the address to your allowlist file from Step 3 so it does not happen again.
Console enrollment stays pending. Confirm outbound HTTPS works with curl -I https://api.crowdsec.net, accept the engine in the Console, and restart CrowdSec.
Conclusion
Your server now detects attacks with CrowdSec, enforces bans in nftables through the firewall bouncer, reports to the CrowdSec Console, and ignores your trusted addresses. Next, consider adding the collection for every service you expose, subscribing the engine to extra blocklists in the Console, and pointing the firewall bouncers of your other servers at a single central LAPI.
