Building a Multi-Container CrowdSec Hub on Proxmox LXC
A complete technical walkthrough of migrating from standalone security to a centralized CrowdSec Hub-and-Spoke architecture.
Managing security across multiple Proxmox LXC containers can quickly become a nightmare. Initially, I was installing fail2ban or standalone CrowdSec instances on every single container. This meant checking logs across 15 different machines, duplicating blocklists, and wasting CPU cycles.
The solution? A CrowdSec Hub and Spoke Architecture.
The Architecture
Instead of every container doing its own threat analysis, we designate one LXC container as the LAPI Server (The Hub). All other containers (Nginx Proxy Manager, Nextcloud, Gitea) become Bouncers (The Spokes).
- The Hub: Reads the logs, communicates with the central CrowdSec threat intelligence API, and maintains the master blocklist.
- The Spokes: Only run the CrowdSec agent. They forward their logs to the Hub and ask the Hub if an IP should be blocked.
Implementation Steps
1. Setting up the Hub
First, spin up a lightweight Debian LXC container. Install CrowdSec:
curl -s https://install.crowdsec.net | sudo sh
sudo apt-get install crowdsec
Next, configure the LAPI to listen on the local network IP instead of localhost by editing /etc/crowdsec/config.yaml.
2. Registering the Spokes
On the Hub, generate a machine credential for each Spoke:
cscli machines add nginx-proxy-spoke --auto
This generates a password. On the Spoke (Nginx Proxy Manager), install the CrowdSec agent, but disable the local LAPI. Edit the config to point to the Hub's IP and use the generated credentials.
The Results
By centralizing the threat intelligence, I reduced the total CPU overhead of my security stack by 60%. If an attacker hits my Nextcloud container and gets banned, they are instantly banned across every other service on the network.
Need help architecting your Proxmox infrastructure?
Let's talk