When following the guide to block DNS over HTTPS from the wiki it assumes ipset-extras and hotplug-extras are installed. The 60-ipset-doh script downloads a list of domains which then is converted into IPs by resolveip used in ipset-extras.
However, ipset-extras sets the resulting ipset to hash:net as seen below, which as far as I understand expects a CIDR-range and not a single IP per entry, see below:
uci -q batch << EOI
set firewall.'${IPSET_NAME}'='ipset'
set firewall.'${IPSET_NAME}'.name='${IPSET_NAME}'
set firewall.'${IPSET_NAME}'.family='${IPSET_FAMILY}'
set firewall.'${IPSET_NAME}'.storage='hash'
set firewall.'${IPSET_NAME}'.match='net'
$(sed -n -e "s/^.*${IPSET_MATCH}.*$/\
del_list firewall.'${IPSET_NAME}'.entry='\0'\n\
add_list firewall.'${IPSET_NAME}'.entry='\0'/p" "${IPSET_TEMP}")
EOI
}
The resulting ipset is therefore useless for the purpose of blocking. Altering the script to instead store the entries as hash:ip produces the expected results. This can be tested through going through the procedure as described in the wiki-page for blocking DNS over HTTPS and adding a rule as such:
config rule
option name 'testing ipset'
option src '*'
option dest '*'
option proto 'all'
option family 'ipv4'
option ipset 'doh dest'
option target 'REJECT'
And trying to ping for example 1.1.1.1 which will succeed. Using hash:ip results in the ping being blocked as expected.
As a solution to this issue, the easiest way would probably be to modify the ipset-extras script to add a {IPSET_HASH} variable which is set depending on which of the functions (ipset_domain, ipset_cidr, ipset_asn) are called to fill the {IPSET_ENTRY} variable. Now, my (b)ash scripting skills are seriously subpar, so I'm at a loss of how to properly do this.
Or am I missing something here?
EDIT: Using OWRT 21.02 and ipset v7.6