Short answer: Proxmox NAT and port forwarding in four commands
Guests on a private bridge (here vmbr1, 10.10.10.0/24) reach the internet
through the host's public bridge vmbr0 once you enable IP forwarding and add a
MASQUERADE rule. A DNAT rule forwards a public port to a guest, and a few lines in
/etc/network/interfaces make a setup that survives reboots.
# 1. Enable IP forwarding now, and on every boot
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/99-ip-forward.conf
# 2. Outbound NAT: private guests leave via the host's public IP
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
# 3. Port forwarding: host port 2222 -> SSH on guest 10.10.10.5
iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 2222 -j DNAT --to-destination 10.10.10.5:22
The iptables rules are gone after a reboot. The section make it survive a reboot shows the Proxmox way to persist them.
The setup: a private bridge with no way out
Proxmox makes it easy to put guests on a private bridge: a virtual switch that connects VMs and
containers to each other, but not to the internet. That saves public IPs and keeps internal services
unreachable from outside. The catch: a guest on 10.10.10.0/24 cannot resolve DNS, install
updates or reach anything on the internet until the host routes and translates its traffic. And if a
service on that guest should be reachable from outside, you need a second rule for the inbound side.
Create the private bridge in /etc/network/interfaces (or under Node → System → Network):
auto vmbr1
iface vmbr1 inet static
address 10.10.10.1/24
bridge-ports none
bridge-stp off
bridge-fd 0
Guests on vmbr1 get an address from 10.10.10.0/24 and use
10.10.10.1 as their gateway.
Step 1: enable IP forwarding on the Proxmox host
Linux does not route packets between interfaces by default. net.ipv4.ip_forward=1 turns
routing on. sysctl -w changes it immediately; the file in /etc/sysctl.d/
makes it permanent. Check the current value with sysctl net.ipv4.ip_forward
(it should print 1). For IPv6 the equivalent is net.ipv6.conf.all.forwarding=1.
Step 2: outbound NAT with MASQUERADE
MASQUERADE rewrites the source address of packets leaving through vmbr0 to the host's
public IP and tracks each connection, so replies find their way back to the right guest:
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
-s is your private subnet, -o the bridge that holds the public IP. With
forwarding and this rule in place, a guest can ping 1.1.1.1 and run
apt update.
Step 3: port forwarding with DNAT
Destination NAT handles the inbound direction. This rule sends TCP port 8080 on the host to a web
server on port 80 of guest 10.10.10.5:
iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to-destination 10.10.10.5:80
One public IP can expose many services this way, each on its own public port. If your FORWARD chain policy is DROP (for example because another firewall manages it), also allow the forwarded traffic:
iptables -A FORWARD -d 10.10.10.5 -p tcp --dport 80 -j ACCEPT
Make it survive a reboot
iptables rules live in memory only. The approach the Proxmox wiki uses is to attach them to the
private bridge in /etc/network/interfaces, so they are added when the bridge comes up and
removed when it goes down:
auto vmbr1
iface vmbr1 inet static
address 10.10.10.1/24
bridge-ports none
bridge-stp off
bridge-fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s 10.10.10.0/24 -o vmbr0 -j MASQUERADE
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to-destination 10.10.10.5:80
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to-destination 10.10.10.5:80
Apply with ifreload -a. If the Proxmox firewall is enabled on these guests, the wiki also
recommends separating connection tracking zones so NAT and the firewall bridges do not interfere:
post-up iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1 (and the matching
-D line under post-down).
Why doing this by hand gets risky
The commands are simple; the operations around them are not.
- Lockout. A wrong FORWARD policy or a flushed chain while you work over SSH can cut your own access. On a remote server that means a console session or a support ticket.
- Mixing with the Proxmox firewall. Proxmox manages its own iptables chains. Rules added in the wrong place or flushed together with them lead to surprises after an update or a firewall reload.
- Drift. Over time you collect forwards for guests that no longer exist, duplicate MASQUERADE rules from earlier attempts, and no record of who opened which port and why.
Three habits help regardless of tooling:
- Keep a management path (IPMI, a console, or a separate interface) that does not depend on the rules you are editing.
- Only MASQUERADE private (RFC1918) source ranges, never a public range by accident.
- Document every port forward with the reason it exists, and remove it when the guest goes away.
Doing it in NexoVirt
NexoVirt has a per-host NAT & port forwarding page for admins. You pick the WAN bridge and the private network; NexoVirt enables IP forwarding, writes the MASQUERADE rule and keeps it active across reboots with its own small systemd service. Port forwards are entries in a table: protocol, public port, destination IP and port, and a comment. Each entry is checked before it is applied (the destination must be inside the private network, a public port can only be used once, and only private source ranges are ever masqueraded), and the host agent checks again before writing.
NexoVirt writes only its own chains (NEXOVIRT-PRE, NEXOVIRT-POST,
NEXOVIRT-FWD) and never flushes the built-in or Proxmox firewall chains, so applying or
clearing NAT does not touch anything the Proxmox firewall manages. The same page shows the host's current
firewall rules (iptables, nftables, ufw, firewalld, pve-firewall) as readable tables, plus a network map of
bridges, guests and active forwards.
NAT sits next to IP address management (Proxmox IPAM with IPv4/IPv6 zones and automatic assignment) and per-guest firewall rules, so the whole network side of a guest is handled in one place. The full feature list is on the features page.