-
Notifications
You must be signed in to change notification settings - Fork 128
Description
I'm facing a problem with my DNS resolution chain that lead to dnssec validation failures on some names:
My raspberry pi (192.168.0.254 in the following examples) runs https_dns_proxy on port 5053 to connect to Cloudflare's DOH service. dnsmasq uses the proxy service on port 5053 as upstream DNS server and offers a classic DNS service for the internal network on port 53. So far so normal.
One of my computers (192.168.0.2, aka "grey") running Gentoo ended up using systemd-resolved. I guess this got pushed through systemd defaults somewhen. Via dhcp it learns to talk to said dnsmasq on 192.168.0.254:53. This mostly works, except that some domains fail to resolve, with systemd-resolved complaining abnout dnssec:
$ dig bmeia.gv.at
; <<>> DiG 9.18.31 <<>> bmeia.gv.at
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 7213
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;bmeia.gv.at. IN A
;; Query time: 341 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Sat May 03 15:53:27 EAT 2025
;; MSG SIZE rcvd: 40
$ resolvectl query bmeia.gv.at
bmeia.gv.at: resolve call failed: DNSSEC validation failed: no-signature (Network Error)
journalctl -f has the following complaint:
May 03 15:52:37 grey systemd-resolved[127851]: [🡕] DNSSEC validation failed for question bmeia.gv.at IN DNSKEY: no-signature
May 03 15:52:37 grey systemd-resolved[127851]: [🡕] DNSSEC validation failed for question bmeia.gv.at IN A: no-signature
May 03 15:52:37 grey systemd-resolved[127851]: [🡕] DNSSEC validation failed for question bmeia.gv.at IN AAAA: no-signature
Almost all other domains work fine, including dnssec validation:
$ resolvectl query go.dnscheck.tools
go.dnscheck.tools: 2a01:4f8:1c1e:84c3::1 -- link: wlan0
116.203.95.251 -- link: wlan0
-- Information acquired via protocol DNS in 1.2003s.
-- Data is authenticated: yes; Data was acquired via local or encrypted transport: no
-- Data from: network
stefan@grey ~ $ resolvectl query badsig.go.dnscheck.tools
badsig.go.dnscheck.tools: resolve call failed: DNSSEC validation failed: invalid (DNSSEC Bogus: failed to verify badsig.go.dnscheck.tools. A: using DNSKEY ids = [35243])
The two I found were and bmeia.gv.at and www.thecitizen.co.tz . There might of course be more.
Doing one of the following works around the issue:
- Set DNSSEC=no in /etc/systemd/resolved.conf, but this obviously breaks dnssec.
- Cut out https_dns_proxy and make dnsmasq talk directly to e.g. 1.1.1.1 port 53 (see the footnote below though)
- Cut out dnsmasq and let systemd-resolved talk to https_dns_proxy directly
- Cut out systemd-resolved and let the glibc resolver talk to dnsmasq->https_dns_proxy->cloudflare
So the following chain fails:
dig -> systemd-resolved -> dnsmasq -> https_dns_proxy -> cloudflare
The following chains work:
- dig -> systemd-resolved -> dnsmasq -> cloudflare
- dig -> systemd-resolved -> https_dns_proxy -> cloudflare
- dig -> dnsmasq -> https_dns_proxy -> cloudflare
The first two of those also show "Data is authenticated: yes" for bmeia.gv.at when I use resolvectl. www.thecitizen.co.tz does not seem to have a dnssec signature. The last one (without systemd-resolved) shows a dnssec record in dig +dnssec for bmeia.gv.at.
Other systems I am using (Android, Mac OS, Linux without systemd-resolved) work fine.
I built https-dns-proxy from source, git commit 0e074b4. For the examples here I ran it with ./https_dns_proxy -b 192.168.0.1,1.0.0.1 -r https://cloudflare-dns.com/dns-query -4 -l - -a 0.0.0.0 -p 5053 as root. The normal startup service invokes it as unprivileged user and only allows connections from 127.0.0.1 of course.
Footnote: Any unencrypted DNS traffic is intercepted by my ISP and answered by its own servers to implement a dumb filter to semi-satisfy legal requirements. I don't care too much about the filtering, but the ISP's DNS server is unresponsive every now and then, making my entire connection unstable for stupid reasons. Hence the use of DNS over HTTPS.