Using ipset by domain from LuCi in 23.05

I followed this guide here:

and also this one:

I have two observations.

Firstly, incorporating a hyphen in an ipset name appears to break things - one ends up with:

root@OpenWrt-1:~# service firewall restart
Section @rule[0] (Restrict-OpenWrt-GitHub) references unknown set 'OpenWrt-GitHub'

Secondly, why when setting ipset in LuCi:

does this rule get generated:

ip saddr @OpenWrtGitHub counter packets 0 bytes 0 jump reject_to_wan comment "!fw4: Restrict-OpenWrt-GitHub"

Surely the point here is not for source address to get referenced but destination address to get referenced?

Should 'Use ipset' get broken up in two: one for source and one for destination?

My goal here is to reject packets directed to domain(s) within an ipset. How would I achieve that with the restriction that ipset covers 'source' address?

Try changing the ipset option to custom value OpenWrtGitHub dest


Great OK that works - thanks, albeit it's a little obscure!

Perhaps the two issues identified above ought to be addressed:

  • hyphen breaks things; and

  • LuCi should split up 'Use ipset' into destination / source somehow.

Does this seem reasonable?

By the way, I take it the script and 'ipset setup' is necessary for all this to work? Should this stuff here:

not get integrated into OpenWrt base (maybe wrong terminology here) such that users don't need to install the script / type 'ipset setup' to make this LuCi functionality work?

All the ipset creation and population by dnsmasq can be setup in LuCI in 23.05 (thanks to dnsmasq 2.89).

You also have the option to setup the ipset “direction” (src or dest) when you define the match attribute (src_ip, dst_ip, or just ip). Otherwise, you can specify it in the individual firewall rules like jow suggested.

1 Like


is kind of obscure though, no? I mean wouldn't it be better to have something like:

  • Use ipset (source)
  • Use ipset (destination)

And also a hyphen in the ipset name breaks things at present.

Also I'm presuming that ultimately the install and invocation of the 'ipset' script (as per this) should be ultimately dispensed with, with this happening in the background automatically? Since it seems like this background script is needed at present for this LuCi functionality to work properly.

I’m talking about in the IP Sets tab in the firewall page.

What did you include in your ipset that required the custom script?

If it’s just domains, they can be added on the IP Sets tab under DHCP and DNS.

It may not be intuitive yet, but the functionality is there for DNS-based sets.

Doesn't this rely on 'resolveip' and this script here:

Or does it render them redundant?

The IP Sets tab in the Firewall page creates the sets in nftables. The IP Sets tab under DHCP and DNS tells dnsmasq to populate the given sets with the query results of the given domains. As dnsmasq receives queries for a specified domain, it will populate the named set with the IPv4 and/or IPv6 results of the queries.

Using resolveip would give you the current IPs at the time the script runs, but if they change later (before the 3 hour cron job from the wiki), the set will be stale.

If you’re only interested in domains (and not fixed IPs, CIDRs or ASNs), then dnsmasq will do all the heavy lifting for you.

EDIT: the ipset/nftset functions require the dnsmasq-full package.

I updated the code and it should work now.


@vgaetera so is the 'resolveip' package and script needed to allow the LuCi IP sets to get populated and work?

There are 2 different methods to populate IP sets with their own pros and cons:

  • Pre-resolve domains with resolveip following the wiki article linked in the OP, this way doesn't actually require dnsmasq, and clients can use any DNS server including DoH or DoT, but it doesn't work well for subdomains and CDNs, although it can be mitigated with IP sets by ASN.

  • Use dnsmasq-full to resolve domains and populate IP sets, but make sure the clients use exclusively dnsmasq, and disable DoH and DoT on the clients, this can work with CDNs, but restarting the router becomes a problem due to DNS caching on the client side.

1 Like

Ah got it. Thanks! And thanks to you too @dave14305. @vgaetera for those who want to switch from the former to the latter, could you please outline a short uninstall routine for the script?

1 Like
opkg remove resolveip
ipset unset
rm -f /etc/hotplug.d/iface/90-online
rm -f /etc/hotplug.d/online/70-ipset-setup
rmdir /etc/hotplug.d/online
rm -f /etc/profile.d/
rmdir /etc/profile.d
sed -i -e /70-ipset-setup/d /etc/crontabs/root
sed -i -e /70-ipset-setup/d /etc/sysupgrade.conf
sed -i -e /90-online/d /etc/sysupgrade.conf
uci -q delete dhcp.filter
uci commit dhcp
uci -q delete firewall.filter
uci -q delete firewall.filter6
uci -q delete firewall.fwd_filter
uci -q delete firewall.fwd_filter6
uci commit firewall
service firewall restart
1 Like

Thanks @vgaetera!

1 Like

OK the dnsmasq-full approach also seems to work.

I encountered one or two hiccups along the way though, including at least:

root@OpenWrt-1:/etc/config# service firewall restart
/dev/stdin:9:6-18: Error: Could not process rule: File exists
        set OpenWrtGitHub {
The rendered ruleset contains errors, not doing firewall restart.

associated with changing an existing IP set:

The fix is to change, disable, then re-enable.

This is very helpful. So if I understand correctly say all clients simply use their own DoTs then with the second approach the IP sets will never get populated because dnsmasq only updates the IP sets on receipt of queries, but since all clients use their own DoTs then dnsmasq never receives queries to the domains and so never updates the IP sets. So the advantage of 'resolveip' is to ensure that the IP sets are updated regardless.

Would a hybrid approach also work in which 'resolveip' and your script updates the IP sets every so often but they are also updated on the fly whenever a new query to dnsmasq is issued? This could be beneficial for mixture of clients that use dnsmasq and their own DoTs?

It sometimes requires to cold start the fw4 service to properly apply the changes.
There's likely a bug in fw4 that can explain this behavior.


Yes, combining both methods can work if necessary.

You can as well consider using banIP as it works in a similar way.
Assuming that your goal is just filtering and doesn't involve PBR by IP set.

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