CrowdSec: Block Malicious IPs in 12 Steps, 40 Min [2026]

Brute-force bots do not knock politely. Every internet-facing Linux server logs a steady stream of failed SSH logins, probes for /wp-login.php, and scans for exposed admin panels within minutes of coming online. The classic answer was Fail2ban, but a single host reacting to its own logs is always one step behind a distributed botnet. CrowdSec flips that model: it detects malicious behavior locally, then shares anonymized attacker signals with a global community so every participant benefits from threats seen elsewhere first.

This tutorial walks through a complete, production-grade CrowdSec deployment in 12 steps, roughly 40 minutes end to end. You will install the Security Engine, attach a firewall bouncer that actually blocks traffic, pull in detection collections for SSH and web servers, enroll in the free Console, simulate an attack to confirm bans fire, harden the setup against the two CVEs patched in the latest release, and wire up allowlists, notifications, and Prometheus metrics. Every command is copy-paste ready and verified against CrowdSec 1.7.8, the current stable release as of July 2026.

By the end you will have a working intrusion prevention stack that blocks known-bad IPs before they touch your services, plus a mental model of how CrowdSec’s detection and remediation layers fit together so you can extend it confidently.

Google · Preferred Sources

Don't miss new tech stories on Google

Add Tech Insider once in the Google app and our stories appear in your news suggestions.

Add Now

What Is CrowdSec and Why It Matters in 2026

CrowdSec is an open-source, participative security engine that offers crowdsourced protection against malicious IPs and access to real-world cyber threat intelligence (CTI). At its core it behaves like a modern intrusion detection and prevention system (IDS/IPS): it parses logs and HTTP requests, matches them against behavioral scenarios, and issues decisions such as “ban this IP for four hours.” What makes it different from a lone log-watcher is the network effect. When enough CrowdSec installations independently report the same aggressive IP, that address lands in a community blocklist that every user can consume, turning millions of servers into a distributed early-warning system.

The project is written in Go (roughly 83% of the codebase) and shipped under the permissive MIT license. As of July 2026 the GitHub repository sits at about 14,100 stars and 670 forks, reflecting a large and active operator community. The engine is deliberately decoupled from enforcement: detection happens in one process, while blocking happens in separate lightweight programs called bouncers (also called remediation components). That separation is the single most important design idea in CrowdSec, and it is why the tool scales from a one-box homelab to a fleet of edge servers behind a shared decision database.

Three capabilities ship in the box. First, a log-based IDS/IPS that watches SSH, web servers, mail daemons, and dozens of other services. Second, an Application Security (AppSec) component that acts as a lightweight web application firewall (WAF), inspecting HTTP requests at Layer 7 to catch SQL injection, cross-site scripting, and known CVE exploitation patterns. Third, the community CTI network that feeds the blocklist. Recent releases also switched the default regular-expression engine to RE2 for more predictable performance under load, and added a kind attribute on alerts so you can tell at a glance whether a decision came from a scenario, a WAF rule, or a manual action.

For teams already running a SIEM such as Wazuh, CrowdSec is complementary rather than competing: Wazuh gives you visibility and correlation, while CrowdSec gives you active, automated blocking backed by shared intelligence. The two run happily side by side.

How CrowdSec Works: Engine, Bouncers, LAPI, and the Console

Before touching a terminal, it helps to understand the five moving parts. The Security Engine reads log lines through parsers (which normalize raw text into structured events) and evaluates them against scenarios (which describe attack patterns, for example “ten failed SSH logins in one minute”). When a scenario triggers, the engine writes a decision – typically a ban – into its local database.

Those decisions are served by the Local API (LAPI), a small HTTP service that by default listens only on localhost. Bouncers poll the LAPI, ask “who should I block right now?”, and enforce the answer. A firewall bouncer drops packets at the nftables or iptables layer; a web bouncer returns a 403 or a CAPTCHA. Because enforcement is separate from detection, you can protect one host or point ten web servers at a single shared LAPI.

The Central API (CAPI) is CrowdSec’s cloud side. Your engine reports triggered signals (anonymized: the offending IP and the scenario name, never your logs) and in return pulls the community blocklist of the most aggressive IPs currently attacking the network. Finally, the free Console at app.crowdsec.net is a SaaS dashboard that visualizes your alerts, decisions, and enrolled machines. None of the community features are mandatory – CrowdSec runs fully offline if you never enroll – but the CTI is the reason most people choose it.

