Proxmox, NAT and preventing the need for reboots

Published: 1 year ago web dev

If you have a single IP address and are using Proxmox, you're probably using NAT. The common advice is to put your iptables rules in the interface on the post-up and post-down commands. But this comes with a big problem. If you add additional rules (e.g. to forward ports on a new VM) you need to restart the network bridge. Doing so results in all running VMs dropping their network connection and they need to be rebooted. Not good. Here's my workaround.

We're going to move the management of the NAT rules into bash scripts but to do so I'm going to make two assumptions.

  1. You're using the proxmox builtin firewall so you aren't currently manually managing iptables at all. Any other solutions may interfere with the below.

  2. You don't need any additional/separate NAT rules for any other services.

The post-up and post-down commands are going to run the bash scripts, your bridge should end up looking something like this:

auto vmbr0
iface vmbr0 inet static
    address 192.168.0.1
    netmask 255.255.255.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up   /etc/iptables/post-up.sh
    post-down /etc/iptables/post-down.sh

The post-up.sh script can then handle the creation of the nat rules:

#!/bin/bash

#internet access for vms
iptables -t nat -A POSTROUTING -s '192.168.0.0/24' -o eth0 -j MASQUERADE
#example web port forward to vm
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.2:80

We can cheat on the post-down.sh script and just clear the nat rules table. If you are using other custom nat rules you'd need to delete each rule previously created.

#!/bin/bash

iptables -t nat -F

Now if you spin up a new VM and need to forward ports to it, you can add them to the post-up.sh script and then run /etc/iptables/post-down.sh && /etc/iptables/post-up.sh. Simple and no more reboots required.