ESC

Start typing to search across invoices, services, domains, tickets, and more...

Search... Ctrl+K
Virtualization & Host Nodes

Proxmox VE NAT Network Setup: vmbr1 Private Subnet, iptables MASQUERADE and Port Forwarding

6 steps 15 min read 1 views 0
On this page

When you run out of public IPs on a dedicated server, or some virtual machines (databases, internal test boxes, build runners) simply do not need one, the cleanest solution is a Proxmox VE NAT network. You create a vmbr1 bridge with no physical port as a private subnet, let the host masquerade VM traffic behind its own public IP with iptables MASQUERADE, and publish only the ports you need with DNAT port forwarding. This guide covers Proxmox VE 7.x/8.x (Debian based), with guest examples for Debian/Ubuntu and CentOS/Rocky/AlmaLinux.

We assume the public bridge is vmbr0 (the Proxmox default), the private subnet is 10.10.10.0/24 and the host's private address is 10.10.10.1. Replace vmbr0 if your public bridge has another name. For installing Proxmox and giving VMs public IPs, see the existing help center guides "Install Proxmox VE" and "Assign IPs to Proxmox VMs".

Step 1: Back Up the Proxmox Network Config and Identify the Public Bridge

Save a copy of /etc/network/interfaces and check which bridge carries the default route. A typo in network config can lock you out remotely, so keep IPMI/KVM console access ready or ask support for help.

cp /etc/network/interfaces /etc/network/interfaces.bak.$(date +%F)
ip -br addr
ip route | grep default

Step 2: Create the vmbr1 NAT Bridge with iptables MASQUERADE

Append the vmbr1 block below to /etc/network/interfaces. bridge-ports none makes it a purely internal switch; the post-up lines enable IPv4 forwarding and masquerade traffic from 10.10.10.0/24 leaving through vmbr0.

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

Apply the configuration and make IP forwarding permanent through sysctl:

ifreload -a
echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-ip-forward.conf
sysctl --system
ip addr show vmbr1
iptables -t nat -S POSTROUTING

You can also add vmbr1 in the web UI under Node → System → Network → Create → Linux Bridge, but the MASQUERADE rules still have to be added to the file by hand.

Step 3: Attach VMs to the NAT Network and Set Private IPs

In the VM's Hardware → Network Device, switch the bridge to vmbr1 (or add a second NIC on vmbr1). Inside the guest, configure a static 10.10.10.x address with 10.10.10.1 as gateway:

# Debian (/etc/network/interfaces inside the VM)
auto ens18
iface ens18 inet static
    address 10.10.10.101/24
    gateway 10.10.10.1
    dns-nameservers 1.1.1.1 8.8.8.8

# Ubuntu (/etc/netplan/50-nat.yaml, then: netplan apply)
network:
  version: 2
  ethernets:
    ens18:
      addresses: [10.10.10.102/24]
      routes:
        - to: default
          via: 10.10.10.1
      nameservers:
        addresses: [1.1.1.1, 8.8.8.8]

# CentOS / Rocky / AlmaLinux 8/9
nmcli con mod ens18 ipv4.method manual ipv4.addresses 10.10.10.103/24 \
  ipv4.gateway 10.10.10.1 ipv4.dns "1.1.1.1 8.8.8.8"
nmcli con up ens18

# test from the VM
ping -c 3 10.10.10.1
ping -c 3 1.1.1.1

If 1.1.1.1 answers, outbound NAT works. If IPs respond but hostnames do not resolve, check the DNS settings.

Step 4: Port Forwarding with DNAT to Expose VM Services

NAT guests cannot be reached from outside by default. To allow SSH or publish a website, add DNAT rules on the host that forward a port on the public IP to the VM:

# public port 2201 -> VM 10.10.10.101:22 (SSH)
iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 2201 -j DNAT --to-destination 10.10.10.101:22
# public port 8080 -> VM 10.10.10.102:80 (HTTP)
iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 8080 -j DNAT --to-destination 10.10.10.102:80

iptables -t nat -L PREROUTING -n --line-numbers
Never forward ports the host itself uses (22, 8006 and so on), or you will lose access to the host or the Proxmox web UI. If the host runs a firewall, allow the forwarded ports there too.

Step 5: Persist the iptables Port Forwarding Rules

Rules entered on the command line disappear after a reboot. Choose one method: put them into the vmbr1 post-up/post-down lines (they live and die with the bridge, which is the tidiest), or install iptables-persistent and save the running rules. If the Proxmox firewall is enabled on these VMs, add the conntrack zone rule as well, otherwise NAT replies can be dropped.

# Option A: add to the vmbr1 block in /etc/network/interfaces
    post-up   iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 2201 -j DNAT --to-destination 10.10.10.101:22
    post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 2201 -j DNAT --to-destination 10.10.10.101:22
    # only if the Proxmox firewall is enabled on these VMs:
    post-up   iptables -t raw -I PREROUTING -i fwbr+ -j CT --zone 1
    post-down iptables -t raw -D PREROUTING -i fwbr+ -j CT --zone 1

# Option B: save the current rules with iptables-persistent
apt update && apt install -y iptables-persistent
netfilter-persistent save
cat /etc/iptables/rules.v4

Step 6 (Optional): DHCP for the NAT Subnet with dnsmasq

With many VMs, typing static IPs gets tedious. Install dnsmasq on the host, bind it to vmbr1 only, and pin fixed addresses with dhcp-host for VMs that have port forwards:

apt install -y dnsmasq
cat > /etc/dnsmasq.d/vmbr1.conf <<'EOF'
interface=vmbr1
bind-interfaces
except-interface=lo
dhcp-range=10.10.10.100,10.10.10.200,255.255.255.0,12h
dhcp-option=option:router,10.10.10.1
dhcp-option=option:dns-server,1.1.1.1,8.8.8.8
# fixed lease for one VM (MAC from: qm config 101 | grep net0)
dhcp-host=BC:24:11:AA:BB:CC,10.10.10.101
EOF
systemctl restart dnsmasq
systemctl status dnsmasq --no-pager
Because dnsmasq is bound to vmbr1 only, it never answers DHCP on the public side and will not interfere with the data center network.

FAQ

The VM can ping 10.10.10.1 but has no internet access

Check that /proc/sys/net/ipv4/ip_forward is 1, that iptables -t nat -S POSTROUTING shows the MASQUERADE rule with the correct outgoing interface, and that the host itself can reach the internet.

Port forwarding does not work from outside

Make sure the DNAT rule uses -i vmbr0, the service inside the VM listens on 0.0.0.0 rather than 127.0.0.1, the guest firewall allows the port, and, if the Proxmox firewall is on, the fwbr+ conntrack zone rule is present.

Can NAT VMs and public-IP VMs run side by side?

Yes. Public-IP VMs stay on vmbr0, NAT VMs use vmbr1, and a single VM can even have one NIC on each. If you need more public IPs, contact IMIDC sales to add an IP block.

Still stuck? Open a ticket with IMIDC 24/7 technical support: https://www.imidc.com/submitticket.php

Was this answer helpful?

Related Tutorials