ComponentRoleRuns whereTalks to
Security Engine (crowdsec)Parses logs, evaluates scenarios, creates decisionsEach protected host (or a central log box)LAPI
Local API (LAPI)Stores and serves decisions to bouncersLocalhost by default, port 8080Engine, bouncers, CAPI
Bouncer / Remediation ComponentEnforces bans (firewall drop, HTTP 403, CAPTCHA)Firewall, reverse proxy, or app layerLAPI
Central API (CAPI)Shares signals, delivers community blocklistCrowdSec cloudEngine
ConsoleWeb dashboard for alerts, metrics, machinesapp.crowdsec.net (SaaS)Engine via enrollment
AppSec ComponentLayer-7 WAF inspecting HTTP requestsAlongside a reverse proxyEngine

Keep this table handy. Ninety percent of CrowdSec troubleshooting comes down to answering one question: which of these components is not talking to the one next to it?

CrowdSec vs Fail2ban: What Changed for 2026

If you have run Fail2ban, CrowdSec will feel familiar and foreign at the same time. Both watch logs and ban IPs. But Fail2ban couples detection and enforcement in one process, uses regex “jails” per service, and reacts only to what your own host sees. CrowdSec decouples the two, ships reusable behavioral scenarios instead of hand-written regex, and – crucially – enriches your defense with intelligence from the entire network. The practical upshot: a scanner that hit someone else’s server an hour ago is already blocked on yours before it arrives.

CriterionCrowdSec 1.7.8Fail2ban
Detection modelParsers + behavioral scenarios (YAML, sharable)Per-service regex jails
EnforcementDecoupled bouncers (firewall, proxy, app)Built-in actions (mostly iptables)
Threat intelligenceCommunity blocklist + CTI via CAPINone (local only)
Multi-serverNative: many engines/bouncers, one LAPIManual scripting required
Layer-7 WAFYes (AppSec component)No
DashboardFree hosted ConsoleNone built in
Language / licenseGo, MITPython, GPLv2
Resource footprintLow; slightly higher with AppSec/RE2Very low

Fail2ban is not obsolete – it is superb for a single box that just needs to slam the door on SSH brute-forcing, and its footprint is tiny. Choose CrowdSec when you want shared intelligence, a Layer-7 WAF, multi-server coordination, or a dashboard. Many operators even run both during migration, letting Fail2ban keep its narrow SSH jail while CrowdSec takes over web and community blocking. The two do not conflict as long as only one of them owns a given firewall chain, which we will address in the pitfalls section.

Prerequisites and Supported Versions

CrowdSec is undemanding. It runs comfortably on a 1 vCPU / 512 MB virtual machine for a handful of services, though enabling the AppSec/WAF component and the RE2 engine raises baseline memory a little. You need root or sudo access, an internet-facing service worth protecting (SSH counts), and outbound HTTPS on port 443 so the engine can reach the CAPI if you choose to use the community features. The table below lists what this guide was tested against.

RequirementMinimumRecommendedNotes
OSDebian 11 / Ubuntu 22.04Debian 13 / Ubuntu 24.04RHEL, Alma, Rocky, and Fedora also supported via RPM
CrowdSec Engine1.7.x1.7.81.7.8 patches CVE-2026-44982 and CVE-2026-44981
CPU1 vCPU2 vCPUAppSec/WAF benefits from a second core
RAM256 MB512 MB+Higher with AppSec + RE2 enabled
Firewalliptablesnftablesnftables is default on Debian 11+/Ubuntu 22.04+
NetworkOutbound 443Outbound 443Only needed for CAPI/Console; offline mode works too

Confirm which firewall backend your kernel uses before you start, because it decides which bouncer package to install:

# Are you on nftables or legacy iptables?
sudo nft list tables 2>/dev/null && echo "nftables is active" || echo "check iptables"
iptables --version

On a modern Debian or Ubuntu system you will almost certainly see nftables. Note the answer; we use it in Step 3.

Step 1 – Add the CrowdSec Repository

CrowdSec publishes its own package repository, which always carries the latest stable engine and bouncers. The official one-line script auto-detects your distribution, adds the correct APT or YUM source, and imports the signing key. Run it first:

