DNS hijacking DNAT to another LAN device

I'm running a DNS server on 192.168.1.2 and using dnsmasq on 192.168.1.1 as an upstream. I want to redirect other devices to 192.168.1.2 but it doesn't work.

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Redirect-DNS'
	option family 'ipv4'
	option src 'lan'
	list src_mac '!CF:E2:26:26:82:C3'
	option src_ip '!192.168.1.2'
	option src_dport '53'
	option dest_ip '192.168.1.2'
	option dest_port '53'
	option reflection '0'

The Luci config generates 2 nftables rules:

chain dstnat_lan {
    ip saddr != 192.168.1.2 tcp dport 53 ether saddr != cf:e2:26:26:82:c3 counter packets 0 bytes 0 dnat ip to 192.168.1.2:53 comment "!fw4: Redirect-DNS"
    ip saddr != 192.168.1.2 udp dport 53 ether saddr != cf:e2:26:26:82:c3 counter packets 17 bytes 1176 dnat ip to 192.168.1.2:53 comment "!fw4: Redirect-DNS"
}

Other devices cannot receive DNS responses via dig @192.168.1.1 domains, while dig @192.168.1.2 domains works normally.

Create an additional SNAT rule.

config nat
        option name 'DNS-Redirect-SNAT'
        option src 'lan'
        option dest_ip '192.168.1.2'
        option dest_port '53'
        option target 'SNAT'
        option snat_ip '192.168.1.1'

Thanks. It works, but why does the reflection option not generate SNAT rule automatically? I tried setting it to 1 but it didn't work, unlike port forwards to wan.

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'Windows Xbox'
	option src 'wan'
	option src_dport '3074'
	option dest_ip '192.168.1.140'
	option dest_port '3074'
	option reflection '1'

This rule will add SNAT automatically.

        chain dstnat_lan {
                ip saddr 192.168.1.0/24 ip daddr PUBLIC_IP tcp dport 3074 dnat ip to 192.168.1.140:3074 comment "!fw4: Windows Xbox (reflection)"
                ip saddr 192.168.1.0/24 ip daddr PUBLIC_IP udp dport 3074 dnat ip to 192.168.1.140:3074 comment "!fw4: Windows Xbox (reflection)"
        }

        chain srcnat_lan {
                ip saddr 192.168.1.0/24 ip daddr 192.168.1.140 tcp dport 3074 snat ip to 192.168.1.1 comment "!fw4: Windows Xbox (reflection)"
                ip saddr 192.168.1.0/24 ip daddr 192.168.1.140 udp dport 3074 snat ip to 192.168.1.1 comment "!fw4: Windows Xbox (reflection)"
        }

        chain dstnat_wan {
                meta nfproto ipv4 tcp dport 3074 counter packets 0 bytes 0 dnat ip to 192.168.1.140:3074 comment "!fw4: Windows Xbox"
                meta nfproto ipv4 udp dport 3074 counter packets 0 bytes 0 dnat ip to 192.168.1.140:3074 comment "!fw4: Windows Xbox"
        }

Because to generate the reflection rules, fw4 requires masquerading on the external (source) zone to be enabled. Enable masquerading on the lan zone and you will see the result, but it's not what you want or need.

@pavelgl is the whole problem not the result of asymmetric routing so if the invalid filter on the router is disabled it could work without the SNAT rule?

Let's say host 192.168.1.100 initiates a DNS query to the router or to an external DNS server.
The request will be intercepted and forwarded to 192.168.1.2 on behalf of the initiator, which is on the same subnet. That's way 192.168.1.2 will try to reply directly to host 192.168.1.100 and the host will drop the connection because the reply came from an unexpected IP address.

The SNAT rule is required to force all DNS traffic through (and on behalf of) the router. The downside is that in the logs of 192.168.1.2 all requests will be recorded as having arrived from the router and not from the original initiator.

IMO it would be better to set DHCP option 6 and use the hijack rule as a last resort for devices with hardcoded DNS.

3 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.