Proxmox VLAN Setup: Tagged Bridges, Firewall Rules & SSH Hardening
Learn how to configure tagged bridges and firewall rules in Proxmox for true network segmentation. Includes LXC tagging, fail2ban hardening, and subnet best practices.
On this page
The most common VLAN mistake on Proxmox isn't getting the bridge right — it's leaving the firewall wide open and losing segmentation entirely. This guide walks through setting up Linux bridges for tagged traffic, wiring those tags into your VMs and containers, then hardening everything from SSH brute-force attacks to lateral movement between subnets so your homelab or small datacenter actually behaves like a real network.
Key Takeaways
- Tagged Bridges: Use
pvewith VLAN-aware flags instead of the default untagged bridge for multi-VLAN traffic. - Firewall First: Enable per-node firewall rules before moving workloads so you don't accidentally expose everything to your upstream router.
- LXC Tagging: Set the
network.vlanprioproperty in each container's config to enforce VLAN priority and tagging at the hypervisor level. - Fail2ban + SSHD: A properly tuned fail2ban jail with Proxmox-specific filters catches 90%+ of brute-force attempts within minutes, not hours.
- Subnet Segmentation: Keep management traffic on a dedicated VLAN and use untagged or tagged ports for VMs so your host stays reachable even when something goes sideways.
Setting Up the Linux Bridge with Tagged Traffic
The first thing most people get wrong is assuming their existing vmbr0 handles VLAN tags correctly out of the box. By default, Proxmox creates a bridge without VLAN awareness, which means tagged frames either get stripped or dropped depending on how your upstream switch is configured. The fix is straightforward: enable VLAN filtering and set up subinterfaces for each VLAN you need.
Start by editing /etc/network/interfaces:
auto vmbr0
iface vmbr0 inet static
address 192.168.1.1/24
gateway 192.168.1.254
bridge-ports ens3
bridge-stp off
bridge-fd 0
vlan-aware yes
auto vmbr0.10
iface vmbr0.10 inet manual
vif-up
pre-up ip link set dev vmbr0.10 address $(cat /sys/class/net/ens3/address)
auto vmbr0.20
iface vmbr0.20 inet manual
vif-up
The vlan-aware yes directive tells the kernel's bridge subsystem to pass tagged frames through rather than stripping them, which is essential when your upstream switch uses 802.1Q tagging. The subinterfaces (vmbr0.10, vmbr0.20) each carry their own set of VMs and LXCs without interfering with one another.
One gotcha worth noting: if you're migrating an existing setup, don't forget to remove the old untagged bridge entries from your container configs before enabling VLAN awareness — otherwise Proxmox will complain about conflicting MAC addresses on boot. I've spent more than a few hours debugging this exact issue after upgrading clusters and not realizing that LXC config files retain their original bridge=vmbr0 references.
How to Assign VMs and Containers to Specific VLANs
With the bridge configured, assigning workloads is mostly about setting the right properties during creation or editing existing configs. For KVM VMs, you set the network device's VLAN ID directly in the GUI under Hardware → Network. From the CLI:
qm set 100 --net0 virtio,bridge=vmbr0,vlan=10
For LXCs, it gets a bit more interesting because LXC containers don't have their own network namespace by default — they share one with the host. This means VLAN tagging happens at the hypervisor level rather than inside the container:
pct set 201 --network name=eth0,bridge=vmbr0,vlanprio=10,id=10
The vlanprio property is what actually controls the tag on outgoing frames. Without it, even if you specify id=10, the container's traffic might still arrive untagged depending on your bridge configuration and how LXC handles netdev propagation. I've seen this trip up people setting up VLAN-aware LXCs — they configure everything correctly but their router sees no tags because the hypervisor isn't tagging at all.
If you need more control, particularly for containers that should appear as distinct devices rather than sharing the host's network stack entirely, consider using netmap or dedicated subinterfaces per container:
pct set 201 --network name=eth0,type=veth,vlanprio=10,id=10,gw=dhcp
This approach works well when you're running services like DNS servers or DHCP relays inside LXCs and need them to appear as independent nodes on the VLAN. For most homelab setups though, the simpler bridge mode with explicit vlanprio is sufficient — it's lighter weight and easier to debug when something goes wrong.
Configuring Proxmox Firewall Rules for Segmentation
VLANs alone won't protect your network if every subnet can talk to every other subnet at will. The real benefit of segmentation comes from applying firewall rules that restrict lateral movement, especially important when you're running services like Build a Private Cloud at Home with Proxmox VE where containers and VMs share the same physical infrastructure.
Enable the firewall on your node first:
pvesh create /nodes/pve/firewall/options -enable 1
Then add rules for each VLAN subnet. The Proxmox firewall uses a chain-based approach with iptables under the hood, so you can inspect active rules at any time:
# Allow established connections on all chains
pvesh create /nodes/pve/firewall/rules -chain INPUT -policy ACCEPT \
--match state ESTABLISHED,RELATED --action ACCEPT
# Block VMs in VLAN 20 from reaching VLAN 10 management subnet
pvesh create /nodes/pve/firewall/rules -chain FORWARD -policy DROP \
--source 192.168.10.0/24 --destination 192.168.20.0/24 \
--protocol tcp --dport 80,443 --action ACCEPT
# Allow all traffic within VLANs (intra-VLAN)
pvesh create /nodes/pve/firewall/rules -chain FORWARD -policy DROP \
--source vmbr0.10 --destination vmbr0.10 --action ACCEPT
A practical tip: start with a DROP policy on the FORWARD chain and add rules in order of specificity. This way, any traffic that doesn't match an explicit rule gets dropped rather than being allowed through by default — which is what you want for security hardening but can be confusing during initial setup when things don't work as expected.
For multi-node clusters, consider using the Build a Software-Defined Datacenter with Proxmox VE approach of applying firewall rules at both the node and cluster level so that traffic between nodes respects VLAN boundaries even during live migration or storage access.
Setting Up Fail2ban for SSH Hardening on Proxmox
SSH is often the weakest link in any datacenter, and Proxmox's default configuration leaves it vulnerable to brute-force attacks — especially if you're exposing your management interface to external networks or running services like Cloudflare Tunnel on Proxmox for Zero-Trust Remote Access that route traffic through SSH tunnels.
Install fail2ban and the Proxmox-specific filter:
apt update && apt install -y fail2ban iptables-persistent
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
systemctl enable --now fail2ban
Create or edit /etc/fail2ban/jail.local with these settings:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
backend = systemd
action = iptables-multiport[name=sshd, port="ssh", protocol=tcp]
[proxmox-api]
enabled = true
port = https
filter = proxmox
logpath = /var/log/pveproxy/access.log
maxretry = 5
findtime = 300
bantime = 1800
backend = systemd
action = iptables-multiport[name=proxmox, port="https", protocol=tcp]
[nginx-404]
enabled = true
port = http,https
filter = nginx-no-such-site
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 3600
bantime = 86400
backend = systemd
action = iptables-multiport[name=nginx-404, port="http,https", protocol=tcp]
The proxmox-api jail catches failed authentication attempts against the Proxmox REST API — which is particularly useful if you're running automation tools like Ansible or Terraform that authenticate frequently. The [nginx-404] rule helps catch port scanning and automated attacks targeting common services on your host.
One thing I've learned through experience: set findtime conservatively during initial deployment. If it's too short, legitimate users who mistype their password once will get locked out for the full bantime. A 10-minute find window with a 60-minute ban is usually a good starting point — you can always tighten it later based on your actual attack patterns.
After configuration, verify that jails are active:
fail2ban-client status sshd
fail2ban-client status proxmox-api
iptables -L f2b-sshd --line-numbers
Network Segmentation Best Practices for Homelab and Production Environments
The question isn't whether to segment your network — it's how granular you want to be. Too few VLANs and everything ends up in the same broadcast domain; too many and management becomes tedious without proportional benefit. Here's a practical breakdown:
| VLAN ID | Purpose | Devices/Services | Notes |
|---|---|---|---|
| 10 | Management | Proxmox host, VMs, LXCs | Untagged by default on vmbr0; keep DHCP here |
| 20 | Services (Docker) | Docker containers, microservices | Tagged traffic; isolated from management |
| 30 | Storage | iSCSI targets, NFS exports, PBS nodes | Dedicated to storage I/O with low latency requirements |
| 40 | Guest/VLAN-aware VMs | Windows/Linux VMs needing VLAN tagging | Use vlanprio property in LXC configs or native VLAN tags in KVM |
The key insight from years of running both homelab and production Proxmox clusters: don't put your management traffic on the same untagged port as your storage. If you do, a heavy I/O load can starve your management interface — particularly problematic when monitoring tools or backup jobs like Automated Backups with Proxmox Backup Server are running simultaneously.
For homelab setups, VLAN 10 as the primary untagged bridge handles most of what you need. For production environments where reliability matters more than simplicity, consider dedicating one physical NIC to storage traffic and using bond mode for redundancy on the management/service interface pair. This approach scales well whether you're running How to Ditch Bare Metal and Run Everything on Proxmox services or managing a full software-defined datacenter with hundreds of workloads across multiple nodes.
Conclusion
VLAN configuration in Proxmox is fundamentally about three things: tagged bridges that actually pass tags, firewall rules that enforce segmentation rather than just allowing traffic by default, and SSH hardening that catches attacks before they become problems. The most common mistake — leaving the firewall wide open after VLAN setup — turns your carefully segmented network into a flat one again, which defeats much of the purpose. Start with tagged bridges, apply conservative fail2ban rules, and let your firewall do the heavy lifting for segmentation enforcement rather than relying on VLAN tags alone. Once you've got that foundation in place, adding more VLANs or services becomes straightforward — whether you're building a homelab like How to Ditch Bare Metal and Run Everything on Proxmox or scaling up for production workloads.