Community discussions

MikroTik App
User avatar
Forum Guru
Forum Guru
Topic Author
Posts: 8775
Joined: Sun Feb 18, 2018 11:28 pm
Location: Nova Scotia, Canada

Hairpin NAT The Right way?

Tue Oct 12, 2021 1:37 am

There is no right way! It depends..............
Every person will have to decide what is the optimal way to configure their device(s) for hairpin NAT (sometimes called Loopback).

Hairpin NAT is a funny situation of what is normally considered a dst-nat problem/variation and mostly for the case of port forwarding, where the requirements (use cases) describe a server on a local subnet and the local users on that subnet, as follows:
a. The server and the LAN users of the server are on the same subnet
b. The server admin requires that access to the server is provided via its domain name (external WAN IP).
i. This could be for several reasons but for example when one has multiple vlans and a standard method for access is provided that works for all users, regardless of vlan associated forward
chain firewall rules.
ii. The admin for other reasons does not want users to use the LANIP address of the servers.
iii. {Leave blank for other reasons.}

There are two quick work-arounds to avoid the necessity to deal with Hairpin NAT and they include:
a. Move the LAN users or Server to a different subnet, done!
b. Allow the LAN users to use the LAN IP of the server for access, done!

If the two work-around options are not to your liking then we have to adjust the config of the Mikrotik appliance and there are two main approaches, one touching upon DNS changes and the other involves NAT rules and specifically one necessary src-nat rule and potentially various manipulations of dst-nat rules

Server IP is, protocol tcp, port 12566,
WANIP= (for static examples), domain

LAN user IP is


(1) DNS METHOD – REDIRECT LAN REQUEST VIA DNS (courtesy of rextended & ZeroByte)

Create the following rule!
/ip dns static
add address= regexp="(^|www\\.)myserver\\.net\$" ttl=5m

The precedence for using DNS within the router is as follows...........
a. static first,
b. static regexp next, and
c. others...

This rule tells the router that for any DNS traffic that is generated to look for the domain name location, there is no need to go to dynamic servers, cached servers, external internet internet servers etc., go directly to the location of the LAN IP indicated (our Server). To ensure even PCs with hard coded DNS server entries are forced to the server location, one needs to redirect all DNS queries to the router, which will then follow the static rule.

add action=redirect chain=dstnat comment="Force Users to Router for DNS - TCP" \
dst-port=53 protocol=tcp src-address=
add action=redirect chain=dstnat comment="Force Users to Router for DNS - UDP" \
dst-port=53 protocol=udp src-address=

Two Points and One Reminder:
(i) You'd need to make sure "allow remote request" is turned on in /IP DNS,
(ii) Ensure there are no static entries in DNS as they take precedence, and
(iii) Confirm you are using default firewall rules and specifically on the input chain, the drop all from the WAN rule:
add action=drop chain=input comment="defconf: drop all not coming from LAN" \

OR the common replacement, as the last rule in the input chain:
add action=drop chain=input comment="drop all else"

Not really a concern with a decent firewall but in general we want to ensure that DNS requests from the internet are blocked to avoid dns-amp ddos attack etc...


(2) SOURCE-NAT Based Addition (May be all you need!)

In all cases (dynamic or static WAN IPs) the first step that is consistent across all variations is the addition of a source-nat rule addition placed before the default SRC-NAT rule.
add chain=srcnat action=masquerade dst-address= src-address=

To understand what effect the ‘extra source nat rule has’ review this link, which clearly describes what happens to packets from an external user and the explains what happens when the same is attempted (also via the WAN IP) from a local user: ... airpin_nat

To be more precise, in the article one could make the extra source-nat rule:
add chain=srcnat src-address= dst-address= protocol=tcp dst-port=12566 out-interface=LAN action=masquerade
However the more encompassing rule would cover a number of servers and a number of users.

(3) STATIC/FIXED WAN IP configurations, [/b]

For static/fixed WAN IPs, the extra generic SRC-NAT rule is all that is required to change. No modifications are required for existing correctly formatted DST-NAT RULES (format as follows):
add chain=dstnat action=dst-nat dst-address= dst-port=12566 \
protocol= tcp to-addresses=
{to-ports only required for port translation}


Dynamic WAN IP configurations boil down to replacing or mimicking the dst-address=WAN IP with something similar.

(4) DYNAMIC WAN IP Local Address approach

This method is fairly straight forward in that you config the router to use a local address as the destination address, and then deny the local subnet address to the router as an option. Effectively the router will choose the next available local address and it should be the current WAN IP.
add chain=dstnat action=dst-nat dst-address-type=local dst-address=! \
protocol=tcp dst-port=12566 to-addresses=

Limitations: This rule ONLY suffices for a single subnet structure behind the Router. As soon as you add more subnets/vlans the rule gets more complex and one would then have to use a firewall address list to identify all subnets on the network that should not be considered as a local subnet to force the router to choose the only remaining available local address,which then would be the WAN interface.
Add chain=dstnat action=dst-nat dst-address-type=local dst-address-list=!allsubnets \
protocol=tcp dst-port=12566 to-addresses=
Add ip=subnetofserver list=allsubnets
Add ip=othersubnetA list=allsubnets
Add ip=othersubnetB list=allsubnets

(5) DYNAMIC WAN IP - Firewall Address List and IP Cloud (kudos to Steveocee)

This method relies upon using ones IP Cloud IP address as a firewall address list entry to replace the actual dst-address of the router. The IP Cloud function periodically updates the WAN IP every few minutes. Thus, instead of using dst-address=WAN IP one uses dst-address-list=updatedCloudIP
add chain=dstnat action=dst-nat dst-address-list=updatedCloudIP address protocol=tcp dst-port=12566 to-addresses=

See for an excellent presentation.

Limitations: There is a chance of a gap in correct coverage if the WANIP is changed or whatever reason in between IP Cloud updates.
(i) Best when there is 1:1 NAT; OR
(ii) if the router itself doesn’t have a public IP address as the IP Cloud service will provide the correct public IP in front of your router.

(6) DYNAMIC WAN IP - Firewall Address List and IP DHCP Client related script (most elegant and courtesy of Sob (sos??))

This method utilizes a script that pulls the actual WAN IP from your IP DHCP Client settings. The script allows the admin to set any schedule desired vice the fixed IP cloud updates.
DHCP lease script:
:if ($bound=1) do={
/ip firewall address-list set [/ip firewall address-list find where comment="wan1ip"] address=$"lease-address" disabled=no
} else={
/ip firewall address-list set [/ip firewall address-list find where comment="wan1ip"] disabled=yes
/ip firewall address-list
add comment=wan1ip disabled=yes list=external_wan

Limitations: Not suited for a private WANIP setup.


That concludes hopefully a more full discussion of the reasons for Hairpin NAT and the options available to tackle this issue.
Any suggestions comments additions welcome.
I'd rather manage rats than software. Follow my advice at your own risk! (Sob & mkx forced me to write that!)
MTUNA Certified, by the Ascerbic Llama!

Who is online

Users browsing this forum: floydthebarber and 2 guests