Hairpin NAT - Working but not as expected

Hi all,

I have a routerboard

aug/09/2020 16:13:35 by RouterOS 6.47.1

with the following firewall setup which gives me some NAT from a public IP:

/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none out-interface-list=WAN
add action=masquerade chain=srcnat dst-address=192.168.88.254 dst-port=53 out-interface=admin protocol=tcp src-address=192.168.0.0/16
add action=masquerade chain=srcnat dst-address=192.168.88.254 dst-port=53 out-interface=admin protocol=udp src-address=192.168.0.0/16
add action=dst-nat chain=dstnat dst-address=XX.XX.81.96 dst-port=53 protocol=tcp to-addresses=192.168.88.254 to-ports=53
add action=dst-nat chain=dstnat dst-address=XX.XX.81.96 dst-address-type=local dst-port=53 protocol=udp to-addresses=192.168.88.254 to-ports=53

When I hit my DNS server with a request, I see my routers ip address, not the public ip. So the hair pin is providing some hair and not so much pin :slight_smile: I would expect to see the public address the request was initially made to.


09-Aug-2020 16:07:25.486 update: info: client @0x7f529c00a550 192.168.88.1#47462/key external-rndc-key: view externals-master: updating zone 'dev.node.example.com/IN': deleting rrset at 'test.dev.node.example.com' A
09-Aug-2020 16:07:25.486 update: info: client @0x7f529c00a550 192.168.88.1#47462/key external-rndc-key: view externals-master: updating zone 'dev.node.example.com/IN': adding an RR at 'test.dev.node.example.com' A 192.168.88.10
09-Aug-2020 16:07:25.490 update-security: info: client @0x7f529c00a550 192.168.88.1#47462/key external-rndc-key: view externals-master: update '168.192.IN-ADDR.ARPA/IN' denied

The public ip is dynamically assigned to ether 1 and my bridges are as follows:


/ip address
add address=192.168.88.1/16 comment=defconf interface=admin network=192.168.0.0
add address=192.168.254.1/16 interface=cluster network=192.168.0.0

The request Im making to my dns server is an nsupdate targetted at the public ip XX.XX.81.96 but I see the same with a web server (Ive removed the export options for those NAT rules).

Any help would be appreciated.

Cheers,
Tom

why are you trying to hairpin DNS?
i dont see the logic if you are asking the user to use your dns to resolve IPs but first they have to your external IP to resolve them… very confusing.
Probably due to my lack of dns knowledge.

We are running a cluster and need to resolve some cluster addresses externally, the DNS server is split into views so we can get internal or an external address so we can access a service the cluster publishes via DNS from the internet. This is for the development side of it so if we run some nodes locally we need to be able to publish those local services, which would all be natted. Its a PITA but theres no way round it.

Just use action=src-nat to-addresses= instead of action=masquerade.

Perfect! That’s precisely what was needed, thank you so much for your help!

For anyone else needing the example…this should give you a public ip address for internal connections which use your XX.XX.81.96 public ip as the destination and when you connect internally you get the internal address.


/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none out-interface-list=WAN
add action=src-nat chain=srcnat dst-address=192.168.88.254 dst-port=53 ipsec-policy=out,none protocol=udp src-address=192.168.0.0/16 to-addresses=XX.XX.81.96
add action=src-nat chain=srcnat dst-address=192.168.88.254 dst-port=53 ipsec-policy=out,none protocol=tcp src-address=192.168.0.0/16 to-addresses=XX.XX.81.96
add action=dst-nat chain=dstnat dst-address=XX.XX.81.96 dst-port=53 protocol=tcp to-addresses=192.168.88.254 to-ports=53
add action=dst-nat chain=dstnat dst-address=XX.XX.81.96 dst-port=53 protocol=udp to-addresses=192.168.88.254 to-ports=53

I do have one question however, the ipsec-policy=out, is this required? Its set on the default rule which I copied. I will add that if a user was to VPN into our network, run some services and have those services available over VPN they might be connecting to (in this case) the DNS server.

Cheers,
Tom

The point of that rule is to exclude connections which use bare IPsec from getting src-nated (or masqueraded in this case, but the difference between the two is not relevant for this purpose). The thing is that packets are chosen transport via bare IPsec after all the steps of routing and firewall handling have been made, so if the route chosen for those packets by the normal routing is the one via WAN, the packets would get src-nated and thus the IPsec policy would miss them. The ipsec-policy=out,ipsec matches on packets that match any of the existing IPsec policies. So the initial packet of each connection actually gets matched to the policy list twice - once by this rule and another time when it is about to be sent out the physical interface. Mid-connection packets do not pass through the srcnat and dstnat chains at all, their NAT handling is determined by the first packet of the same connection.