Blocking Lan clients from using DoH

following up on earlier threads, I finally got round to using the recipe at https://openwrt.org/docs/guide-user/firewall/fw3_configurations/intercept_dns to block potentially hostile LAn clients from using DoH.
I have a couple of errors, can anyone help troubleshoot?

on running

# Configure IP sets
uci -q delete dhcp.doh
uci set dhcp.doh="ipset"
uci set dhcp.doh.instance="doh"
uci add_list dhcp.doh.name="doh"
uci add_list dhcp.doh.name="doh6"
uci commit dhcp
/etc/init.d/dnsmasq restart

it seems to fail with the error

root@OpenWrt:~# /etc/init.d/dnsmasq restart
udhcpc: started, v1.36.0
udhcpc: broadcasting discover
udhcpc: no lease, failing

and at the final part

# Populate IP sets
ipset setup

I get the error
-ash: ipset: not found

I can see the Deny-DoH traffic rule is created in Luci from Lan to Wan with the port 443 and on both UDP and TCP

Can anyone help please?

This not a bad error, but a good error, as it is checking if there are other dhcp servers listening.

thanks for super quick reply. I did install this, but did it again to check and I still get the failure


root@OpenWrt:~# opkg install resolveip
Package resolveip (2) installed in root is up to date.
root@OpenWrt:~# # Populate IP sets
root@OpenWrt:~# ipset setup
-ash: ipset: not found
root@OpenWrt:~#

no you did not install it. opkg install ipset is missing.
resolveip is simple dns query tool.

but please note: 22.x using fw4 which is nftables based, dnsmasq 2.86 is not yet nft compatible. the ipset extra guide is for ipset, will not work together with fw4

duh you are right! thanks! sorry....

When I try to install ipset I get the incompatibilty errors below. is that because I am on a snapshot and need to have snapshot and packaged aligned?
Or is your point above a different one? That suggests I need to wait until dnsmasq is updated and can go no further today - do I understand right?

 * pkg_hash_check_unresolved: cannot find dependency kernel (= 5.15.94-1-d6f4013419221202000223d083538d55) for kmod-nf-reject
 * pkg_hash_check_unresolved: cannot find dependency kernel (= 5.15.94-1-d6f4013419221202000223d083538d55) for kmod-nf-ipt
 * pkg_hash_check_unresolved: cannot find dependency kernel (= 5.15.94-1-d6f4013419221202000223d083538d55) for kmod-nf-log
 * pkg_hash_check_unresolved: cannot find dependency kernel (= 5.15.94-1-d6f4013419221202000223d083538d55) for kmod-ipt-core
 * satisfy_dependencies_for: Cannot satisfy the following dependencies for ipset:
 * 	kernel (= 5.15.94-1-d6f4013419221202000223d083538d55)
 * opkg_install_cmd: Cannot install package ipset.

yes

but my point is unrelated to snapshot. if you are using fw4 as firewall and ipset package they are not working together, i.e. cannot reference to an ipset in fw4 rules,

you need nft set so little update is required in the script, replace ipset add with nft add.

for example:

ipset add doh $ip -> nft add element inet fw4 doh { $ip }

so just run that command?

no no, that will be not enough.

this is an elegant solution, the idea is great to address the big problem with DNS over Https, i.e. DoH using standard HTTPS which is for legit traffic as well (access your bank account). so simply blocking all port 443 make no sense if your goal is to disallow clients to use a public DoH server instead the one you want as admin.

but as you can see from the link it is for fw3.

just create/use the online hotplug stuff, and overwrite 60-doh script by replacing ipset with nft (mind the syntax of course).

in high level the linked solution is that when wan interface goes online it will trigger the online hotplug script(s), so 60-doh will download a list of public DoH servers, resolve the domains and store the ip address in a set. this set can be used then in firewall to block access for example.

as mentioned the only problem is that the script is assuming fw3 and ipset, but 22.x fw4 and nft should be used.

dnsmasq could also use ipset in version pre-2.87, which similarly could add resolved ip address to a set (and then you could do whatever you want) but again while fw4 is introduced dnsmasq is still on 2.86 so you cannot populate resolved ips to nft set. yet.

ah - so what do i need to do then (once I have aligned snapshot and packages)
And sorry for testing your patience!!!

Yes, that was the solution I tried....

so change it like this?

