DNS hijacking in bridge mode

Hi,

I have my 'LAN' on 10.11.12.0/24 and my 'firewall zone' or 'Wan' on 10.11.13.0/24. I have an OpenWrt One in bridge mode between the two. I have two internal DNS server 10.11.12.24 and 10.11.12.35 which forward to OpenDNS servers and I have a forward rule to allow that which works fine.

I find I have a couple of devices on my network that have hard-coded DNS server addresses, lets say 8.8.8.8 for example. I want to make those devices use my DNS servers.

I created a simple port forward rule to catch TCP/UDP trafic destined to 8.8.8.8:53 and redirected it to 10.11.12.35:53.

Network tracing shows that the OpenWrt device catches the request to 8.8.8.8:53 from 10.11.12.99 and always redirects it to 10.11.12.35:53 but with the original source IP address. Of course the DNS server's final response is sent back on the 10.11.12.99 directly as it's on the same network and does not arrive at the client, presumably because the client didn't originate the request to 10.11.12.35.

So how do I get the Port forward rule to use the OpenWrt's IP address as the source so that the DNS server will return the response to the OpenWrt which will forward it to the as comning from 8.8.8.8?

I have tried with and without the 'Enable NAT loopback' option and have also tried a different subnet but always the request the OpenWrt send has the client IP address as the source.

Disable NAT Loopback to avoid collisions and create a SNAT rule.

config nat
        option name 'SNAT-DNS-Hijack'
        option target 'SNAT'
        option src 'lan'
        option src_ip '10.11.12.0/24'
        option dest_ip '10.11.12.35'
        option snat_ip '10.11.12.1' # Router IP
        option dest_port '53'

Thanks pavelgl, I'm mainly a LUCI user so disabling NAT Loopback on the port forward is fine but where does the 'config nat' go? Also the 10.11.12.1 is supposed to be the router IP, is that the OpenWrt device address 10.11.12.250?

LuCI->Network->Firewall->NAT Rules

Yes.

Thanks that works a treat. I even removed the 8.8.8.8 and it works for any target DNS server.

Ooops looks like remove the 8.8.8.8 stopped it working. I guess I'll just have to check the logs to see what DNS servers are being used and add allowed ones to the list.

pavelgl,

In the SNAT rule you specify dest_port '53' but I can't see anywhere to set that in LUCI.

Also the port forward rule only seems to allow one destination IP address, 8.8.8.8 in my example, Is there a way to allow for other DNS servers, preferably any?

Well, not all options are available in LuCI. Not a big problem in your case.

We haven't seen your DNAT rule, but it should work without specifying a destination address(es). The important thing is to exclude the internal DNS server from the rule to avoid a loop.

Since you have two such servers, it will be a bit complicated because you need to use IP sets.

Use the --custom-- field to add an exclamation mark (!) in front of the set name.

In a DNAT rule, you can also specify multiple destination addresses using ip sets.