# Add the official CrowdSec repository (Debian/Ubuntu and RHEL family)
curl -s https://install.crowdsec.net | sudo sh

Piping a remote script into a shell always deserves a second look. If your policy forbids it – a reasonable stance in any hardened environment – download the script first, read it, then execute it:

# Safer: inspect before you run
curl -s https://install.crowdsec.net -o crowdsec-repo.sh
less crowdsec-repo.sh
sudo sh crowdsec-repo.sh

The script only configures the repository and refreshes your package index. It does not install the engine yet, which is deliberate: it lets you pin versions or stage the rollout across a fleet with your existing configuration management before anything starts listening. Expect output confirming that the crowdsec repository was added and the package cache updated.

Step 2 – Install and Verify the CrowdSec Security Engine

With the repository in place, installing the engine is a single command. The package ships a sensible default configuration, registers a systemd service, and enrolls a local machine credential so the engine can talk to its own LAPI immediately.

# Install the Security Engine
sudo apt update && sudo apt install crowdsec -y

# Confirm the version and that the service is running
sudo cscli version
sudo systemctl status crowdsec --no-pager

The cscli command-line tool is your primary interface to everything from here on. A healthy install prints a version banner similar to this:

$ sudo cscli version
version: v1.7.8
Codename: alphaga
BuildDate: 2026-05-27
GoVersion: 1.24
Platform: linux

During installation CrowdSec detects services already present on the machine – SSH, for instance – and pulls the matching collections automatically. The default configuration lives under /etc/crowdsec/. The files you will edit most are config.yaml (global settings), acquis.yaml (which logs to read), and profiles.yaml (what to do when a scenario fires). The engine’s data, including the GeoIP database and the decision store, lives in /var/lib/crowdsec/data/. Take thirty seconds to confirm the engine is reading logs and has no acquisition errors:

# What is the engine actually watching?
sudo cscli metrics
sudo journalctl -u crowdsec -n 30 --no-pager

Step 3 – Install a Firewall Bouncer to Enforce Bans

This is the step new users skip, then wonder why nothing gets blocked. The Security Engine only decides; a bouncer enforces. Without one installed, CrowdSec will faithfully log “I would ban 203.0.113.10” while the attacker keeps knocking. Install the firewall bouncer that matches the backend you identified in the prerequisites.

# For nftables (Debian 11+/Ubuntu 22.04+ default)
sudo apt install crowdsec-firewall-bouncer-nftables -y

# For legacy iptables systems, use this instead
# sudo apt install crowdsec-firewall-bouncer-iptables -y

# Make sure the nftables kernel module is loaded
sudo modprobe nf_tables

Installation automatically registers the bouncer with the LAPI and generates an API key, so it can immediately fetch decisions. Verify the registration and confirm the bouncer service is active:

$ sudo cscli bouncers list
-------------------------------------------------------------------------------
 Name                              IP Address  Valid  Last API pull         Type
-------------------------------------------------------------------------------
 cs-firewall-bouncer-1720080000    127.0.0.1   valid  2026-07-05T09:14:22Z  firewall
-------------------------------------------------------------------------------

$ sudo systemctl status crowdsec-firewall-bouncer --no-pager

A “valid” status and a recent “Last API pull” mean the enforcement path is live. From this moment, any decision the engine writes will be pushed into an nftables set (named crowdsec-blacklists) and dropped at the kernel. If you ever run both CrowdSec and Fail2ban, make sure only one of them manages a given chain to avoid two tools fighting over the same rules.

Step 4 – Install Detection Collections for SSH and Web

Collections are bundles of parsers and scenarios for a specific service, distributed through the CrowdSec Hub. Rather than writing detection logic yourself, you install a maintained collection and get community-reviewed rules for free. Start with the Linux baseline, then add whatever your box actually runs.

# Baseline: syslog parsing, GeoIP enrichment, date normalization
sudo cscli collections install crowdsecurity/linux

# SSH brute-force and user-enumeration detection
sudo cscli collections install crowdsecurity/sshd

# If you run Nginx (add crowdsecurity/apache2 for Apache)
sudo cscli collections install crowdsecurity/nginx

# Detect exploitation of known web CVEs (path traversal, RCE, etc.)
sudo cscli collections install crowdsecurity/http-cve

