Hairpin NAT - the easy way

When this filter is done for work, not to censor or otherwise, on workstations, I don’t think employees can do it to sabotage their work by themselves…
don’t you think?

It’s not about anyone trying to sabotage or get around anything. It’s mainly the Just Works™ factor, hairpin NAT is foolproof and maintenance-free. You add one srcnat rule (or more, one per subnet), you do it once, and you don’t need to touch it or even think about it ever again. No matter how many services you have, how many you add or remove, there’s no extra work required, you just add or remove dstnat rules (which you need to do for external access anyway). You don’t need to worry about what DNS resolver users use. It always works.

Please, how do you solve the problem of having MORE-THEN-ONE internal servers, on different internal IPs?
For example, one web server 192.168.88.100 listening on port 443 and one mail server 192.168.88.101 on port 25. From the outside they are both reachable on the same DomainName “www.mydomain.it” , and with 2 different dst-nat rules you can reach both
.

Seems perfectly reasonable its the same public IP being reached and the distinguishing factor for access is the port/protocol.
Access from the exterior works just fine.
Access from the interior will depend on
a. the proper confi of your firewall rule for port fowarded traffic…
b. the makeup of your destination nat rule ( is it formulated for the type of WAN connections you have (static vs dynamic).
c. srcnat rule for hairpin nat added to the config.

Remember hairpin nat is only needed if the users and server(s) are in the same subnet. One can always consider moving the servers to a different subnet.

@anav: Not the point. That post quoted @rextended’s post about internal DNS, as a way to avoid NAT completely, so it’s safe to assume that it was about that. And the answer is that it can’t be done, because if you point the common hostname to some internal server, it will always be either one or the other, but not both (well, it can be both, but then it will be unusable hit and miss).

Ahh yes, I missed that nuance. Not to worry, DNS is pain in de ass and should be avoided monkeying with at all costs LOL.

Man i love you!!! hairpin nat with lte hi link through usb worked with your way

Apologies for reviving an old thread.


@anav, could you kindly explain why it will make a difference, please?

Is it because in the same LAN scenario, the packet back would be destined directly to the client MAC address as the server has it in its ARP table, and the router would simply switch it back to the client without any processing,

while in the separate LAN scenario, the server would set the MAC address of the router in the reverse packet as ARP table does not span to directly unreachable LANs, the router would route (not switch) the packet, and the dst-nat would be reversed?

Or am I overcomplicating it/missing anything?

Is it because in the same LAN scenario, the packet back would be destined directly to the client MAC address as the server has it in its ARP table, and the router would simply switch it back to the client without any processing,

Something like that… the router knows where the originator is and attempts to send it back directly and the originator rejects the traffic as it appears to be traffic not requested ( source IP does not match the original dst IP).

http://gregsowell.com/?p=4242

Thanks, that makes sense.

But why would it work without the additional srcnat rule if we put the server in a separate subnet?


off the top of my head, the issue is no longer a Layer2 problem, as a different subnet provides no connectivity at layer 2.

I did try the topic approach and the official one but none did really work…
The topic approach I do see the mangle packets get increased but zero in the nat; I’m suspecting if fasttrack is somehow influencing it.
Is there other good approaches?

I have a hAP ac² running at version 7.19.1

Try it this way, you need three rules:
/ip firewall nat
chain=srcnat action=masquerade connection-mark=Hairpin NAT log=no log-prefix=“”

/ip firewall nat
chain=dstnat action=dst-nat to-addresses=192.168.1.113 to-ports=8000 protocol=tcp dst-address=12.34.56.78(PublicIP) dst-port=8000 log=no log-prefix=“”

/ip firewall mangle
chain=prerouting action=mark-connection new-connection-mark=Hairpin NAT passthrough=yes src-address=192.168.1.0/24 dst-address=12.34.56.67(Public IP) log=no log-prefix=“”

And you only add firewall NAT (second line) rules, for another devices.

Thanks for the help Urajmal.

The first and third rules are basic the main post and the second one is a dst-nat, I did try set the dst-address to the public IP as mentioned but still didn’t work.
The mangle counter is increasing but the nat one is still zero; the dst-nat works but only for devices outside the lan.

check your routing if you have a valid symmetric route to the target host on that LAN segment where the target host and it should work

I’m kind network enthusiastic/newbie, how do I check for the symmetric route? All my ip-routes are dynamic.
External devices can access the lan host by public IP (port forwarding using dst-nat).

Please use this guide from normis and compare to what you are doing, https://www.youtube.com/watch?v=1I5FywY6opQ this will surely help you another approach is you can use split horizon DNS to fix your issue.

Thanks for the reply; in the video I did notice that in the dst-nat the “in. interface” is empty, only the “dst. address” is used; well that makes sense for hairpin.
The problem was the host was using upnp to auto add the dst-nat rules, but the upnp rules forces the “in. interface”; disabling it and adding dst-nat manually did the trick and now hairpin works :slight_smile:

In resume the Hairpin works good but not with UPNP.