Why (not) use Hairpin NAT

There are few more differences…

Why hairpin NAT is the best thing in the world (only slightly biased comparison with local DNS override :smiley:)

Initial config:

  • common: nothing
  • dns: nothing
  • hairpin: add one srcnat rule

Ooops, hairpin is losing right from the start. Well…

Put company webserver behind router (www.company.tld and company.tld):

  • common: add one dstnat rule to forward ports 80 and 443 to internal server; in public dns, point two hostnames to router’s public address
  • dns: add two hostnames in local dns
  • haipin: nothing to do, everything works

Add another virtual host (eshop.company.tld):

  • common: in public dns, point one hostname to router’s public address
  • dns: add one hostname in local dns (it won’t work for local users until you do)
  • haipin: nothing to do, everything works

Move eshop to different external server:

  • common: in public dns, point eshop hostname to different public address
  • dns: remove eshop hostname from local dns (if you don’t, local users will keep connecting to local server, which either doesn’t run the virtual host anymore or in worse case it has stale version, so it seemingly works, but has old data, e.g. new orders don’t show up)
  • haipin: nothing to do, everything works

Move virtual hosts to different internal server:

  • common: change to-addresses in dstnat rule
  • dns: in local dns, change all hostnames to new address
  • haipin: nothing to do, everything works

Mail server (behind same router) uses common mail.company.tld for everything (smtp, imap, …). For some reason, you need to split the server in two, with smtp port going to one and others to another. You’d like to keep mail.company.tld, because too many people have it configured in all their devices:

  • common: split dstnat rule for port 25 from the rest and set its to-addresses to another server
  • dns: “Houston, we have a problem…”
  • haipin: nothing to do, everything works

Someone scares CEO with DNS-hijacking and recommends to run DNSSEC validating resolver on his own notebook; CEO believes that it’s the only way and refuses to consider any other solution:

  • common: nothing
  • dns: “oh no, not again…”
  • haipin: nothing to do, everything works

CEO has bookmarked company FTP server, which is behind same router, the bookmark is for public numeric address (no hostname) and he insists that it must work even from same LAN (and encryption is required, so there’s no chance for any conntrack magic):

  • common: add one dstnat rule to forward control and passive data ports to internal server
  • dns: “that’s it, I quit!”
  • haipin: nothing to do, everything works

Ok, I know I’m stretching it, but it’s all true.

One reason not to use hairpin NAT that I haven’t seen anyone mention here, is that you lose some of your ability to log what people on the LAN are doing to your servers. Not so much a difference is how difficult it is to setup, but keep in mind that some other things are lost when you just source NAT everything with a hairpin NAT rule.

For example in hairpin NAT’ed network, all connections from your LAN that access the company’s FTP server’s external IP-address will look like they are coming from the router rather than from the internal computers. Only way to track this is to log it on the NAT’ing router, which might have more than enough things being logged already.

Another issue I have with hairpin NAT’ing is when you have many different LANs. Either you have to make a very wide hairpin NAT rule, or keep adding a new hairpin NAT rule every time a new LAN is created. This is further complicated if your servers are also not all on one dedicated server LAN/DMZ, having to again make a wide hairpin NAT rule that covers all of them or keep adding new hairpin NAT rules as servers get setup on new LANs/DMZs. Mix those two and you need a lot of hairpin NAT rules or one very wide hairpin NAT rule that covers everything from your whole network to your whole network.

I agree that making internal DNS is a good idea for some things, but it all depends on how complex your network is. But you might also have some issues with troubleshooting when you use internal DNS, since you aren’t technically pinging the same device as external people.
Not that I normally hear anyone suggesting that ICMP should be destination NAT’ed to the servers you are port-forwarding to. So in most causes you are just pinging the router and not the actual server when you ping a domain name. But at least you would be pinging the same device as the external people.

I have yet to actually work with IPv6, but the idea of not having NAT at all and just use simple stateful firewalls seems like a very nice and clean solution.

If you have publicly accessible service and thousand remote computers connect to it, it’s possible that you will see just one source address, if they happen to be behind same remote NAT. If you can live with this, why you should be bothered when accesses from your LAN will be hidden behind one common address too?

Personally I don’t like to see router’s internal address as source, because that really looks confusing. But it doesn’t have to be that, you can use action=src-nat instead of usual masquerade and set any address you like. I usually use router’s public address, that looks right to me. Or you can use any random address you like and it will work too.

If you really can’t live without telling one internal client from another, you can netmap real source addresses to some virtual subnet. But I still don’t understand why. Hairpin NAT is a hack, it’s convenient way to let internal clients use public entrance. It’s less efficient, because traffic has to unnecesarily travel to router and back. But it’s great, because things will still work instead of breaking up completely. If not being able to tell one internal client from another is problem for you, I’d say you’re trying to see hairping NAT as something more than it actually is.

Many rules for large LANs with many subnets, well, that may be unfortunate, but that’s to be expected that configuration for large network will be more complex than for small one.

Btw, one fresh point for hairpin NAT: When browsers enable DNS over HTTPS, everything will still work great and admin won’t have to move the finger. Internal DNS overrides on the other hand, …

Nope.
Simply use address lists. 1 rule for hairpin and then add range to address list when needed.

That will unnecessarily apply srcnat also to connections between different subnets where it could work without it.

And one more point for hairpin NAT (edit: actually, this is not exactly hairpin NAT itself, because srcnat would not be required; but it’s related):

Let’s say you do have larger LAN with multiple subnets and different access rules. For example four different LANs for servers, admins, employees and guests. Admins can access everything, others only internet and nothing else, i.e. there’s no direct access to servers from employees or guests. Your website is on server in server’s LAN and it should be accessible to anyone. If you use DNS override, you have to add new firewall filter rule(s) for that, to allow access from employees and guests LANs to given server, and it’s another thing you need to keep in sync. With hairpin NAT, you again don’t need to do anything (it’s starting to get boring :wink:), because everything will be allowed automatically with probably already existing:

/ip firewall filter
add action=accept chain=forward connection-nat-state=dstnat

Personally i use Hair pin nat in the following cases (just an example)
I have a dns name which with the help of a script i update it with my public IP address and at the same time there is a static dns entry in my router with the same Dns name which points to my rourers IP…

This way i can access from a public place any device i wish in my Lan with the appropriate port forward…And at the same time when i am inside my Lan i can still do the same…

for example i can see my Dvr cameras from outside and inside the lan by using the exact same Dns name with no changes at all… so when i am outside the lan it resolves to my public IP, but when i am inside the Lan it resolves to the routers IP and with the help of hair pin nat, (masquerade and dst nat) i can access my Dvr…

And what is the role of hairpin nat in this scheme? Why can’t you just point the inside DNS directly to the resource?!

And what is the role of hairpin nat in this scheme? Why can’t you just point the inside DNS directly to the resource?!

Because i dont want my Dns to point on a specific device..so simple…

Ok, I get it.
Some people in this thread are from ip:port + hairpin nat camp.
Others from dns + reverse proxy camp.
You are somewhere in the middle :laughing: