[Solved] Port forward/dnat on the same subnet under 22.03

Hi there!
I'm in the middle of evaluating OpenWrt as a replacement for my pfSense machines, since Linux allows me to bond bonded interfaces, where FreeBSD does not. I run 22.03 on an x86_64 Intel Atom board.

So, here I am trying to port the following functionality:

All machines on a given subnet [here: localaccess] should get their dns traffic redirected to the correct server (usually the router itself). This is to prevent that rogue devices that do not respect the dhcp setting are getting timeouts because of the firewall rules not allowing 53/udp.
In pfSense I set up a port forward rule which redirects dns traffic NOT targeting the gateway to the gateway itself, using 127.0.0.1 as the NAT IP.

I did the same in OpenWrt. Here are the respective rules that I defined:

config redirect
	option target 'DNAT'
	option name 'redirect-dns-from-localaccess'
	option src 'localaccess'
	option src_dip '!192.168.0.1'
	list proto 'udp'
	option src_dport '53'
	option dest_ip '127.0.0.1'
	option reflection_src 'external'

config rule
	option family 'ipv4'
	list proto 'udp'
	option src 'localaccess'
	option dest_port '53'
	option target 'ACCEPT'
	option name 'allow-dns-from-localaccess'

A little success I had was when I redirected to 192.168.0.1, since then an nslookup to another subnet (192.168.1.1) gave a reponse. But an nslookup to 192.168.0.2 timed out. When redirecting to 127.0.0.1, however, lookups time out every time. dnsmasq listens on 127.0.0.1 as well, though.

I tried NAT reflection with both internal and external addresses to no avail.

The nftables status also looks fine:

chain dstnat_localaccess {
		ip daddr != 192.168.0.1 udp dport 53 counter packets 0 bytes 0 dnat ip to 127.0.0.1:53 comment "!fw4: redirect-dns-from-localaccess"
	}

Any hints on how to achieve the desired outcome would be appreciated!

Regards
ph0x

What you appear to be looking to do is known as dns hijacking. Take a look at this article, and let us know if you have questions...

2 Likes

I compared my setup with the article and can't find much of a difference. Any specific areas that I should look into?

Well, at least the other subnet works again with the masquerading from the last paragraph. That's at least something. But the same subnet still doesn't work.

let's see your complete configuration:

Please copy the output of the following commands and post it here using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have:

cat /etc/config/network
cat /etc/config/firewall

I stripped it down to the relevant sections:

/etc/config/network

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fd99:2c4d:b446::/48'

config interface 'localaccess'
	option proto 'static'
	option device 'eth0'
	option force_link '0'
	option ipaddr '192.168.0.1'
	option netmask '255.255.255.0'
	option delegate '0'
/etc/config/firewall

config defaults
	option forward 'REJECT'
	option synflood_protect '1'
	option output 'REJECT'
	option input 'REJECT'
	option drop_invalid '1'

config zone
	option name 'localaccess'
	option forward 'REJECT'
	list network 'localaccess'
	option input 'REJECT'
	option output 'REJECT'

config rule
	option family 'ipv4'
	list proto 'udp'
	option src 'localaccess'
	option dest_port '53'
	option target 'ACCEPT'
	option name 'allow-dns-from-localaccess'

config redirect
	option target 'DNAT'
	option name 'redirect-dns-from-localaccess'
	option src 'localaccess'
	option src_dip '!192.168.0.1'
	list proto 'tcp'
	list proto 'udp'
	option src_dport '53'
	option reflection_src 'external'

config nat 'dns_masq'
	option name 'Masquerade-DNS'
	option dest_port '53'
	option target 'MASQUERADE'
	option family 'ipv4'
	option src 'localaccess'
	list proto 'tcp'
	list proto 'udp'
	option dest_ip '127.0.0.1'

Changing the very last line to 192.168.0.1 also makes no difference.

This output setting on the local access zone is probably the cause. What is your intent here? This will cause the network to be completely isolated (no traffic can exit the firewall towards that network).

I doubt that, because a more specific rule covers the desired traffic (conntracked input rule from my understanding). The intent is to be in complete control of the traffic to and fro, that's all.
I'll test it nontheless.

a few moments later

Yeah, no change.

And don't forget, it works when I direct the dns lookup at the correct address (192.168.0.1) or another subnet (192.168.1.0/24), only the same subnet is a problem.

What happens if you change this to 192.168.0.1?

Unfortunately the same result. I also tested some combinations in the DNAT rule with or without specific addresses and the like.

Ok. I’m out of ideas for the moment. I’d probably need to experiment, but I can’t do that now.

Hopefully someone else will have some ideas.

Thanks anyway for your time. At least this shows me, that I'm not completely off course here. I will test some other use cases that I'd have to port and come back to this problem later.
In the end it is also very unlikely that a rogue device chooses a dns address from the same subnet. :smiley:

Oh. Wait. Maybe I misunderstood.

You wish to intercept/hijack a dns request between two devices in the same subnet? So for example, if host 192.168.0.4 sends a dns request to say 192.168.0.72, you want to capture that and redirect?

I think I know what you're up to. The device that sends the wrong lookups is hooked directly to eth0, so the router should get every packet anyway and correctly apply the DNAT.
But yes, that's where I struggle right now.

Generally, you can’t because that traffic is switched and never hits the firewall.

You can look at using the bridge firewall - I haven’t ever used it, and I know it has quirks. But might do what you want.

(Keep in mind, this is a fw3 thing, I don’t know if it will work on fw4)

2 Likes

Like switched directly by the device? Because there's no hardware switch between the router and the test host.

If you have multiple devices on a single subnet, it is switched (L2). Always. Even if there isn’t a hardware switch, a bridge is the equivalent. And depending on the device you are using, there may be a hardware switch chip inside the device.

The exception would be the bridge firewall which is sort of between l2 and l3 (routed).

1 Like

I have to admit that I never checked what pfSense does, when I try to use a rogue dns server out of the same subnet.
Thanks for the insight though, that'll help with the evaluation!

a few moments later

You're right, even with pfSense this doesn't work. Then I have all I need with the DNAT and the MASQUERADE rules. Thanks again!

You’re welcome.

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.
Thanks! :slight_smile:

1 Like

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