Learned something new today: hairpin nat (with iptables on linux)


So I was trying to set up a service that should be accessible from the internet and locally (under the same Domain name and in a different subnet as the internal hosts for security reasons).

the variables are self explainatory I think (IP Addresses and interface name)

$IPTABLES -t nat -A PREROUTING -p tcp -d ${EXTIP} --dport 80 -j DNAT --to ${WEB}
$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 80 -i ${IFACE_WAN} -j ACCEPT

Trying to just use my usual DNAT rules did work from outside, but not from the inside.. luckily I found help in #Netfilter on irc.freenode.net ..  duclicsic pointed out to me that i needed SNAT or MASQUERADE too so the router rewrites the local packets too. And also told me that this whole thing was called Hairpin NAT. Thanks to that I now have my iptables rules in place:

$IPTABLES -t nat -A POSTROUTING -s ${INTERNALNET} -d ${WEB} -p tcp --dport 80 -j MASQUERADE

INTERNALNET is just the internal network in CIDR notation.

He also pointed out to me that a package forwared this way would not hit the INPUT chain, but FORWARD instead on the host (since the LAN interface on my router does not block port 80 i did not have an issue with this).

Currently unrated


There are currently no comments

New Comment


required (not published)