# Apply changes
sudo systemctl reload crowdsec

List what you now have and confirm each collection is enabled and up to date:

$ sudo cscli collections list
-------------------------------------------------------------------------
 Name                       Status    Version  Local Path
-------------------------------------------------------------------------
 crowdsecurity/linux        enabled   0.2.x    /etc/crowdsec/collections/...
 crowdsecurity/sshd         enabled   0.4.x    /etc/crowdsec/collections/...
 crowdsecurity/nginx        enabled   0.3.x    /etc/crowdsec/collections/...
 crowdsecurity/http-cve     enabled   1.x      /etc/crowdsec/collections/...
-------------------------------------------------------------------------

The table below lists the collections most single-server operators reach for. Install only what you run – every collection adds parsing work, and there is no benefit to loading MySQL rules on a box with no database.

CollectionProtectsTypical scenarios
crowdsecurity/linuxBase OS / syslogGeoIP, date parsing, foundation for others
crowdsecurity/sshdOpenSSHBrute-force, user enumeration, slow attacks
crowdsecurity/nginxNginx web serverHTTP probing, bad user-agents, 4xx floods
crowdsecurity/http-cveAny web appKnown CVE exploitation, path traversal
crowdsecurity/base-http-scenariosGeneric webAggressive crawling, scanning, enumeration
crowdsecurity/wordpressWordPresswp-login brute-force, XML-RPC abuse

Step 5 – Point CrowdSec at Your Logs

A parser is useless if it never sees the logs. Acquisition is configured in /etc/crowdsec/acquis.yaml and in drop-in files under /etc/crowdsec/acquis.d/. The installer wires up common paths automatically, but you should verify – and add anything nonstandard, like a custom Nginx access log path. Here is a clean acquisition file covering syslog and a web server:

# /etc/crowdsec/acquis.yaml
---
filenames:
  - /var/log/auth.log
  - /var/log/syslog
labels:
  type: syslog
---
filenames:
  - /var/log/nginx/access.log
  - /var/log/nginx/error.log
labels:
  type: nginx
---
# Read directly from the systemd journal instead of files
source: journalctl
journalctl_filter:
  - "_SYSTEMD_UNIT=ssh.service"
labels:
  type: syslog

The type label is what links a log stream to the right parser, so it must match what the collection expects (syslog, nginx, and so on). After editing, always run a config test before reloading – a malformed acquisition file will otherwise stop the engine from starting:

# Validate configuration, then apply
sudo cscli config show
sudo crowdsec -t          # dry-run test of the full config
sudo systemctl reload crowdsec

# Confirm each source is being read (look for non-zero "lines read")
sudo cscli metrics

In the cscli metrics output, the “Acquisition Metrics” table shows a row per log source with lines read, parsed, and poured into scenarios. If a source shows zero lines read, the path is wrong or the file is unreadable by the crowdsec user – a permissions issue we tackle in troubleshooting.

Step 6 – Enroll in the Free CrowdSec Console

The CrowdSec Console is a free hosted dashboard that centralizes alerts, decisions, and machine health across all your engines. Enrolling also unlocks the full community blocklist and richer CTI. Create an account, copy the enrollment key from the Console UI, then register this machine:

# Paste the enrollment key from app.crowdsec.net
sudo cscli console enroll YOUR_ENROLLMENT_KEY

# Restart so the engine picks up the new console context
sudo systemctl restart crowdsec

Return to the Console and accept the pending enrollment request; the machine appears within a minute. From here you can watch attacks arrive in near real time, see which scenarios fire most, and compare your local decisions against the global community blocklist. If your environment is fully air-gapped, skip this step entirely – CrowdSec keeps working with local decisions only, you simply forgo the shared intelligence. You can confirm the engine is now pulling the community blocklist with:

$ sudo cscli decisions list | head
# Expect entries with origin "CAPI" once the community blocklist syncs
sudo cscli capi status

Step 7 – Test Your Setup by Simulating an Attack

Never trust a security tool you have not seen fire. The safest way to prove the full detection-to-enforcement path works is to manually add a decision, confirm the bouncer enforces it, then remove it. Use a documentation-range IP so you never risk locking yourself out:

# Manually ban a safe test IP for 5 minutes
sudo cscli decisions add -i 203.0.113.10 -d 5m -t ban

