Howto-FW4-DNS-Based-Firewall with nftsets and OpenWrt Snapshot

Since i have seen some other people asking for this feature to come back, i noticed that in master dnsmasq 2.87 was commited and the functionality can be implemented again with ease in current master.
So i took a standard openwrt master snapshot build for x86 and recorded the following steps.

First of all for this to work as expected we need dnsmasq-full package so ssh into the router and issue following commands:

opkg update
cd /tmp/ && opkg download dnsmasq-full
opkg remove dnsmasq
opkg install dnsmasq-full --cache /tmp/
rm -f /tmp/dnsmasq-full*.ipk

After the setup finished you can start to make changes in the firewall file. So open it up with your favorite editor

vi /etc/config/firewall

and add the following :

config nftset
        option name 'lan_4'
        option family 'ipv4'
        option timeout '180'
        option match 'dest_ip'
        option enabled '1'

config nftset
        option name 'lan_6'
        option family 'ipv6'
        option timeout '180'
        option match 'dest_ip'
        option enabled '1'

now save the file and afterwards issue:

uci commit firewall /etc/init.d/firewall restart
If everything went fine the nftsets should be created and waiting for dnsmasq to fill them so next we will open the /etc/config/dhcp file and add the following to it:

config nftset
        list name               'lan_4'
        list name               'lan_6'
        option table            'fw4'
        list domain             '#'

Don't close the file just yet since we need to adjust the Time To live that DNSMASQ issues for resolved domains, this way we can use a timeout in the nftsets without interupting usual surfing experience.
so under the dnsmasq section add this

        option max_ttl          '180'
        option min_cache_ttl    '60'
        option max_cache_ttl    '180'

This should pretty much be it for dnsmasq maybe you can find better timeout values for yourselves.
so commit the changes and restart dnsmasq.
Now in a standard Configuration of the firewall LAN->WAN forwards are always accepted, so we need a rule in the /etc/config/firewall file to reject all connections not in our nftsets open the file and add these rules:

config rule
        option name 'Reject-NFTSET-LAN->WAN-FWD-v4'
        option src 'lan'
        option ipset '!lan_4 dest'
        option dest 'wan'
        option proto 'all'
        option family 'ipv4'
        option target 'REJECT'

config rule
        option name 'Reject-NFTSET-LAN->WAN-FWD-v6'
        option src 'lan'
        option ipset '!lan_6 dest'
        option dest 'wan'
        option proto 'all'
        option family 'ipv6'
        option target 'REJECT'

After saving committing and restarting the firewall our system should now reject all traffic not resolved in our dnsmasq instance. effectively blocking doh and hardcoded ips.

Keep in mind i wanted to keep things simple. If wanted,I can post a config file for Segmenting the Network into LAN/WLAN/KIDS/GUESTS with each network segment having its own Dnsmasq instance and its own nftsets.
Have a nice Day
KDW

1 Like

Isn’t the uci syntax still config ipset?

Yes, it still is config ipset.

Kevins dnsmasq init.d also checks for the term nftset, so I thought it might be okay to use it. Not sure how to edit the post, but if I am able to i will change it.
I will check the uci terminology and learn it and revise the howto afterwords.

1 Like

You are a peach, thank you very much for this!

I'm trying to get this runnig with 23.05.0-rc4 but have no luck.

Creating the sets in table fw4 worked with this config:

config ipset
	option name 'dnsresolved_ip4'
	option family 'ipv4'
	list match 'dest_ip'
	option timeout '180'

config ipset
	option name 'dnsresolved_ip6'
	option family 'ipv6'
	list match 'dest_ip'
	option timeout '180'

But there is no publishing of addresses to the sets from dnsmasq. I do have dnsmasq-full installed and added this to /etc/config/dhcp:

config nftset
	list name 'dnsresolved_ip4'
	list name 'dnsresolved_ip6'
	option table 'fw4'
	list domain '#'

Any hint on this?

To start, change nftset to ipset. The uci syntax hasn’t changed from firewall3,

1 Like

Ok, I got it. (thanks @dave14305)

In /etc/config/dhcp it needs to be

config ipset
	list name 'dnsresolved_ip4'
        list name 'dnsresolved_ip6'
	option table 'fw4'
	list domain '#'

It's also showing up in Luci:

Ips are showing up in the sets. :slight_smile:

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