IP Sets in FW4 and DHCP settings

I am trying to create a rule that whitelists specific domain names i.e. alexa.co.uk.

There appears to be 2 places in which IP Sets can be created, under "DHCP and DNS" and "Firewall". The one under DHCP and DNS allows domain names to be added (I did that and called it alexa_ipset). Under the Firewall IP Sets tab it is not possible to add domain names, only IP addresses.

I created a FW rule using the interface and under the "Advanced Settings" there was no option to select from an existing list so I manually entered "alexa_ipset" in the field.

Probably predictably, it does not work. I thought it wouldn't because I could not see how the FW is going to "know" about the IP Set created in DHCP and DNS. Also, I don't see how/where the domain names are resolved to IP addresses for the FW to block.

Am I missing something? Any ideas/guides how I can achieve what I'm trying to using the UI?

By creating the ipset in the firewall pages.

By creating the ipset in the DCHP and DNS pages.

1 Like

I'm not sure I understand your comments.

I did create the IP set in the DHCP and DNS tab as that is the only place where I can add domain names. The IP Sets tab under the FW section does not allow domain name entry.

Here's what I did:

Created IP Set under DHCP and DNS -> IP Sets
Name: alexa_ipset
FQDN: list of fqdn entries
Netfilter table name fw4
Table IP family: IPv4

Under the FW rule -> Advanced Settings -> Use ipset "alexa_ipset"

It's not supposed to. That's what the entry under 'DHCP and DNS' is for. But you need to create the ipset in the firewall. Which is why there's a section in the 'Firewall' pages.

You need to add an ipset to the firewall with the same name as the one you've created under 'DHCP and DNS'. Then, as a minimum, you need to set what IP family the ipset is for and how it should match packets.

Once you've done that you can use the ipset in rules.

Thank you so much @krazeh

Does this look OK?

Packet Field Match is wrong. It should be dst_ip as you want to match packets that are going to specific IP addresses.

Thanks. I changed it to src_ip as I'm blocking incoming traffic from domains. I should have mentioned that earlier :slight_smile:

Just be aware that dnsmasq will only populate ipsets when a DNS lookup takes place. So if you're using this setup to allow access from remote locations you'll need to ensure that a DNS lookup for relevant domains takes place everytime the firewall is restarted.

1 Like

Thank you for that. I certainly wasn't aware of the way it worked. I thought it would have a schedule to do this in the background somehow.

Where is the data saved? i.e. the results of the resolved domains in relation to the ipset? Also, is it just a case of doing nslookup within openwrt to populates the list?

The ipset is created within the firewall rules. You can view it by SSH'ing to the router and running nft list ruleset. As it has no static entries it is empty when created (or recreated which is what happens whenever the firewall is restarted).

DNSmasq can be told to populate ipsets with the results of DNS lookups (this it what adding an entry on the 'DHCP and DNS' pages does) but there's no associated scheduled task. It's literally 'if domain X is looked up add the results to ipset Y'.

As long as DNSmasq does the resolving it doesn't matter where the lookup was done. You could do it on a client device as long as it's using the router as its DNS server. But, if you were looking to schedule a 'lookup' task then you could just just nslookup on the router.

Also @krazeh

Be aware that ipset is a legacy iptables utility. Unfortunately the decision was made in the development of fw4 (the OpenWrt nftables firewall configuration tool) to use a cludgy non-standard emulation of traditional ipsets, instead if directly supporting the native nftables nftsets.
This not only causes all sorts of confusion but also breaks the ability of defining a traditional ipset in the Dnsmasq config.

The data is saved in the nft ruleset. You can see it by looking at the output of:
nft list ruleset

For it to work with FW4, you must replace the default dnsmasq with dnsmasq-full.

That implies that you have some sort of block-list. Obviously implementation of the allow-list depends on your implementation of the block-list, so you may want to elaborate on that.

You do need two definitions for your set, one for dnsmasq to resolve domains from your set into IP addresses with which the ip set is populated, and another for firewall to take an action on a match.

AFAIK, for dnsmasq to properly populate the ip set when domain name is resolved, you need to replace the dnsmasq package with the dnsmasq-full package. Also, there are known compatibility issue between ip sets generated by dnsmasq-full and the ip set processed by firewall4 on 22.03, so you need to be on 21.02 or 23.05 for this to work.

I don't know of any way to troubleshoot it from WebUI, but the very first step would be verify if your setup supports such a scenario, but running:

ubus call system board
dnsmasq --version

Hi guys

I think I'm making good progress here with your help so many thanks.

I didn't realise that I needed the dnsmasq-full so I removed the existing one and installed the full version. Rebooted.

Now I'm getting the following under System Log:
daemon.err dnsmasq[1]: nftset ip fw4 alexa_ipset Error: No such file or directory; did you mean table ‘fw4’ in family inet?

Should I have created a file somewhere for the list to be written to or updated?

@stangri I'm trying to create an allowlist for incoming Alexa IP addresses to restrict access to my audio player to an Alexa Skill.
I will probably need to create a script to do nslookup every day or a few times a day to keep the list up to date :slight_smile:

In the dnsmasq set definition, leave the table family as IPv4+IPv6. The fw4 table is both IPv4+IPv6 (inet).

1 Like

That did the trick. Thank you all very much indeed.

Below is a summary of what is needed to get domain name ipsets to work with nftables fw4

  • dnsmasq-full (not the standard dnsmasq)
  • IP Set created under "DHCP and DNS"
    • Name of the set
    • FQDN of domain(s)
    • Table IP family "IPv4+6"
  • IP Set under "Firewall"
    • Name that matches the name of the set created under "DHCP and DNS"
    • Family "I specified IPv4"
  • Make sure you do "nslookup of the FQDNs in the IP Set"
  • SSH into OpenWrt and run "nft list set inet fw4 <ip set name>". This should hopefully output the table inet fw4 with the elements section containing the IP addresses of the FQDNs in the IP Set.

I hope this helps someone.

All credit goes to: @krazeh @bluewavenet @stangri @dave14305 for their time and insightful help


No, the dnsmasq-full manages that for you. Upon request to resolve a specific domain it will populate the ip set with the results. Unless Alexa uses the encrypted DNS requests (DoH or DoT), it will either use your router as advertised resolver, or if it has the hardcoded IP addresses for DNS servers, you can implement DNS Hijack on your router, either manually or as a part of existing OpenWrt package, like adblock-fast or https-dns-proxy or maybe others I'm not familiar with.

PS. You may want to mark your previous reply as a solution for anyone else trying to achieve the same.

Would dnsmasq do that periodically or as and when TTL expires?

I'm asking because this is for incoming connections so it is highly unlikely that I or any of my devices will be doing an nslookup for the domains especially as they're just the hyphenated IP address + .amazon.com e.g 1-2-3-3. amazon. com

Great question which is beyond my knowledge of dnsmasq. I know that it does resolve domains from the set into IPs when idle, but I don't know if it does it automatically on TTL expiration or not. That question should be asked in the upstream/main dnsmasq discussion forum (if it exists).

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