DEV Community

Cover image for How to Deploy a Secure Hub-and-Spoke Cluster Across Proxmox LXC
Anas Rhimi
Anas Rhimi

Posted on

How to Deploy a Secure Hub-and-Spoke Cluster Across Proxmox LXC

If you are running multiple self-hosted services on a single Proxmox node, leaving them on a default flat network (vmbr0) is a massive security vulnerability. If one container is compromised, the attacker gains lateral movement across your entire infrastructure.

A Hub-and-Spoke architecture solves this. The "Hub" container acts as the strict central router and reverse proxy. The "Spoke" containers hold your actual applications. Spokes cannot talk to the physical network directly—all traffic must pass through the Hub, where it is inspected, filtered, and logged.

Here is a high-level look at the architecture we are building:

[ Internet / Physical LAN ]
    │
    ▼ (eth0: 192.168.1.50)
┌───────────────────────────────┐
│       HUB (hub-router)        │  <-- HAProxy + CrowdSec
└───────────────────────────────┘
    │ (eth1: 10.0.0.1)
    ▼ [ Internal vmbr1 Bridge ]
   ┌───────────┴───────────┐
   ▼                       ▼
┌──────────────┐    ┌──────────────┐
│ Spoke 1      │    │ Spoke 2      │
│ (10.0.0.10)  │    │ (10.0.0.11)  │
└──────────────┘    └──────────────┘

Enter fullscreen mode Exit fullscreen mode

By combining this architecture with Proxmox LXC (Linux Containers) and CrowdSec, you get enterprise-grade isolation with virtually zero performance overhead.

Here is exactly how to set it up.

Prerequisites

  • A Proxmox VE node.
  • Basic understanding of Linux networking.
  • SSH or Console access to your Proxmox host.

Step 1: Create the Isolated Spoke Network

By default, Proxmox uses vmbr0 to bridge directly to your physical network. We need a second, internal-only bridge for the Spokes.

  1. In the Proxmox Web GUI, go to Node -> System -> Network.
  2. Click Create -> Linux Bridge.
  3. Name it vmbr1.
  4. Leave the IPv4/CIDR and Bridge ports completely blank. (This ensures it has no direct physical internet access).
  5. Click Create, then click Apply Configuration.

Step 2: Provision the Hub Container

The Hub needs to talk to both the outside world (vmbr0) and the internal isolated network (vmbr1).

  1. Download a lightweight Debian or Ubuntu template (local -> CT Templates -> Templates).
  2. Create a new LXC container (CT ID: 100, Hostname: hub-router).
  3. Under the Network tab, attach it to vmbr0 (your public network). Assign it a static IP (e.g., 192.168.1.50/24) and your standard gateway.
  4. Finish creating the container, but do not start it yet.
  5. Select the hub-router container, go to Network, and click Add.
  6. Add a second interface (eth1), attach it to the new vmbr1 bridge, and assign an internal IP (e.g., 10.0.0.1/24). Leave the gateway blank.

Start the Hub container.

Step 3: Provision the Spoke Containers

Your Spokes will only live on the isolated internal network.

  1. Create a new LXC container for your application (CT ID: 101, Hostname: spoke-app-1).
  2. Under the Network tab, attach it only to vmbr1.
  3. Assign it an internal static IP: 10.0.0.10/24.
  4. Set its Gateway to the Hub's internal IP: 10.0.0.1.

If you try to ping the internet from spoke-app-1 right now, it will fail. This is exactly what we want. It is completely isolated.

Step 4: Configure the Hub as a NAT Router

To allow the Spokes to download software updates, the Hub must translate their internal traffic.

Log into the hub-router container console and enable IP forwarding:

echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

Enter fullscreen mode Exit fullscreen mode

Next, set up iptables to route the traffic from the 10.0.0.0/24 subnet out through eth0:

apt update && apt install iptables-persistent -y
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
iptables-save > /etc/iptables/rules.v4

Enter fullscreen mode Exit fullscreen mode

Now, your Spokes can securely reach the internet to pull packages, but the internet cannot directly reach them.

Step 5: Secure Ingress with CrowdSec & HAProxy

To route incoming web traffic securely to your Spokes, install HAProxy and CrowdSec on the Hub container.

  1. Install HAProxy:
apt install haproxy -y

Enter fullscreen mode Exit fullscreen mode
  1. Install the CrowdSec agent (which analyzes logs for attacks) and the HAProxy Bouncer (which drops malicious IPs):
curl -s [https://install.crowdsec.net](https://install.crowdsec.net) | sh
apt install crowdsec crowdsec-custom-bouncer-haproxy -y

Enter fullscreen mode Exit fullscreen mode

CrowdSec will automatically detect HAProxy and start monitoring its logs for Layer 7 attacks (like brute-forcing or SQL injection). If a malicious IP is detected, the Bouncer instantly blocks it at the Hub layer, ensuring the bad traffic never even touches your internal Spoke containers.

The Result

You now have a production-ready cluster architecture:

  • Zero Lateral Movement: A compromised Spoke cannot scan your physical home/office network.
  • Centralized Security: You only need to manage SSL certificates, firewall rules, and reverse proxies on the Hub.
  • Automated Defense: CrowdSec blocks known bad actors before they reach your apps.

Because this uses LXC instead of full KVM virtual machines, the overhead of this entire setup is less than 150MB of RAM.

Top comments (0)