# It should now appear in the decisions list
sudo cscli decisions list
$ sudo cscli decisions list
+----+--------+------------------+--------+--------+---------+--------+------------+
| ID | SOURCE |   SCOPE:VALUE    | REASON | ACTION | COUNTRY | EVENTS | EXPIRATION |
+----+--------+------------------+--------+--------+---------+--------+------------+
| 12 | cscli  | Ip:203.0.113.10  | manual | ban    |         |      1 | 4m58s      |
+----+--------+------------------+--------+--------+---------+--------+------------+

Now confirm the firewall bouncer actually pushed that IP into the kernel’s block set, then clean up:

# Confirm the IP is in the nftables set the bouncer manages
sudo nft list set ip crowdsec crowdsec-blacklists | grep 203.0.113.10

# Remove the test ban
sudo cscli decisions delete -i 203.0.113.10

To validate real detection rather than a manual ban, generate failed SSH logins from a throwaway host (never your admin workstation) and watch a scenario trigger. Within a handful of failures the crowdsecurity/ssh-bf scenario fires and CrowdSec issues an automatic ban. Review what happened with the alerts log:

$ sudo cscli alerts list
+----+------------------+----------------------+---------+---------+-----------+
| ID |      VALUE       |        REASON        | COUNTRY |   AS    | DECISIONS |
+----+------------------+----------------------+---------+---------+-----------+
| 42 | Ip:198.51.100.23 | crowdsecurity/ssh-bf | NL      | AS-EXMPL| ban:1     |
+----+------------------+----------------------+---------+---------+-----------+

# Drill into a single alert
sudo cscli alerts inspect 42 -d

Step 8 – Protect Yourself with Allowlists

The fastest way to ruin your afternoon is to ban your own office or CI runner. CrowdSec’s modern allowlists feature (which replaced the old whitelist-decision workaround) lets you exempt trusted IPs and CIDR ranges so they can never be blocked, no matter how noisy they get. Create an allowlist and add your management ranges before you leave the setup unattended:

# Create a named allowlist
sudo cscli allowlists create my_allowlist -d "Trusted admin and CI ranges"

# Add individual IPs or CIDR blocks
sudo cscli allowlists add my_allowlist 192.0.2.25
sudo cscli allowlists add my_allowlist 198.51.100.0/24

# Review it
sudo cscli allowlists inspect my_allowlist

Allowlists are evaluated before decisions are enforced, so an allowlisted address is never handed to a bouncer even if a scenario would otherwise flag it. Keep the list tight: allowlisting broad ranges (an entire hosting provider, say) hands attackers a free pass from inside that range. At minimum, add your own static admin IP and any monitoring or uptime-check services that legitimately hammer your endpoints.

Step 9 – Enable the AppSec WAF and Patch the 2026 CVEs

CrowdSec’s AppSec component turns the engine into a lightweight WAF that inspects live HTTP requests at Layer 7, catching SQL injection, XSS, and CVE exploitation that log-based detection sees only after the fact. It pairs with a web bouncer in your reverse proxy. This is also where the two vulnerabilities fixed in 1.7.8 live, so getting on the patched release matters if you use it.

Per the official 1.7.8 security advisory, CVE-2026-44982 was a high-impact partial WAF bypass in the AppSec datasource: HTTP/1.1 requests using Transfer-Encoding: chunked and HTTP/2 requests sent without a Content-Length header were evaluated against an empty body, silently bypassing any WAF rule that targeted body content. Headers-only and URI-only rules were unaffected. CVE-2026-44981 was a Local API denial-of-service: LAPI did not enforce a maximum decompressed body size on gzip-compressed requests, and the unauthenticated /v1/watchers and /v1/watchers/login endpoints were exploitable – though because LAPI listens only on localhost by default, it was not remotely exploitable out of the box. Both are fixed in 1.7.8.

# Confirm you are on the patched release
sudo cscli version | grep 1.7.8 || echo "UPGRADE NEEDED: sudo apt update && sudo apt upgrade crowdsec"

# Install the AppSec (WAF) collections
sudo cscli collections install crowdsecurity/appsec-virtual-patching
sudo cscli collections install crowdsecurity/appsec-generic-rules

# Reload to activate
sudo systemctl reload crowdsec

