CrowdSec on Proxmox: Cluster-Wide Brute-Force Defense
Install CrowdSec 1.6 on Proxmox VE 9 to block known malicious IPs before they connect. Learn how to add the nftables bouncer and share bans cluster-wide.
On this page
CrowdSec gives your Proxmox nodes something fail2ban never could: crowd-sourced threat intelligence. Where fail2ban sits idle until it sees a brute-force attempt in local logs, CrowdSec arrives pre-loaded with a blocklist of known malicious IPs contributed by thousands of servers worldwide — and adds local detection on top. By the end of this guide, you will have CrowdSec 1.6 installed on your Proxmox VE 9 host, an nftables bouncer enforcing bans at the kernel level, and — if you run a cluster — decisions shared across all your nodes automatically.
Key Takeaways
- CrowdSec vs fail2ban: CrowdSec uses community IP blocklists preemptively; fail2ban only reacts after local log events.
- Host install: Deploy directly on the Proxmox VE host (Debian 12 base) via CrowdSec's official apt repo — no VM or LXC needed.
- Bouncer: The
crowdsec-firewall-bouncer-nftablespackage integrates with Proxmox's existing nftables stack with zero conflicts. - Parsers: The
crowdsecurity/linuxandcrowdsecurity/sshdcollections cover SSH and pvedaemon auth failures out of the box. - Cluster bans: Point every node's agent at a central LAPI instance to propagate decisions across all nodes within seconds.
Why CrowdSec Works Better Than fail2ban for Proxmox
The standard Proxmox hardening guide covering fail2ban and SSH lockdown is a solid starting point. But fail2ban has one fundamental limitation: it only knows what it has already seen. A scanner hitting your SSH port for the first time gets N-1 free attempts before a ban triggers.
CrowdSec flips this model. It pulls from a community Cyber Threat Intelligence (CTI) feed — contributed by nodes worldwide — so IPs that attacked someone else's server yesterday are already blocked on your node before they ever reach yours.
| Capability | fail2ban | CrowdSec 1.6 |
|---|---|---|
| Block known bad IPs on install | No | Yes (community CTI feed) |
| React to local log events | Yes | Yes |
| Multi-node ban sharing | Manual | Built-in via LAPI federation |
| Firewall integration | iptables (legacy) | nftables (native) |
| Dashboard | None | Web console, free tier |
| Config language | Regex filters | YAML scenarios |
CrowdSec's agent runs at around 40 MB RSS — lighter than most monitoring daemons you are likely already running on the same host.
What You Need Before Installing
- Proxmox VE 9.x or 8.x (both use Debian 12 Bookworm as their base)
- Root access to the Proxmox host shell — not inside a VM or LXC
- Outbound HTTPS (port 443) for the community CTI feed
- About 20 minutes end to end
You do not need to remove fail2ban first. Both can coexist during the transition. Once CrowdSec's nftables bouncer is active, fail2ban is redundant for the same attack vectors and you can disable it at your own pace.
How to Install CrowdSec 1.6 on Proxmox VE
CrowdSec maintains an official Debian APT repository. Add it and install in two steps:
curl -s https://install.crowdsec.net | bash
apt update && apt install crowdsec -y
The service starts automatically. Confirm it and check the version:
systemctl status crowdsec
cscli version
Expected version output:
version: v1.6.3
Install Collections for SSH and Linux Auth
CrowdSec uses collections — bundles of parsers and detection scenarios published on the CrowdSec Hub. Install these two for Proxmox:
cscli collections install crowdsecurity/linux
cscli collections install crowdsecurity/sshd
crowdsecurity/linux handles generic syslog auth events, which includes pvedaemon (Proxmox web UI) login failures. crowdsecurity/sshd covers SSH brute-force and credential stuffing patterns.
Reload to activate:
systemctl reload crowdsec
Confirm both are active:
cscli hub list
Both collections should show status enabled.
Verify Log Acquisition
CrowdSec auto-detects common log files on install. Check what it found:
cscli metrics show acquisitions
If /var/log/auth.log is not listed, add it explicitly to /etc/crowdsec/acquis.yaml:
filenames:
- /var/log/auth.log
- /var/log/syslog
labels:
type: syslog
Restart after editing:
systemctl restart crowdsec
How to Install the nftables Bouncer
The bouncer translates CrowdSec's ban decisions into real firewall rules. Proxmox VE uses nftables natively, so install the matching bouncer:
apt install crowdsec-firewall-bouncer-nftables -y
It registers with the local LAPI automatically. Verify it is up and connected:
systemctl status crowdsec-firewall-bouncer
cscli bouncers list
Expected output:
Name IP Address Valid Last API pull
FirewallBouncer-1746882153 127.0.0.1 true 2026-05-10
Confirm bans are landing in nftables:
nft list set ip crowdsec crowdsec-blacklists
On a fresh install connected to the community feed, you will typically see thousands of IP entries already loaded — IPs actively attacking other CrowdSec nodes worldwide. That is the entire point.
Testing Your CrowdSec Install
Never brute-force your own host to validate a security install. Instead, inject a test ban using a safe IP from the RFC 5737 documentation range:
cscli decisions add --ip 192.0.2.1 --duration 5m --reason "connectivity-test"
Confirm nftables has it:
nft list set ip crowdsec crowdsec-blacklists | grep 192.0.2.1
Expected output:
elements = { 192.0.2.1 timeout 5m00s expires 4m58s }
Remove it:
cscli decisions delete --ip 192.0.2.1
Check the live decision list to see what the community feed has already blocked:
cscli decisions list --limit 10
When I first deployed CrowdSec on a fresh Proxmox node, the community CTI feed had already loaded over 12,000 blocked IPs before I finished the installation. With fail2ban on the same node, that count would have been zero until the first attack landed.
How to Share Bans Across a Proxmox Cluster
If you run a multi-node Proxmox cluster, you want a detection on one node to immediately ban that IP on all the others. CrowdSec's LAPI federation handles this without manual coordination.
Configure pve1 as the Central LAPI
By default, the LAPI only listens on localhost. Open it up so other nodes can connect — edit /etc/crowdsec/config.yaml on pve1:
api:
server:
listen_uri: 0.0.0.0:8080
Restart:
systemctl restart crowdsec
Generate a machine credential for each additional node:
cscli machines add pve2-agent --auto
cscli machines add pve3-agent --auto
Note the generated login and password for each — you need them on the secondary nodes.
Register Secondary Nodes Against the Central LAPI
Install CrowdSec on pve2 and pve3 the same way. Then point each agent at pve1's LAPI instead of the local one.
Edit /etc/crowdsec/local_api_credentials.yaml on pve2:
url: http://192.168.1.10:8080
login: pve2-agent
password: <password-from-pve1>
Disable the local LAPI so it does not conflict. Edit /etc/crowdsec/config.yaml on pve2:
api:
server:
enable: false
Restart on pve2:
systemctl restart crowdsec
Back on pve1, confirm all agents are visible:
cscli machines list
Name Last Update Status Version
pve1-agent 2026-05-10 14:45:00 online v1.6.3
pve2-agent 2026-05-10 14:46:10 online v1.6.3
pve3-agent 2026-05-10 14:47:03 online v1.6.3
One important gotcha: the nftables bouncer on each secondary node must be separately configured to point at pve1's LAPI. Edit /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml on pve2 and pve3 to set api_url: http://192.168.1.10:8080, using a bouncer-specific API key generated with cscli bouncers add on pve1. The machine credential you created earlier is for agent authentication only — bouncers use a different key.
Monitoring with the CrowdSec Console
The free tier of the CrowdSec Console at app.crowdsec.net shows active decisions, attacking IP geolocation and ASN data, and per-scenario breakdowns. Enroll with one command:
cscli console enroll <your-enrollment-key>
systemctl restart crowdsec
Your node appears in the Console within a few minutes. The free tier supports unlimited security engines. If you also run separate network segments with VLANs on Proxmox, the geolocation and ASN data helps confirm that flagged traffic is genuinely external rather than internal VLAN traffic being misclassified.
CrowdSec also exposes a Prometheus metrics endpoint at http://localhost:6060/metrics. The endpoint includes active decision counts, parser hit rates, and bouncer sync status — useful if you already have a Prometheus scraper pointed at your Proxmox infrastructure.
Conclusion
With CrowdSec 1.6 and the nftables bouncer running, your Proxmox VE 9 nodes are blocking known malicious IPs at the kernel level before they establish a single connection — and sharing those bans across your cluster in real time. The logical next step is expanding coverage: install the crowdsecurity/nginx or crowdsecurity/caddy collection if you run a reverse proxy on the same host, and browse the CrowdSec Hub for application-specific collections matching the rest of your self-hosted stack.