Hairpin NAT with dynamic WAN IP?

Is this possible at all?

Sure. Did you read how to setup hairpin nat?

http://wiki.mikrotik.com/wiki/Hairpin_NAT

Yes. From that article:

/ip firewall nat
add chain=dstnat dst-address=1.1.1.1 protocol=tcp dst-port=80 \
  action=dst-nat to-address=192.168.1.2
add chain=srcnat out-interface=WAN action=masquerade

The public IP address that is getting the port forward is dynamic. So I can setup a rule but as soon as the “wonderful” ISP decides to renew the DHCP lease, the IP changes and the rules invalid.

Are you wanting to setup hairpin NAT or DSTNAT? What are you trying to achieve?

Hairpin NAT is a combination of DSTNAT and SRCNAT correct?

I want hairpin nat on port 3389. public interface is ether1. the lan subnet is on ether2. the public interface pulls dhcp from the isp.

huh?

I have DST-NAT setup and working for specific ports. It comes in and does a DST-NAT when on port 3389 using TCP. That works great from the outside. I have this router registering a DDNS account so I can access it.

Now, when my laptop/tablet is brought inside the network and tries to hit the same DDNS/IP, the hairpin NAT doesn’t work. When the hairpin NAT is needed, the rule doesn’t get executed and I’m assuming it is because the DST-NAT rule isn’t setup per IP address… it is setup per the in-interface.

What IP address does port 3389 go to and what is your LAN subnet?

subnet on ether2-lan → 192.168.77.0/24
to-address for 3389 → 192.168.77.20

You need to do something like this.

add action=masquerade chain=srcnat dst-address=192.168.77.20 src-address=192.168.77.0/24

I will try that this evening. Thanks for your help

@rotten777

Have you managed to sort your problem out?

I also need to implement a hairpin NAT but have a dynamic public IP address. :frowning:

When you use hairpin NAT you use your private IPs.

dst-address being the WAN IP, src-address being a local NAT’d IP…

No

Ok sorry to be a thread necromancer, but I want to make sure I understand what is happening here -

add action=masquerade chain=srcnat dst-address=192.168.77.20 src-address=192.168.77.0/24

This rule is basically taking all traffic that is directed at 192.168.77.20 and is coming from 77.0/24 and applying the masquerade action to it, correct? So the router treats the traffic as if it were coming from the outside world and applies the already established forwarding rules to it (ie, forward 80 and/or 443 to said IP)?

Do I have this right? Sorry again to revive an old thread, but I figured it would be better than starting a fresh one. Just seems like a really simple and elegant solution, I wonder if I am missing something or if it could introduce any security issues (passing traffic outside when not needed). Thanks!

Actually in this case router pretends to be the initiator of the connection not that it comes from the outer space.

No, as Jarda has pointed out, this rule obscures the SOURCE address from the server. (p.s. “Thread Necromancer” made me laugh)

The thing that makes hairpin nat a special case is that you have to NAT the dst address/ports to the internal address AND you must nat the source address to something that will cause the internal host to direct its replies to the router.
There is nothing special about the dstnat portion in a hairpin situation - the same DSTNAT pinhole rule works for normal incoming connections AND the hairpin case, so no additional rules are required for this part.
The SRCNAT portion is required, but you only want to do it when the SRC is on the same network as the internal host’s IP range. It’s easy to just use the MASQUERADE action.

If you don’t do the srcnat, here’s why hairpin breaks:
Internal host 192.168.77.19 sends a TCP:80 socket request to public IP a.b.c.d - the source IP of this request is 192.168.77.19
The router will dutifully map this packet’s destination to the inside address and port (e.g. 192.168.77.80:80)

If the router does not masquerade the source to something “remote” from the internal server, the server will see the source as being 192.168.77.19 - which is a local destination, so the internal host will send its reply directly to the other host (not via the router). The problem is that the internal host doesn’t know it’s behind NAT, so the reply packet’s destination will be 192.168.77.19 and the reply’s source will be 192.168.77.80 – when this packet arrives at the original host, the host won’t recognize it as a reply because it’s expecting the reply to come from a.b.c.d:80 – so it will discard the reply.

With the hairpin rule, the inside web server will see the request as having come from the router, so it will send the reply to the router. The router will then continue the lies it’s been telling everone, and send the reply packet to the actual host requesting the connection (dst=192.168.77.19) and put the address A.B.C.D:80 as the source.

Ohhhhhh ok. I think I get it now. And since as far as the server that is getting the forwards is concerned all external traffic appears to come from the router anyway, this just makes it work correctly when ports are being forwarded. So we really don’t need to try and apply the src-nat by port at all, (in fact, now that I think about it, wouldn’t that break it?). Let me give it a shot. Thanks again for all the awesome help.

No problem.

And FYI - you don’t need the SRCNAT rule to apply for traffic coming in from the Internet because the replies must go to the router anyway.
In fact, you probably don’t want the SRCNAT for inbound-from-internet connections, so that way your logs show the real remote IP address.
That’s why the hairpin rule has src-address=192.168.77.0/24 as a clause - so it ONLY applies to hairpin traffic.