Then define an AppSec acquisition endpoint that your reverse proxy forwards requests to for inspection. This teaches CrowdSec to score inbound HTTP before it reaches your application:

# /etc/crowdsec/acquis.d/appsec.yaml
appsec_config: crowdsecurity/appsec-default
labels:
  type: appsec
listen_addr: 127.0.0.1:7422
source: appsec

Pair this with a web bouncer (for example the Nginx or Traefik remediation component) configured to send requests to 127.0.0.1:7422. The bouncer forwards each request’s metadata, receives an allow or block verdict, and enforces it before your app ever runs the query. This is the same class of Layer-7 defense that would have blunted edge-device exploits like the CitrixBleed NetScaler flaw and the FortiBleed firewall breach that dominated 2026 headlines.

Step 10 – Tune Scenarios and Decision Profiles

Out of the box CrowdSec bans aggressively enough to be useful and conservatively enough to avoid friendly fire, but production always needs tuning. Two files control behavior: scenarios (the “when”) and profiles (the “then”). Profiles live in /etc/crowdsec/profiles.yaml and let you escalate – for example, ban repeat offenders for longer, or send a CAPTCHA instead of an outright block for web traffic.

# /etc/crowdsec/profiles.yaml (excerpt)
name: default_ip_remediation
filters:
  - Alert.Remediation == true && Alert.GetScope() == "Ip"
decisions:
  - type: ban
    duration: 4h
on_success: break
---
name: aggressive_repeat
filters:
  - Alert.GetScenario() == "crowdsecurity/ssh-bf" && Alert.EventsCount > 20
decisions:
  - type: ban
    duration: 72h

You can also raise or lower a scenario’s sensitivity by overriding its parameters instead of editing the shipped file – safer, because Hub updates will not clobber your changes. Drop overrides into /etc/crowdsec/scenarios/. After any change, dry-run the config and reload:

sudo crowdsec -t && sudo systemctl reload crowdsec
sudo cscli scenarios list

Resist the urge to over-tune on day one. Run defaults for a week, watch which scenarios fire and how often in the Console, and only then tighten the rules that generate noise or loosen those that miss real attacks.

Step 11 – Add Real-Time Notifications

A ban you never hear about is a ban you cannot audit. CrowdSec’s notification plugins push alerts to Slack, Discord, Telegram, email, or any HTTP webhook. Configurations live in /etc/crowdsec/notifications/, and you link a plugin to a profile so specific decisions trigger a message. Here is a Slack webhook example:

# /etc/crowdsec/notifications/slack.yaml
type: http
name: slack_default
url: https://hooks.slack.com/services/YOUR/WEBHOOK/URL
method: POST
headers:
  Content-Type: application/json
format: |
  { "text": "CrowdSec banned an IP via {{range . -}}{{.Scenario}}{{end}}" }

Reference the plugin from a profile’s notifications key, then test it end to end before you rely on it:

# List available notification plugins
sudo cscli notifications list

# Fire a test message through the Slack plugin
sudo cscli notifications test slack_default

Keep notification volume sane: alert on manual bans, long-duration escalations, and AppSec blocks, but do not page yourself for every routine SSH ban or you will train yourself to ignore the channel. Route high-signal events to a human and let the routine bans flow silently into the Console.

Step 12 – Monitor CrowdSec with Prometheus and Grafana

CrowdSec exposes Prometheus-formatted metrics, so you can graph parse rates, scenario hits, bounced requests, and API health alongside the rest of your infrastructure. The engine serves metrics on 127.0.0.1:6060/metrics by default. Point Prometheus at it:

# prometheus.yml scrape config
scrape_configs:
  - job_name: crowdsec
    static_configs:
      - targets: ["127.0.0.1:6060"]
    metrics_path: /metrics

Enable the Prometheus listener in /etc/crowdsec/config.yaml if it is not already on, then reload and confirm the endpoint responds:

# In /etc/crowdsec/config.yaml
# prometheus:
#   enabled: true
#   level: full
#   listen_addr: 127.0.0.1
#   listen_port: 6060

sudo systemctl reload crowdsec
curl -s 127.0.0.1:6060/metrics | grep cs_ | head

CrowdSec publishes a ready-made Grafana dashboard you can import by ID from the official documentation, giving you attack maps, top scenarios, and decision counts without building panels by hand. The same cscli metrics command you used earlier is the quick terminal equivalent when you just need a snapshot. With monitoring in place, your 12-step deployment is complete: detection, enforcement, community intelligence, allowlisting, WAF, tuning, alerting, and observability are all live.

