Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsStudyTraining
ProjectsChecklistsAI RankingsNewsletterStatusTagsAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Study
Training
Projects
Checklists
AI Rankings
Newsletter
Status
Tags
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

429+ Articles
114+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. Projects
  3. Build a Collaborative IPS with CrowdSec
Build a Collaborative IPS with CrowdSec
PROJECTIntermediate

Build a Collaborative IPS with CrowdSec

Deploy CrowdSec on a Linux server to get community-powered intrusion prevention — block brute-force attacks, credential stuffing, and vulnerability scanners using crowd-sourced threat intelligence and automatic firewall enforcement.

Dylan H.

Projects

March 27, 2026
10 min read
3-5 hours

Tools & Technologies

CrowdSec Security Enginecscli CLInftables / iptablesNginxCrowdSec Console (app.crowdsec.net)

Overview

Traditional intrusion prevention systems (IPS) operate in isolation — each deployment independently decides what to block based only on the attacks it has seen. CrowdSec flips this model by crowdsourcing threat intelligence. Every participating installation shares (anonymised) attacker IPs with the community, and in return receives a live blocklist maintained by hundreds of thousands of engines worldwide.

Under the hood CrowdSec splits into two clean layers:

  • Security Engine — reads your logs, runs them through parsers and behaviour-detection scenarios, and raises alerts when it spots attacks.
  • Bouncers (Remediation Components) — consume the engine's decisions and enforce them at whichever layer makes sense: the kernel firewall, your web server, Cloudflare, etc.

By the end of this guide you will have:

  1. CrowdSec installed and monitoring SSH, syslog, and Nginx access logs.
  2. A firewall bouncer auto-blocking malicious IPs via nftables.
  3. An Nginx bouncer returning 403 Forbidden to banned clients.
  4. Your instance enrolled in the CrowdSec Console for a central view across all machines.
  5. The community blocklist actively pre-banning known-bad IPs before they even attempt an attack.

Architecture

                          ┌─────────────────────────────┐
                          │        CrowdSec Engine        │
                          │                               │
   /var/log/auth.log ────▶│  Log Acquisition (acquis.d)   │
   /var/log/nginx/   ────▶│         │                     │
   journald        ────▶│   Parsers (s00 → s01 → s02)   │
                          │         │                     │
                          │    Scenarios (leaky bucket)   │
                          │         │                     │
                          │     Local API  (:8080)        │
                          └──────┬──────────┬─────────────┘
                                 │          │
                       ┌─────────▼──┐  ┌────▼───────────┐
                       │  Firewall  │  │  Nginx Bouncer  │
                       │  Bouncer   │  │  (Lua / :7422)  │
                       │ (nftables) │  └────────────────┘
                       └─────────┬──┘
                                 │
                          ┌──────▼──────┐
                          │  nftables   │  ◀── blocked IPs
                          │   kernel    │
                          └─────────────┘

         CrowdSec Console (app.crowdsec.net)
           ▲ shared CTI + community blocklist

The engine never touches your firewall directly — bouncers are separate processes that poll the local API, which means you can add or remove enforcement points without restarting the engine.


Prerequisites

RequirementNotes
Linux host (Ubuntu 22.04 / 24.04 recommended)VPS, bare-metal, or VM
Root or sudo accessFor package install and systemd
Nginx installed (optional)Only needed for the web bouncer step
Free CrowdSec Console accountapp.crowdsec.net — takes 60 seconds
Open outbound HTTPSEngine calls api.crowdsec.net for blocklist sync

Step 1 — Install the CrowdSec Security Engine

CrowdSec provides a one-liner that adds the package repository and installs the engine:

curl -s https://install.crowdsec.net | sudo sh
sudo apt install -y crowdsec
sudo systemctl enable --now crowdsec

Verify the engine is running and check its initial status:

sudo cscli version
sudo cscli metrics

The installer auto-detects common log paths and creates acquisition configs for them. Check what was discovered:

sudo cscli hub list
sudo cat /etc/crowdsec/acquis.yaml

Step 2 — Install Collections

Collections bundle the parsers and detection scenarios needed for a given service. Install the essentials:

# Core Linux + SSH brute-force detection
sudo cscli collections install crowdsecurity/linux
sudo cscli collections install crowdsecurity/sshd
 
# Nginx access and error log analysis
sudo cscli collections install crowdsecurity/nginx
 
# HTTP attack scenarios (path traversal, SQLi probes, etc.)
sudo cscli collections install crowdsecurity/http-cve
sudo cscli collections install crowdsecurity/base-http-scenarios
 
# Portscan and common CVE detection
sudo cscli collections install crowdsecurity/iptables

After installing collections, reload the engine so the new parsers are active:

sudo systemctl reload crowdsec

List everything currently installed:

sudo cscli collections list
sudo cscli scenarios list
sudo cscli parsers list

Step 3 — Configure Log Acquisition

CrowdSec reads *.yaml files from /etc/crowdsec/acquis.d/ to know which logs to tail. The installer creates a starting file; augment it for your services.

Review and extend acquis.yaml

