Imagine running a local web server at 192.168.1.10:80 at your LAN. To expose this service to the internet, you create a DNAT rule to map your router’s public address 1.2.3.4:80 to 192.168.1.10:80.
When a client in the same LAN at 192.168.1.20 tries to access the service, without hairpin NAT:
- Client sends a packet with src=
192.168.1.20, dst=1.2.3.4:80 - The router receives the packet
- Router’s DNAT rule maps dst to
192.168.1.10:80 - Web server at
192.168.1.10:80receives the packet, and sends a response back to the client at192.168.1.20 - Client at
192.168.1.20receives the packet directly, but it is expecting a response from1.2.3.4:80, which breaks the connection
With hairpin NAT (SNAT + DNAT):
- Client sends a packet with src=
192.168.1.20, dst=1.2.3.4:80 - The router receives the packet
- Router’s DNAT rule maps dst to
192.168.1.10:80 - Router’s SNAT rule maps src to router’s LAN IP, e.g.,
192.168.1.1 - Web server at
192.168.1.10:80receives the packet, and sends a response back to the router at192.168.1.1 - Router untranslates (with conntrack), forwards reply back to
192.168.1.20 - Client sees reply from
1.2.3.4- connection works