Common Pitfalls and How to Avoid Them

Most CrowdSec problems are not bugs – they are one of a handful of predictable configuration mistakes. Here are the ones that trip up nearly everyone.

  • No bouncer installed. The number-one mistake. The engine happily creates decisions, but with no bouncer nothing is enforced. If attacks are detected yet IPs still connect, run sudo cscli bouncers list – an empty list is your answer.
  • Banning yourself. Set up allowlists (Step 8) before you walk away. If you do lock yourself out, access the console via your provider’s out-of-band tools and run sudo cscli decisions delete --all to clear every ban.
  • Logs not being read. A wrong path or a log the crowdsec user cannot read means zero detection. Check “lines read” in cscli metrics; a zero there points straight at acquisition.
  • Fighting Fail2ban over the firewall. Running both without coordination produces duplicated or conflicting rules. Pick one tool to own each service, or scope them to separate nftables chains.
  • Skipping the config test. Editing YAML and restarting blind will take the engine down on a typo. Always run sudo crowdsec -t before systemctl reload.
  • Allowlisting too broadly. Exempting an entire cloud provider’s range to fix one false positive gives every attacker inside that range a free pass. Allowlist specific IPs, not whole ASNs.

Troubleshooting CrowdSec: 8 Common Issues

When something misbehaves, work down the pipeline from log to firewall. This quick-reference table maps the symptom to the likely cause and the command that confirms it.

SymptomLikely causeFix / command
IPs detected but never blockedNo bouncer, or bouncer invalidcscli bouncers list; reinstall the firewall bouncer
No alerts ever fireLogs not acquiredcscli metrics then check “lines read”; fix acquis.yaml
Engine will not start after editYAML syntax errorsudo crowdsec -t to see the exact line
Permission denied on a logcrowdsec user lacks read accessAdd the user to the log’s group, e.g. adm; reload
Bouncer shows invalidAPI key mismatchcscli bouncers delete then re-add; restart bouncer
Community blocklist emptyNot enrolled / no outbound 443cscli capi status; check firewall egress
Legitimate traffic blockedFalse positive scenarioAdd source to an allowlist; tune the scenario
High CPU with AppSec onHeavy regex, single coreConfirm RE2 engine; add a vCPU; scope AppSec rules

Two commands solve the majority of cases. sudo cscli metrics tells you whether logs are being read and scenarios are pouring, and sudo journalctl -u crowdsec -f streams the engine’s live reasoning. For bouncer-side issues, tail the bouncer’s own journal (journalctl -u crowdsec-firewall-bouncer -f) – enforcement failures show up there, not in the engine log.

Advanced Tips for Production CrowdSec Deployments

Once the single-host setup is solid, a few patterns take CrowdSec from “installed” to “operationalized.” First, centralize the LAPI. In a fleet, run one hardened LAPI/database node and point every engine and bouncer at it, so a ban detected on any server is enforced everywhere within seconds. Register remote machines with cscli machines add and distribute their credentials with your configuration management.

Second, subscribe to third-party blocklists from the Console – curated feeds of known VPN exit nodes, TOR relays, or industry-specific threat lists – to block categories of traffic proactively rather than waiting for a scenario to fire. Third, version-control your configuration. Keep acquis.yaml, profiles.yaml, and your scenario overrides in Git; CrowdSec’s file-based config makes this trivial and turns disaster recovery into a git clone.

Fourth, on the security of CrowdSec itself: keep the engine patched. The 1.7.8 release underlines why – a WAF that silently passes chunked request bodies is worse than no WAF, because it breeds false confidence. Subscribe to the GitHub releases feed and treat engine updates like any other security-critical package. If you run the AppSec component behind a reverse proxy, make sure the proxy strips or normalizes ambiguous transfer-encoding headers as defense in depth. Finally, pair CrowdSec with the rest of a layered stack: a properly configured WireGuard tunnel for admin access, hardened credentials via a manager like those in our password manager comparison, and centralized log analysis in Wazuh. CrowdSec is a strong perimeter, not a complete security program.

Related Coverage

Frequently Asked Questions

Is CrowdSec free?