# /etc/crowdsec/acquis.d/acquis.yaml  (already created by installer)
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

Add journald acquisition (systemd-based distros)

Create /etc/crowdsec/acquis.d/journald.yaml:

source: journalctl
journalctl_filter:
  - "_SYSTEMD_UNIT=sshd.service"
labels:
  type: syslog

Reload after any acquisition change:

sudo systemctl reload crowdsec

Test the parsing pipeline

Use cscli explain to verify logs are parsed correctly. Feed a real line from your auth log:

sudo cscli explain \
  --log 'Mar 27 10:12:34 myhost sshd[12345]: Failed password for invalid user admin from 198.51.100.42 port 54321 ssh2' \
  --type syslog

A successful parse shows green 🟢 indicators through each pipeline stage. A red 🔴 means the parser did not match — check the collection is installed and reload.


Step 4 — Deploy the Firewall Bouncer

The firewall bouncer watches the local API for ban decisions and writes blocking rules directly into nftables or iptables.

Detect your firewall backend

iptables -V
# If output contains "nf_tables" → use nftables package
# Otherwise → use iptables package

Install

# nftables (most modern distros)
sudo apt install -y crowdsec-firewall-bouncer-nftables
 
# iptables (older kernels)
sudo apt install -y crowdsec-firewall-bouncer-iptables

The package creates a config at /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml and registers itself with the local API automatically. Check it is linked:

sudo cscli bouncers list

You should see crowdsec-firewall-bouncer with status valid. Enable and start:

sudo systemctl enable --now crowdsec-firewall-bouncer
sudo systemctl status crowdsec-firewall-bouncer

Verify rules are being written

# nftables
sudo nft list ruleset | grep crowdsec
 
# iptables
sudo iptables -L -n | grep crowdsec

Step 5 — Deploy the Nginx Bouncer (Optional)

If you run Nginx, the web bouncer intercepts requests at the Lua layer — banned IPs receive a 403 before any application code executes.

Install dependencies and bouncer

sudo apt install -y lua5.1 libnginx-mod-http-lua luarocks gettext-base lua-cjson
sudo apt install -y crowdsec-nginx-bouncer

The bouncer auto-generates its API key and injects the Lua config into /etc/nginx/conf.d/crowdsec_nginx.conf:

# /etc/nginx/conf.d/crowdsec_nginx.conf (auto-generated)
init_by_lua_block {
    local cs = require "plugins.crowdsec.crowdsec"
    local ok, err = cs.init("/etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf", "crowdsec-nginx-bouncer/v1.0")
    if ok == nil then
        ngx.log(ngx.ERR, "[CrowdSec] Failed to init lib: " .. err)
    else
        ngx.log(ngx.ALERT, "[CrowdSec] Loaded")
    end
}
 
access_by_lua_block {
    local cs = require "plugins.crowdsec.crowdsec"
    cs.Allow(ngx.var.remote_addr)
}

Reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

Verify the bouncer appears in the list:

sudo cscli bouncers list

Enable AppSec (Web Application Firewall)

CrowdSec can also run virtual patching rules — catching SQLi, XSS, path traversal, and known CVE exploit patterns at the request level:

sudo cscli collections install crowdsecurity/appsec-virtual-patching
sudo cscli collections install crowdsecurity/appsec-generic-rules

Create /etc/crowdsec/acquis.d/appsec.yaml:

listen_addr: 127.0.0.1:7422
appsec_config: crowdsecurity/virtual-patching
name: myapp-appsec
source: appsec
labels:
  type: appsec

Add APPSEC_URL=http://127.0.0.1:7422 to /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf, then restart both services:

sudo systemctl restart crowdsec
sudo systemctl reload nginx

Test AppSec is active:

curl -I "http://localhost/.env"
# Expected: HTTP/1.1 403 Forbidden

Step 6 — Connect to the CrowdSec Console

The Console (free tier) gives you a centralised dashboard across all your engines, shows live alerts, and lets you manage allowlists without SSH-ing into each server.

Create your account

Go to app.crowdsec.net, sign up, and verify your email. The onboarding screen provides your personal enrollment key.

Enroll the engine

sudo cscli console enroll <YOUR_ENROLLMENT_KEY>
# Optional: name the instance
sudo cscli console enroll <YOUR_ENROLLMENT_KEY> --name "homelab-vps-01"

Back in the Console, accept the pending enrollment. Then restart the engine to push initial metadata:

sudo systemctl restart crowdsec

Confirm enrollment

sudo cscli console status

Output should show Enrolled: true.


Step 7 — Configure Slack / Email Notifications

CrowdSec can push alerts when a scenario triggers. Notification plugins live in /etc/crowdsec/notifications/.

Slack webhook example

Create /etc/crowdsec/notifications/slack.yaml:

type: slack
name: slack_default
log_level: info
format: |
  {{range . -}}
  [{{.Scenario}}] {{.Source.IP}} ({{.Source.Country}}) — {{.Message}}
  {{end -}}
webhook: https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK

Reference it in /etc/crowdsec/profiles.yaml:

