The Real-World Risks of Sharing a Single Flat Subnet Across Virtual Machines
My Proxmox VE homelab cluster hosts 12 virtual machines and LXC containers. Initially, for convenience, I attached every VM to the default bridge vmbr0. All virtual machines, containers, and household devices leased IP addresses in the 192.168.1.x/24 subnet directly from the ISP router.
This flat network worked smoothly until I exposed a few services to the Internet: a staging web app, Nextcloud, and Nginx Proxy Manager. Within just two weeks, automated scanners discovered the staging container’s SSH port and launched a successful brute-force attack at 12,000 requests per hour.
The attackers obtained root privileges on that container. Worse yet, from that compromised machine, they scanned across the entire subnet directly into my Synology NAS, RTSP camera feeds, and personal workstations without hitting a single barrier. This lateral movement technique was vastly more dangerous than losing an isolated testing container.
The Limitations of Consumer Routers and Built-in Firewalls
Following post-incident remediation, I audited the infrastructure and identified three major bottlenecks:
- ISP routers lack segmentation features: Consumer routers have very small NAT session tables (typically under 8,000 sessions). They do not support true 802.1Q VLAN isolation and lack stateful inspection between subnets.
- PVE Firewall is difficult to monitor centrally: Proxmox provides
pve-firewallbased on nftables/iptables. However, writing rules manually for every interface on every VM is error-prone. It also lacks an intuitive dashboard for traffic logging, running IDS/IPS, or centrally managing Unbound DNS. - Bandwidth bottlenecks when using external routers: Hooking up an external router (such as a MikroTik hEX) over a single 1Gbps cable creates a router-on-a-stick topology. When two VMs on different VLANs transfer files between each other, the traffic has to leave the physical NIC, hit the router, and loop back to the host. Bandwidth immediately caps out at ~940 Mbps.
Three Routing Approaches for Proxmox
To isolate the DMZ (public services), LAN (workstations), and Internal network (databases, storage), there are three implementation strategies:
- Dedicated Hardware Appliance: Buying a standalone mini PC running OPNsense. The advantage is hardware isolation—if Proxmox crashes, the router stays up. The drawbacks: extra power consumption (15–25W running 24/7), occupied switch ports, and throughput locked to physical port speeds.
- Configuring iptables/nftables Directly on the Debian Host: Maximizes RAM savings. However, operational risk is extremely high. A single typo in an nftables rule can lock you out of port 8006, leaving physical monitor and keyboard access as your only recovery option.
- Virtualizing OPNsense Directly on Proxmox: Provisioning virtual Linux Bridges for OPNsense. OPNsense functions as the central gateway and firewall. Inter-VLAN traffic runs directly in memory across CPU cores using the VirtIO driver, achieving speeds that far exceed standard physical network cables.
Step-by-Step Guide to Installing and Configuring OPNsense on Proxmox VE
After more than six months of real-world operation, virtualizing OPNsense has delivered the highest performance on existing hardware. Inter-VM traffic easily reaches 12–15 Gbps without requiring expensive 10GbE network cards.
Step 1: Set Up Linux Bridges on the Proxmox Host
The minimal architecture requires two separate bridges:
vmbr0: The WAN interface. This bridge binds directly to the host’s physical network adapter for Internet access.vmbr1: The internal LAN interface. This bridge has no physical ports assigned (bridge-ports none), functioning as an isolated virtual switch.
Open /etc/network/interfaces on the Proxmox host or edit it via the GUI (Node -> System -> Network):
auto lo
iface lo inet loopback
iface eno1 inet manual
# Host physical network port
auto vmbr0
iface vmbr0 inet static
address 192.168.1.10/24
gateway 192.168.1.1
bridge-ports eno1
bridge-stp off
bridge-fd 0
# WAN Bridge - connects to external modem/router
auto vmbr1
iface vmbr1 inet manual
bridge-ports none
bridge-stp off
bridge-fd 0
# Virtual LAN Bridge - internal host communication only
Apply the configuration immediately without rebooting the server:
ifreload -a
Step 2: Create the OPNsense Virtual Machine
Download the amd64 OPNsense ISO (select the dvd image) from the official website and upload it to Proxmox ISO storage. Then, create the VM using the following specifications:
- General: Set a VM name (e.g.,
OPNsense-Gateway), check Start at boot, Order: 1. - OS: Select the OPNsense ISO, Type: Other.
- System: Qemu Agent: Enabled. SCSI Controller: VirtIO SCSI single.
- Disks: Bus: SCSI, size 32 GB, check Discard if running on an SSD/NVMe.
- CPU: 2 vCPUs. Set CPU Type to host so OPNsense detects the hardware AES-NI instruction set, accelerating OpenVPN/WireGuard throughput.
- Memory: 4096 MiB. You must uncheck Ballooning Device. Dynamic memory allocation frequently causes the FreeBSD kernel to crash randomly.
- Network:
- NIC 1 (WAN): Bridge
vmbr0, Model VirtIO (paravirtualized). - After creating the VM, navigate to Hardware -> Add -> Network Device to add NIC 2 (LAN): Bridge
vmbr1, Model VirtIO.
- NIC 1 (WAN): Bridge
Step 3: Install the OS and Assign Interfaces
Start the virtual machine and open the Console tab in Proxmox:
- Once booted into the Live environment, log in with user
installerand passwordopnsense. - Select the default keymap, then choose Install (ZFS) or Install (UFS). For a single-disk VM, UFS is the most stable and memory-efficient choice.
- Once installation completes, select Reboot. Make sure to remove the ISO from the virtual CD/DVD drive.
- After rebooting, the console displays a 13-item menu. Press
1to assign interfaces:- Do you want to configure LAGGs now? Select
N. - Do you want to configure VLANs now? Select
N. - WAN interface: assign to
vtnet0(connected to vmbr0). - LAN interface: assign to
vtnet1(connected to vmbr1).
- Do you want to configure LAGGs now? Select
- Press
2to configure the LAN IP address:- Enter the new gateway IP:
10.0.0.1, subnet mask bit count:24. - Enable DHCP Server: select
Y, set the pool range from10.0.0.100to10.0.0.200.
- Enter the new gateway IP:
Step 4: Disable VirtIO Hardware Offloading (Critical Step)
FreeBSD running on KVM/QEMU frequently conflicts with VirtIO hardware offloading features. Typical symptoms include successful ICMP pings but extremely slow web page loading and 40–60% packet loss. Resolve this immediately:
- Create a test VM (Ubuntu or Windows) connected to
vmbr1. It will automatically receive an IP in the10.0.0.xrange. - Open a browser inside that VM, navigate to
https://10.0.0.1, and log in asroot. - Go to: Interfaces -> Settings.
- Under Hardware Acceleration, check all three boxes to disable hardware offloading:
- Disable Hardware Checksum Offload
- Disable Hardware TCP Segmentation Offload
- Disable Hardware Large Receive Offload
- Click Save and reboot OPNsense to apply the changes.
Step 5: Set Up a DMZ and Secure Port Forwarding
Your network architecture is now clearly partitioned:
- Internal VMs (Database, Graylog, NAS) connect strictly to
vmbr1, completely isolated from internet port scanners. - When publishing a web application externally, create a rule under Firewall -> NAT -> Port Forward: forward port 443 from the WAN IP to the internal IP of Nginx Proxy Manager.
- To isolate other service tiers, simply assign VLAN tags in OPNsense (e.g., VLAN 20 for DMZ, VLAN 30 for IoT) over the same virtual switch
vmbr1.
Real-World Operational Data After 6 Months
The system has been running continuously for half a year with the following measured metrics:
- Reliability: 182 days of continuous uptime with zero kernel panics. Reboot times following firmware updates average 38–45 seconds.
- Resource Consumption: OPNsense operates with minimal footprint. Average CPU load ranges between 0.8% and 2.5%, with RAM usage holding steady at ~950MB (with Unbound DNS enabled alongside a 150,000-domain blocklist).
- Throughput Tested via iperf3: Inter-subnet bandwidth through OPNsense clocked in at 11.4 Gbps—over 12 times faster than routing through an external 1Gbps physical appliance.
Key takeaway from production: Always keep the Proxmox Web GUI (port 8006) bound to a static IP on an independent physical interface. Never make Proxmox host management reliant on the OPNsense VM’s DHCP service. If the firewall VM runs into boot issues, you will still retain full management access to troubleshoot.

