How to allow certain domains only with firewall rules?

Hi all,
I've set a firewall rule to stop all access to internet after certain time. This works.

However, I also want to give access to certain website, for school work and Microsoft 365 sites. My test was using nslookup to get IPs, and add them manually in an ipset. But initial test shows very slow/nearly non-functioning connections to these sites.

I've been looking at using dnsmasq-full and ipset to populate the IPset automatically. This somehow didn't work and I had to reset the router. However, from reading this Dnsmasq-full, ipset support removed (in master) , it looks like the old guide using this combo (dnsmasq-full and ipset) will not work anymore.

What would be the best way to do this going forward?

CDNs often involve IPv6 and rely on dynamic subdomains and transient domains.
You can populate IP sets by ASN or try using OpenWrt snapshot with latest dnsmasq that supports nftables sets.

Here is the situation:
OpenWrt 22.03.x

  1. dnsmasq-full does not have nftset support but does have ipset support
  2. As 22.03.x is migrated to nftables, it does not support ipsets

Conclusion for 22.03.x:
dnsmasq populated ipsets are not supported.
dnsmasq populated nftsets are not supported.
Without some 3rd party package or writing something yourself, it cannot be done.

OpenWrt Snapshot

  1. dnsmasq full does not have ipset support but does have nftset support
  2. Snapshot is migrated to nftables so does not support ipsets
  3. FW4 has a non-standard ipset emulation and dnsmasq-full is patched, preventing standard nftset support.

Conclusion for Snapshot:
Neither dnsmasq populated ipsets, nor dnsmasq populated nftsets are supported "out of the box".
Without some 3rd party package or writing something yourself, it cannot be done.

Note: "ipset" is a standard Linux package. Unfortunately OpenWrt has decided to diverge from standard ipset and nftset support, breaking many other packages, even when those packages are fully migrated to nftables. This was done on the pretext of providing "simple" support for users with little technical knowledge who want to manually add a list of ip addresses using Luci or uci.

Thank you, very succinct info on the whole situation. I am not good enough to write anything for myself in Linux, so that is quite out of the questions. I do wonder how the OpenWrt team will take this going forward, because IPset features is a very good one that I am sure a lot of people uses.

I've tested the latest OpenWrt snapshot with dnsmasq-full+fw4 and it works for me.
The only problem is that it generates long lines which may fail with multiple domains.
There's a PR splitting long lines, but it was not accepted in time:

This is the OpenWrt "ipset" emulator making a (unique to OpenWrt) mess of things.

The standard Linux way defines an nftset in dnsmasq and adds the dynamic set and appropriate rules to the nft ruleset.

The firewall is nftables. Fw4 is just a static configuration tool.

In OpenWrt you have to pretend you are still using iptables ipset but of course iptables is not present. Any packages built to use ipset or nftset support will fail unless patched/rewritten for OpenWrt.

I'm not sure about your issue, but it works fine for me basically OOTB on the latest snapshot.
The patch mentioned above is only necessary when the number of domains reaches hundreds or more.

1 Like

Hi,
thank you for your answer. I'm looking forward doing the same thing as Rangnarok with the current stable version of OpenWRT : 22.03.05. I've got a wireguard interface from which I would like to limit the domains that can be reached.
I tried the "populate IP sets by ASN" but I'm a bit lost. Here's what I did:

  • Create a IP set in command line. The IP set is visible in LuCI -> Network -> DHCP and DNS -> IP Sets. But it does not display any information other than the name of the IP set and the Domain I provided.
  • Created two firewall traffic rules: LuCI -> Network -> Firewall -> Traffic Rules
  • First one to allow my IP Set: defined source zone (a wireguard interface), destination zone (wan), action is "accept", then "Advanced Settings" -> Use ipset and the name of my ipset.
  • Second one to reject any other packets: defined source zone and destination zone, action to "Reject".

Applying the firewall rules, my wireguard "clients" can still connect to any domain. And I don't have any feedback about the content of the IPset I created.
Could you please detail a bit how to proceed with the IP sets method?
Thank you!

You can test with disabled permissive firewall rule to make sure the prohibitive one actually works.

Thank you for your swift answer (and sorry for the delay).
I tested with only the prohibitive one and it works as intended (no traffic allowed).
I think my IP Set is empty which could be the reason why all traffic is allowed when I enable permissive firewall.
I'll dwelve into that. Thank you for your help.

The rule using an empty IP set will be ignored, only elements like 0.0.0.0/0 and ::/0 can match any IPv4 and IPv6, so it should be an error in the config, check the output:

uci show firewall; nft list ruleset