Just to update you on this. It's a little bit off-topic, but considering the issue I ran into and that you guys are also running dns proxies.
I ended up installing dnsproxy; it's significantly larger than stubby, but it supports, all-in-one, DNS over TLS, DNS over HTTPS, DNS over HTTPS/3, DNS over QUIC and DNSCrypt.
Currently, I've a mix of DNS over TLS and DNS over HTTPS/3 upstream servers, but I will switch to DNS over QUIC (with DNS over TLS as fallback) once more servers start supporting it.
With that being said, I ran into a minor issue with the network.rrdns ubus call. This ubus call is part of LuCI's rpcd-mod-rrdns and is used by LuCI to perform reverse DNS lookups for some of its display information.
While network.rrdns takes an optional DNS server address and port, LuCI doesn't actually pass any to it, which causes rrdns to fallback to looking at /etc/resolv.conf, taking the first valid server, see https://github.com/openwrt/luci/blob/openwrt-23.05/libs/rpcd-mod-rrdns/src/rrdns.c#L251-L284
Now, once the dns proxy was set, dnsmasq option noresolv set to 1 and all network.[interface].dns entries removed, /etc/resolv.conf started pointing to an empty file.
root@router1:~# cat /etc/resolv.conf
# Interface wan
# Interface wan6
This causes network.rrdns to fail, if no server is explicitly passed to it as it can no longer obtain a server from /etc/resolv.conf.
A quick look at dnsmasq's service init script showed me that there is a "hidden" option that controls writing to /tmp/resolv.conf (pointed by /etc/resolv.conf).
This option is always forced to 1, if noresolv is not 1, resolvfile is /tmp/resolv.conf.d/resolv.conf.auto (or not set, defaulting to this path) and the option itself is not explicitly set in dhcp.dnsmasq. See: https://github.com/openwrt/openwrt/blob/openwrt-23.05/package/network/services/dnsmasq/files/dnsmasq.init#L1050-L1057 and https://github.com/openwrt/openwrt/blob/openwrt-23.05/package/network/services/dnsmasq/files/dnsmasq.init#L1182-L1192
I am leaving the fix here, in case any of you also run into this issue. Simply setting localuse to 1 forces the script to write a proper local resolv.conf.
uci set dhcp.@dnsmasq[0].localuse='1'
uci commit
service dnsmasq restart
Result:
root@router1:~# cat /etc/resolv.conf
search intranet
nameserver 127.0.0.1
nameserver ::1
root@router1:~# ubus call network.rrdns lookup '{"addrs":["139.178.84.217", "2604:1380:4641:c500::1"], "limit":2}'
{
"139.178.84.217": "dfw.source.kernel.org",
"2604:1380:4641:c500::1": "dfw.source.kernel.org"
}