# Configure hotplug
mkdir -p /etc/hotplug.d/online
cat << "EOF" > /etc/hotplug.d/online/60-nft-doh
if [ ! -e /var/lock/nft-doh ] \
&& lock -n /var/lock/nft-doh
then
uclient-fetch -O - "https://raw.githubusercontent.com/\
dibdot/DoH-IP-blocklists/master/doh-domains.txt" \
| uci -q batch << EOI
delete dhcp.doh.domain
$(sed -e "s/^.*$/\
del_list dhcp.doh.domain='\0'\n\
add_list dhcp.doh.domain='\0'/")
commit dhcp
EOI
lock -u /var/lock/nft-doh
fi
EOF
cat << "EOF" >> /etc/sysupgrade.conf
/etc/hotplug.d/online/60-nft-doh
EOF
. /etc/hotplug.d/online/60-nft-doh

what happens at the end where the current version wants

ipset setup

Does the reference to ipset need to change here also

# Configure IP sets
uci -q delete dhcp.doh
uci set dhcp.doh="ipset"
uci set dhcp.doh.instance="doh"
uci add_list dhcp.doh.name="doh"
uci add_list dhcp.doh.name="doh6"
uci commit dhcp
/etc/init.d/dnsmasq rest

the guide states:

# Configure hotplug
mkdir -p /etc/hotplug.d/online
cat << "EOF" > /etc/hotplug.d/online/60-ipset-doh
if [ ! -e /var/lock/ipset-doh ] \
&& lock -n /var/lock/ipset-doh
then
uclient-fetch -O - "https://raw.githubusercontent.com/\
dibdot/DoH-IP-blocklists/master/doh-domains.txt" \
| uci -q batch << EOI
delete dhcp.doh.domain
$(sed -e "s/^.*$/\
del_list dhcp.doh.domain='\0'\n\
add_list dhcp.doh.domain='\0'/")
commit dhcp
EOI
lock -u /var/lock/ipset-doh
fi
EOF
cat << "EOF" >> /etc/sysupgrade.conf
/etc/hotplug.d/online/60-ipset-doh
EOF
. /etc/hotplug.d/online/60-ipset-doh
 
# Populate IP sets
ipset setup

and as prerequisite https://openwrt.org/docs/guide-user/advanced/ipset_extras
this guide will explain how to override the ipset command with an ipset script and introducing the new setup parameter (details at link). this will not fly for the aforementioned reason.

i suggest:

  • just to create the online hotplug setup
  • create a 60-doh script as follow
    NOTE: this is not a fully working solution
if [ x$INTERFACE = xwan ]
then
        lock -n /var/lock/doh.lock && logger -t "hotplug.online" "Acquire lock to resolve IPs into DoH set." \
        && {

        logger -t "hotplug.online" "Downloading list of public DoH domains"
        uclient-fetch -q -O - "https://raw.githubusercontent.com/dibdot/DoH-IP-blocklists/master/doh-domains.t
        | uci -q batch << EOI
delete dhcp.doh.domain
$(sed -e "s/^.*$/\
add_list dhcp.doh.domain='\0'/")
commit dhcp
EOI

# you dont need to delete and add doh.domain entries once you delete the whole uci entry just before.


        logger -t "hotplug.online" "Found $( uci show dhcp.doh.domain | wc -w) DoH domain(s)."
        logger -t "hotplug.online" "Filling DoH set ..."

# todo: flush nft set first !!!

        i=0
        for d in $( uci show dhcp.doh.domain | sed -e 's|^.*=||' -e "s|'||g")
        do
                for ip in $( resolveip -t1 $d )
                do
                        [ -z "$ip" ] && continue

                        i=$(( $i + 1 ))
                        # 22.x
                        [ $( expr index "$ip" '.' ) -gt 0 ] && nft add element inet fw4 doh { $ip } || nft add element inet fw4 doh6
                done
        done

        lock -u /var/lock/doh.lock && logger -t "hotplug.online" "Released lock. Resolved $i IP address(es)."
        rm -f /var/lock/doh.lock
        } || logger -t "hotplug.online" "Failed to acquire lock to resolve IPs into DoH set"
fi

thank you so much for a patient explanation.

Yet me absorb this so I fully understand and I will try again. So this means I don't need the ipset up command then?

if you want to use sets within fw4 then no you don't.

perfect - so just the revised script you provided - thank you so much

so you may find rough edges but i think yes, you just need resolveip, online hotplug setup and the enhanced working script (as mine is just a quick, raw stuff).

edit: as said, just found for sure one mistake, one done is missing ... i update the script ... fixed

oh, one more question, to flush as you advised, just
fw4 flush ?

no. that would flush all rules. you just need to flush the doh/doh6 sets

how do i do that?

that's your homework :wink:

LoL - thank you so much for your help - have a great day

1 Like