Proxmox NAT & port forwarding for private guests
June 22, 2026 · 6 min read
If you run guests on a private bridge in Proxmox VE, those guests cannot reach the internet and nothing on the internet can reach them, until you configure NAT and, optionally, port forwarding on the Proxmox host itself. Getting this right involves iptables chains, kernel forwarding flags, persistence across reboots, and careful rule ordering. Done by hand, it is one of the more fragile parts of a Proxmox setup. This post explains how outbound NAT and inbound port forwarding work in Proxmox, why the manual approach carries real risk, and how NexoVirt handles it through a validated, reboot-safe configuration.
The Problem: Private Bridges and No Routing
Proxmox makes it straightforward to create guests on a private bridge: a virtual switch that
connects your VMs and LXC containers to each other but not directly to the internet. This is
useful: guests on a private network cannot be reached from the outside by default, and you can
assign RFC1918 addresses (10.0.0.0/8, 172.16.0.0/12,
192.168.0.0/16) without needing public IPs for every VM.
The trade-off is that without additional configuration, those guests have no path out either.
A guest on 10.10.0.0/24 attached to a private bridge cannot make a DNS query,
cannot pull a package update, and cannot reach anything on the internet. If you also want
to expose a service, say, a web server running on that private guest, from outside the
host, you need a second piece of configuration on top.
Both problems are solved with standard Linux kernel networking: NAT (MASQUERADE) for outbound traffic, and DNAT port forwarding for inbound exposure. The logic is well-understood; the challenge is doing it safely and keeping it working across reboots.
Outbound NAT with MASQUERADE
NAT (Network Address Translation) in the MASQUERADE form lets traffic from a private subnet leave the host using the host's own public IP address. The kernel rewrites the source address on outbound packets and tracks the connection so replies can be routed back to the correct private guest.
In iptables terms, the rule lives in the nat table's POSTROUTING
chain:
iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o vmbr0 -j MASQUERADE
Here vmbr0 is the WAN-facing bridge (the one with the public IP) and
10.10.0.0/24 is the private subnet. You also need the kernel's IP forwarding
enabled:
sysctl -w net.ipv4.ip_forward=1
With those two things in place, guests on the private bridge can reach the internet. Replies come back to the host's IP and the kernel's connection tracking table routes them back to the originating guest.
Port Forwarding with DNAT
Port forwarding (DNAT: Destination NAT) solves the inbound direction. If a guest at
10.10.0.5 is running a web server on port 80, you can make it
reachable from outside the host by adding a DNAT rule:
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.10.0.5:80
Traffic arriving at the host on TCP port 8080 is rewritten before routing and
forwarded to the private guest. You also need a FORWARD rule to allow that forwarded traffic
through:
iptables -A FORWARD -d 10.10.0.5 -p tcp --dport 80 -j ACCEPT
DNAT lets you expose multiple services on a single public IP by assigning each a distinct public port. The public port maps to a private destination: the guest IP and its internal service port, and each mapping is independent.
Why Doing This by Hand Is Risky
The individual commands above are not complicated. The risk comes from everything around them.
The most acute danger is locking yourself out. If you apply an incorrect FORWARD policy or accidentally flush the INPUT chain while tuning rules via an SSH session, the connection drops and the change is permanent until you can access the host through a console or IPMI. On a remote server this can mean a support ticket and downtime.
Persistence is another common failure point. iptables rules are in-memory by
default; they disappear on the next reboot. Persisting them requires iptables-save
to a rules file, a restore hook at boot, and awareness that Proxmox VE also manages its own
firewall rules in the same iptables tables. Interleaving your rules with PVE's can produce
rule ordering surprises, especially after a Proxmox update regenerates its own chains.
Finally, hand-edited rules accumulate. Over time, a server acquires stale DNAT entries for guests that no longer exist, duplicate MASQUERADE rules from multiple attempts, and no record of who added what or when. Auditing a hand-maintained ruleset on a production Proxmox host is tedious work.
Doing It in NexoVirt
NexoVirt includes a per-host NAT & port forwarding page (admin-only) that manages the above configuration without you writing iptables rules manually.
You enable NAT by selecting the WAN bridge and specifying the private CIDR. NexoVirt writes
the MASQUERADE rule, enables ip_forward, and persists the configuration across
reboots via a generated /usr/local/sbin/nexovirt-nat.sh script and a
nexovirt-nat.service systemd oneshot, so the rules survive a reboot without
any extra steps.
Port forwards are added individually through a modal: protocol, public port, destination IP, destination port, and an optional comment. NexoVirt validates each entry: destination IP must fall within the configured private CIDR, ports must be in range, and the same public port cannot be mapped twice on the same host. The panel then applies all active rules in one operation.
Crucially, NexoVirt writes only its own dedicated chains
(NEXOVIRT-PRE, NEXOVIRT-POST, NEXOVIRT-FWD), which
are jumped into from the built-in chains. It never flushes the built-in iptables chains or
PVE's own chains. Only the NEXOVIRT-* chains are rebuilt on each apply.
This means Proxmox's own firewall rules are untouched, and applying or clearing NAT
configuration does not affect anything the Proxmox firewall manages.
Alongside NAT, the same page includes a read-only firewall inspection view. NexoVirt reads the host's current iptables / nftables / ufw / firewalld / pve-firewall output via the host agent, normalises it into a unified rule model, and displays it per tool and chain with colour-coded action badges. It also shows a network map: a topology view of the host's bridges, the guests attached to each by IP, and any active NAT or port-forward overlays. Both the inspection output and the map are persisted in the database so the page renders instantly from a snapshot without requiring a live agent round-trip.
Safety Notes Worth Keeping in Mind
Whether you configure NAT by hand or through a panel, a few practices reduce operational risk.
First, keep your management access on a separate path from the traffic you are NATing. If your SSH session into the Proxmox host travels over the same interface and bridge as the guest traffic, a misconfigured FORWARD DROP policy can cut your own access. A management interface or IPMI/console access that bypasses iptables entirely is worth having before experimenting with firewall rules.
Second, validate MASQUERADE sources server-side. NexoVirt rejects any MASQUERADE source that is not a valid RFC1918 range at the panel level and again in the host agent before writing any rules: it refuses to write a MASQUERADE rule for a public IP range regardless of what is submitted. This prevents a misconfiguration that would NAT traffic you did not intend to rewrite.
Third, keep port-forward rules minimal and documented. Every open public port is a potential exposure. NexoVirt's port-forward table includes a comment field specifically to record why each mapping exists, making it easier to audit and remove stale entries when a guest is deleted or reassigned.
Where This Fits in NexoVirt
NAT and port forwarding are part of the broader networking stack in NexoVirt, which also covers IPAM (IPv4/IPv6 zones with automatic subnet math, static or DHCP assignment at provision time), network discovery (detecting bridges and their roles: WAN, private, internal), and per-guest firewall rules with admin-locked vs customer-editable policies and reusable firewall presets. The goal is to keep the full guest network lifecycle: provision an IP, configure routing, expose a port, inspect what is actually running on the host, manageable from one place without shelling into the Proxmox host for each step.
NexoVirt is available now. Community Edition is free (up to 2 nodes). If you are running Proxmox guests on private bridges and want a safer, auditable way to manage outbound NAT and port forwarding, you can get started free and try it against your own infrastructure. The full feature set: IPAM, Plans with enforcement, alerting, a customer portal, and a clean REST API, is covered on the features page.