name: default_ip_remediation
filters:
  - Alert.Remediation == true && Alert.Source.Scope == "Ip"
decisions:
  - type: ban
    duration: 4h
notifications:
  - slack_default
on_success: break

Reload the engine and trigger a test alert:

sudo systemctl reload crowdsec
sudo cscli notifications test slack_default

Testing

Simulate a brute-force attack

On a different machine, run repeated failed SSH attempts against your server:

for i in $(seq 1 10); do
  ssh -o ConnectTimeout=2 baduser@YOUR_SERVER_IP 2>/dev/null || true
done

Back on the server, watch alerts appear in real time:

sudo cscli alerts list

The source IP should appear as banned within seconds:

sudo cscli decisions list

Verify the IP is blocked at the firewall:

sudo nft list ruleset | grep -A5 crowdsec

Check the community blocklist

CrowdSec auto-subscribes you to the community blocklist. View pre-blocked IPs:

sudo cscli decisions list --origin CAPI

These are IPs that other CrowdSec users reported and the community validated as malicious — blocked on your server before they even connect.

Inspect a specific decision

sudo cscli decisions list -i 198.51.100.42

Manually add / remove a ban

# Ban an IP for 24 hours
sudo cscli decisions add --ip 198.51.100.42 --duration 24h --reason "manual-test"
 
# Remove the ban
sudo cscli decisions delete --ip 198.51.100.42

Unban your own IP if locked out

sudo cscli decisions delete --ip YOUR_IP

Monitoring and Observability

Live metrics

# Engine processing stats
sudo cscli metrics
 
# Bouncer status
sudo cscli bouncers list
 
# Active decisions
sudo cscli decisions list
 
# Recent alerts
sudo cscli alerts list --limit 20

Grafana dashboard (optional)

CrowdSec exposes Prometheus metrics at http://127.0.0.1:6060/metrics. If you already run Grafana:

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

Import the official CrowdSec Grafana dashboard (ID 14712) from the Grafana dashboard hub.


Deployment Notes

Whitelist trusted IPs

Never ban your own workstation or monitoring systems. Add trusted CIDRs to /etc/crowdsec/parsers/s02-enrich/mywhitelist.yaml:

name: myorg/whitelist-internal
description: "Whitelist RFC1918 and monitoring"
whitelist:
  reason: "internal network"
  ip:
    - "127.0.0.1"
  cidr:
    - "10.0.0.0/8"
    - "172.16.0.0/12"
    - "192.168.0.0/16"

Reload after adding:

sudo systemctl reload crowdsec

Adjust ban duration per scenario

Edit /etc/crowdsec/profiles.yaml to tune durations:

decisions:
  - type: ban
    duration: 24h   # increase from default 4h for repeat offenders

Extensions and Next Steps

ExtensionWhat It Adds
HAProxy bouncerBlock at load-balancer level before traffic reaches Nginx
Cloudflare bouncerPush bans to Cloudflare firewall rules automatically
Traefik bouncerKubernetes/Docker ingress protection
OPNsense pluginProtect your edge firewall with community blocklists
Multi-server ConsoleEnroll all your VPS and homelab nodes into one dashboard
Custom scenariosWrite YAML leaky-bucket rules for your own app logs
SIEM integrationForward CrowdSec alerts to Grafana Loki, Elastic, or Splunk
Premium CTISubscribe to advanced threat feeds (ransomware, botnets) via Console

Writing a custom detection scenario

If your application produces login failure logs, you can write a scenario to detect brute force in a few lines of YAML:

# /etc/crowdsec/scenarios/myapp-bf.yaml
type: leaky
name: myorg/myapp-bruteforce
description: "Detect brute force against MyApp login"
filter: evt.Meta.log_type == 'myapp_failed_login'
groupby: evt.Meta.source_ip
capacity: 5
leakspeed: "10s"
blackhole: 1m
labels:
  service: myapp
  type: bruteforce
  remediation: true

Place your parser in /etc/crowdsec/parsers/s01-parse/myapp-logs.yaml, then reload. Use cscli explain to validate the pipeline end-to-end before deploying to production.


CrowdSec turns every server into both a protected node and a contributor to collective defence. The community blocklist alone stops a significant percentage of automated attacks before any detection logic even runs — and as more engines join the network, that intelligence only gets sharper.

#crowdsec#intrusion-prevention#homelab#security#threat-intelligence#linux#firewall#nginx

Related Articles

Keycloak SSO: Self-Hosted Identity Provider for Your Homelab

Deploy Keycloak with Docker Compose and PostgreSQL to build a centralised single sign-on platform for your homelab services, with OIDC integration for...

11 min read

HashiCorp Vault: Secrets Management for Your Homelab and

Deploy HashiCorp Vault to centrally manage secrets, certificates, and dynamic credentials — eliminating hardcoded passwords from your infrastructure with...

12 min read

Claude Code for IT Operations: Building a Multi-Project

Transform Claude Code from a chatbot into a DevOps co-pilot. Set up CLAUDE.md templates, custom hooks, reusable agents, deployment skills, and MCP server...

12 min read
Back to all Projects