Yes. The Security Engine, bouncers, and collections are open source under the MIT license and free forever. The hosted Console has a free tier that covers individual operators and homelabs, with paid Enterprise tiers adding team features, longer data retention, and premium blocklists. Nothing in this tutorial requires a paid plan.

CrowdSec vs Fail2ban – which should I use?

Use Fail2ban for a single box that only needs to block SSH brute-forcing with a minimal footprint. Choose CrowdSec when you want crowdsourced threat intelligence, a Layer-7 WAF, multi-server coordination, or a dashboard. They can coexist during migration as long as only one tool manages a given firewall chain. See our Fail2ban setup guide for the alternative.

Does CrowdSec send my logs to the cloud?

No. When you enroll in the community, the engine shares only anonymized attack signals – the offending IP address and the name of the scenario it triggered. Your raw logs never leave the machine. You can also run CrowdSec fully offline and forgo the community blocklist entirely if your policy requires it.

What is the latest version of CrowdSec?

As of July 2026 the current stable release is CrowdSec 1.7.8, published in May 2026. It is a security release that patches CVE-2026-44982 (a partial WAF bypass in the AppSec datasource) and CVE-2026-44981 (a Local API denial-of-service). If you use the AppSec/WAF component or the nginx/OpenResty remediation components, upgrading to 1.7.8 is strongly recommended.

Why is CrowdSec detecting attacks but not blocking them?

You almost certainly have no bouncer installed, or the bouncer is registered but inactive. The Security Engine only creates decisions; a bouncer enforces them. Run sudo cscli bouncers list – if it is empty, install a firewall bouncer as shown in Step 3. If a bouncer is listed but shows an invalid status, delete and re-add it to refresh the API key.

Does CrowdSec work with Docker and Kubernetes?

Yes. There is an official crowdsecurity/crowdsec Docker image and a Helm chart for Kubernetes. In containerized environments you typically run the engine as a sidecar or DaemonSet reading container logs, with bouncers deployed at your ingress or reverse-proxy layer. The concepts in this guide – engine, LAPI, bouncers, collections – map directly to those deployments.

How much memory and CPU does CrowdSec use?

For a handful of services, the engine runs comfortably in a few hundred megabytes of RAM on a single vCPU. Enabling the AppSec/WAF component and the RE2 regular-expression engine raises the baseline somewhat, so allocate 512 MB or more and a second core if you inspect heavy HTTP traffic. It remains far lighter than a full commercial WAF appliance.

Can I use CrowdSec without the community features?

Absolutely. Skip the Console enrollment in Step 6 and CrowdSec runs entirely on local detection and decisions, with no outbound connection to the Central API. You lose the shared blocklist and CTI, but every other capability – scenarios, bouncers, allowlists, AppSec, notifications, metrics – works exactly the same. This is common in air-gapped or strict-compliance environments.

Conclusion: A Smarter Perimeter in Under an Hour

In twelve steps you have gone from an exposed Linux host to a coordinated intrusion prevention stack: the Security Engine reads your logs, scenarios turn suspicious behavior into decisions, a firewall bouncer drops the offenders at the kernel, allowlists keep you from banning yourself, the AppSec component adds a Layer-7 WAF patched against the 2026 CVEs, and the community blocklist blocks attackers you have never even seen. Notifications and Prometheus metrics close the loop so nothing happens silently.

The real payoff is the network effect. Every CrowdSec install makes the others stronger, and the moment you enroll, your server starts benefiting from millions of attacks observed elsewhere. Keep the engine patched, keep your allowlists tight, review the Console weekly, and treat CrowdSec as one hardened layer in a defense-in-depth strategy alongside your VPN, your secrets manager, and your SIEM. For roughly forty minutes of work, that is one of the best security returns available to a self-hosting operator in 2026.

Nadia Dubois

Nadia Dubois

AI & Innovation Editor

Nadia Dubois is the AI & Innovation Editor at Tech Insider, where she tracks the rapid evolution of artificial intelligence, from foundation models to real-world enterprise deployment. She previously covered AI and startups for La Tribune and contributed to MIT Technology Review's European coverage. Nadia specializes in generative AI, AI regulation, and the intersection of technology and European industrial policy. She holds a dual degree in Computational Linguistics and Journalism from Sciences Po Paris.

View all articles