Ipset firewall configuration does not work with dns resolver

Hi, I want to block all traffic from LAN to WAN except a few hosts for a specific device laptop(192.168.1.143). It works with static IP addresses, but not with an ipset loaded from a DNS query like github.com.

The idea is that the whole wan is blocked I have to whitelist domains. I tried to figure it out by some randomly distributed stuff from the web, but the examples are mostly for a »vanilla OpenWrt«. I think the problem is, that the default Turris OS does not use dnsmasq as DNS provider it uses a resolver configuration. I found also this thread How to use ipset with knot or remove it, but it does not help me.

/etc/config/firewall

config ipset
        option name 'MyExample'
        option match 'dest_net'
        option storage 'hash'
        option family 'ipv4'
        option enabled '1'

config rule
        option name 'laptop allow ipset MyExample'
        option src 'lan'
        option dest 'wan'
        list src_ip '192.168.1.143'
        option ipset 'MyExample'
        option target 'ACCEPT'
        list proto 'any'
        option enabled '1'

config rule
        list proto 'all'
        option name 'laptop allow specific address'
        list src_ip '192.168.1.143'
        option dest 'wan'
        list dest_ip 'some_ip_to_whitelist'
        option target 'ACCEPT'
        option src 'lan'
        option enabled '1'

config rule
        option src 'lan'
        option name 'laptop no wan'
        option dest 'wan'
        option target 'REJECT'
        list proto 'all'
        list src_ip '192.168.1.143'
        option enabled '1'

/etc/config/ipset-dns

config ipset-dns
	option ipset 'MyExample'

/etc/config/dhcp

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option domain 'lan'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option resolvfile '/tmp/resolv.conf.auto'
	option localservice '1'
	option port '0'
	option nonwildcard '0'
	option dhcpscript '/etc/resolver/dhcp_host_domain_ng.py'
	list ipset '/github.com/MyExample'
	list ipset '/archlinux.org/MyExample'

I think the dnsmasq »list ipset« entities are ignored.

A custom.conf injected in

/etc/config/resolver

config resolver 'kresd'
option rundir '/tmp/kresd'
option log_stderr '0'
option log_stdout '0'
option forks '1'
option include_config '/etc/kresd/custom.conf'

/etc/kresd/custom.conf

hostnames = {'github.com', 'archlinux.org'}
policy.add(policy.suffix(policy.STUB({'127.0.0.1:53001'}), policy.todnames(hostnames))

I grepped the address 127.0.0.1:53001 by logread -e ipset-dns; netstat -l -n -p | grep -e ipset-dns

If I restart the resolver with
/etc/init.d/resolver restart
dns will not work anymore. why?

But I think the address will sometimes change, so the setup is not automated?

Turris Omnia
Turris OS Version 5.1.8
Turris OS Branch HBS
Kernel-Version 4.14.216

I see unbalanced parentheses in your kresd config. Generally it’s good to read the logs when something is wrong (you’d probably need to flip those log_* options for that, too).

Yes it was the missing parentheses and the address format: hostname@port

hostnames = {'github.com', 'archlinux.org'}
policy.add(policy.suffix(policy.STUB({'127.0.0.1@53001'}), policy.todnames(hostnames)))

now it works! :partying_face:

# ipset list
Name: MyExample
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 368
References: 1
Number of entries: 1
Members:
140.82.121.3

But I am not yet fully satisfied:

The hard coded ipset-dns 53001 port will maybe change after the next reboot. Is there a way to automate or define the port constantly for this service? I think it’s not best pratice to template a command like logread -e ipset-dns; netstat -l -n -p | grep -e ipset-dns into the kresd custom.conf.

And there is also another issue. I need to make a DNS lookup request, to fill the IP addresses list with the related addresses for the domain in ipset list:

# nslookup -p53001 archlinux.org 127.0.0.1
has anyone an elegant solution for it? Maybe there is already a feature? I found in the OpenWRT a small script, is there no other way?