dst-NAT works with 1.1.1.1 and not with local DNS

I have a local DNS filter on IP 10.10.10.1 and I tried using this config to forward traffic to it but it just won’t work.
Why does this work :

add action=dst-nat chain=dstnat dst-port=53 log=yes log-prefix=Filter17 protocol=udp src-address=192.168.0.150 to-addresses=1.1.1.1 to-ports=53
add action=dst-nat chain=dstnat dst-port=53 log=yes log-prefix=Filter6 protocol=tcp src-address=192.168.0.150 to-addresses=1.1.1.1 to-ports=53

But this won’t work:

add action=dst-nat chain=dstnat dst-port=53 log=yes log-prefix=Filter17 protocol=udp src-address=192.168.0.150 to-addresses=10.10.10.1 to-ports=53
add action=dst-nat chain=dstnat dst-port=53 log=yes log-prefix=Filter6 protocol=tcp src-address=192.168.0.150 to-addresses=10.10.10.1 to-ports=53

What is the difference in the rules you posted? I fail to see it.

Anyway, it’s worth to mention that firewall and NAT rules are processed in order from top to bottom. If you have a specific rule (such as in your example) but pushed quite to the bottom of rules and at the same time you have some more general rule which triggers on same packets and is higher on the list, then your specific rule won’t get executed.

one was to DNS server 1.1.1.1 and another to Local DNS server 10.10.10.1 but it got fixed with hairpin

Generally hairpin-NAT is only needed if client is in the same subnet as server which is redirect target. If hairpin-NAT solves your problem, then your setup is “out of a box” and needs special consideration. Or there’s some other configuration which interferes.

Actually, My only problem after Hairpin NAT is that it’s Masquerading the source IP to the local IP 10.10.10.1 and I’m trying to understand what to do before surrendering

Look here how to solve this by using action=netmap instead of action=masquerade.

I tried this and it doesn’t seem to work I’ll have to dig deep.
My conclusion is if I used the Hairpin NAT the traffic inside the lan will be masqueraded but if I remove MSQ Hairpin the Dns gets the source IP but doesn’t know where to reply. Is my understanding correct? And in this case what can I do or just accept it as it is?

OK, so let me explain what @mkx wrote in his second post in deeper detail.

A “hairpin NAT” normally means literally that the connection from host A in subnet X to host B in the same subnet X goes through the router because host A sends the connection request to some address outside subnet X, and the router dst-nats that to the address of host B in subnet X. In order that this worked, the dst-nat is not sufficient, because it doesn’t change the source address of the request, so the host B can see that the request came from host A, and sends the response directly to host A rather than sending it to the router, because host A is in its own subnet. So host A ignores the response because it came from a different address than where it has sent the request. Hence you have to add a src-nat rule at the router, so that host B would get the request from some address outside its own subnet, and would thus have to send the response to the router rather than directly to host A.

In your case, host A (the DNS client) and host B (the DNS filter) are not in the same subnet, hence you should not need the hairpin NAT if the DNS filter uses the Mikrotik as its gateway towards 192.168.0.150. But if the DNS filter doesn’t use the Mikrotik as a gateway to 192.168.0.150 because (one of):

  • it has an address from 192.168.0.0/x on one of its other interfaces,
  • it has no route to 192.168.0.0/x at all.
  • it has no route anywhere except the one to 10.10.10.x, which is created automatically as you assign an address from that subnet,
  • there is some other router than Mikrotik in your network, and the DNS filter uses that other router as a gateway to 192.168.0.0/x,

you need to srcnat the DNS request from 192.168.0.150 to 10.10.10.1 so that the response would get to the Mikrotik (which then un-src-nats and un-dst-nats it and delivers it to 192.168.0.150).

In the “normal” case, where both host A and host B are in the same subnet, the new source address of the request (A’) need not be Mikrotik’s own one; the only requirement on that address is that host B would use the same router through which it has received the request as a gateway for packets to A’.

So depending on the actual reason why the masquerade rule is currently necessary to make the response from the 10.10.10.1 machine reach 192.168.0.150, you may not need the masquerade rule at all if you can fix a misconfiguration, or you may need a netmap rule with a “correct” to-addresses prefix in the srcnat chain if that configuration is intentional and cannot be “fixed”.

I really appreciate the long explanation, it’s really worth it and much appreciated.
So I understood my misconception about returning the request from Host B(Dns filter) to Host A it just doesn’t understand that it’s returning the same request it sent to the router.
Second please correct me if I’m wrong, I think I think I understand my misconfiguration after reading the post since what I did is I gave the DNS filter an IP 10.10.10.1 and gateway 10.10. 10.253 (a different mikrotik router) rather than my main one and the other mistake is that in order to make the router and the Dns reach each other I simply assigned an IP address of 10.10.10.254 in the address menu which created the default route to it on the LAN ethernet port so, my mistake is that I didn’t change the subnet of the DNS filter and that’s why it needed the Hairpin NAT for 10.10.10.1/24 since to the mikrotik it’s the same as using the default subnet 192.168.0.0/24 it’s a Local subnet with just different numbers. Also to my stupidity I assigned an extra IP to the Dns filter of 192.168.0.33 so I could access it from the default subnet and that’s just unnecessary.
So to answer your list directly:

  • it has an address from 192.168.0.0/x on one of its other interfaces (that’s true it has an extra ip 192.168.0.33)
  • it has no route to 192.168.0.0/x at all.( it has the default route after adding a standard Ip address on the same ethernet port)
  • it has no route anywhere except the one to 10.10.10.x, which is created automatically as you assign an address from that subnet ( this is 100% correct)
  • there is some other router than Mikrotik in your network, and the DNS filter uses that other router as a gateway to 192.168.0.0/x ( this is unapplicable)

So in order to resolve this how should I correct my configuration inorder to leave the Hairpin NAT for 10.10.10.0/24?

It depends on what is the overall topology and what you can afford to change.

On the DNS filter, you can remove the 192.168.0.33, and add a route to 192.168.0.0/24 via the address of this Mikrotik in 10.10.10.0/24 (10.10.10.254 if I get you right).

If you cannot remove the 192.168.0.33, you’ll have to set up policy routing at the DNS filter, making sure that connections coming to 10.10.10.1 will be responded using 10.10.10.254 even though their source address is in 192.168.0.0/24 - doing so requires connection marking and route marking.

Just add DoH on your client and bypass all DNS on the way :slight_smile:
Example
https://play.google.com/store/apps/details?id=com.frostnerd.smokescreen

Finally, I got it to work I simply removed my extra local IP, then routed the pc through MikroTik’s 10.10.10.254. and it worked like a charm all source IPs are visible this time. Thanks all.