I have one host running Proxmox VE.

I set up 3 virtual bridges vmbr[0-2] to handle my networking needs: vmbr0 runs directly on the main interface for VMs with public IPs, vmbr1 allows for NATed VMs, and vmbr2 is a host-only network. Let's say my main public IP is

For the NAT to work, I set up the following iptables ruleset:

-A PREROUTING -d -i vmbr0 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination
# and other rules like this one for different ports to different local IPs

-A POSTROUTING -s -o vmbr0 -j SNAT --to-source

Now let's say I have a VM on vmbr1 with IP

This machine cannot access the webserver at using the public IP

I initially thought that the POSTROUTING directive above was enough for hairpin NAT to work.

Having read the canonical Loopback to forwarded Public IP address from local network - Hairpin NAT and multiple other answers on the same variant, I tried :

  • setting -P [INPUT|FORWARD|OUTPUT] ACCEPT temporarily on the host to check if it could be caused by some filtering rules

  • adding -A POSTROUTING -d -p tcp --dport 80 -j MASQUERADE to the ruleset, trying it both before and after the current POSTROUTING rule

but still, it does not work.



  • If you have an internal DNS server you can also create a zone for the internal webserver so that local clients resolve the host name to the private IP instead of the public IP so you don't need to use a hairpin NAT rule. – user5870571 Feb 15 '16 at 13:57
  • I know of this solution, but I would highly prefer the NAT one, which is supposed to work I think... – rapht Feb 15 '16 at 14:40
  • Not a duplicate actually, problem solved see below : specifying the interface is key and not a subject covered in the referenced document. – rapht Feb 15 '16 at 16:15

To do the hairpin NAT method you will need to enter the commands below.

iptables -t nat -A PREROUTING -d -i vmbr1 -p tcp -m multiport --dports 80,443 -j DNAT \
iptables -t nat -A POSTROUTING -s -o vmbr1 -d -p tcp \
    --dport 80 -j SNAT --to-source
  • I just found what was wrong, which is not solved by your proposal: I need to remove -i vmbr0 from the PREROUTING directive and it all works like a charm. In retrospect I should have seen it : with -i vmbr0 the PREROUTING does not apply to packets coming from vmbr1 which is where the NATed VMs are located. – rapht Feb 15 '16 at 14:53
  • 1
    I assumed you specified the interface you intended. I updated it. Give that a try. :) – user5870571 Feb 15 '16 at 14:59

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.