A DNS leak test showing your home network is not evidence that encrypted DNS failed, and it is not evidence that anything worked either. The test answers one question: which resolver did this query reach, from this network. Whether that is a problem depends on what you were protecting and from whom.

Write the goal down before running any test.

Step 1: name the protection you actually want

Three goals get mixed together. You may want an observer on the path to stop reading queries. You may want a particular resolver to stop receiving them. You may want the websites you visit to stop seeing your home address. Encrypted DNS serves the first, changes who satisfies the second, and does nothing at all for the third.

A VPN serves the third and, depending on the provider, the first. Neither tool is a superset of the other.

Step 2: choose a resolver and verify its identity

DNS over TLS wraps the query in a TLS session with the resolver, and DNS over HTTPS wraps it in an HTTP request; RFC 7858 and RFC 8484 describe both, and neither needs a tunnel. What matters operationally is that the certificate is verified against the name you configured, because an encrypted session to the wrong party is worse than plaintext to the right one. That means strict mode where the platform offers it, not an opportunistic mode that falls back when verification fails. Check the session directly before trusting the setting: openssl s_client -connect 9.9.9.9:853 -servername dns.quad9.net -brief.

The handshake should name the resolver you configured and return a chain you can verify.

Step 3: decide the failure behaviour

Every implementation has a policy for an unreachable encrypted resolver, and that policy is the privacy decision. Strict mode fails the lookup, which is visible and irritating. Opportunistic mode retries in plaintext, which is invisible and defeats the purpose on exactly the day it matters. Choose deliberately, then record the choice next to the requirement.

On systemd-resolved that means DNSOverTLS=yes rather than opportunistic; on Android it means the Private DNS hostname mode rather than automatic.

Check what is actually in force with resolvectl status | grep -i -A1 "dns over tls", because a drop-in file that was never reloaded changes nothing.

Step 4: check that applications follow the system resolver

A browser with its own secure-DNS setting bypasses the system configuration entirely, and so does a container runtime with an embedded resolver or a language runtime reading a hard-coded list. Either make those follow the system or configure them explicitly and record it. Then look at the fallback behaviour of each one, because they do not all fail closed. The inventory is short in practice: browser, container runtime, and whatever VPN client you also run.

Private organizational names stay on the approved internal resolver. Sending them to a public service so a test looks tidy creates a different problem on purpose.

Step 5: read the leak test against the requirement

A test that reports an unexpected resolver is a prompt, not a verdict. It may have observed your intended encrypted resolver, an application-specific setting, or a plaintext fallback you did not know about. Compare the reported resolver with what step 2 configured, and compare the result with the goal from step 1.

If the goal was keeping queries away from the local network, a test showing your ordinary resolver is a real finding. If the goal was anonymity while browsing, no DNS setting was ever going to deliver it.

Write the acceptance line in the language of the goal: these lookups use this verified resolver under these conditions. Anything broader is a claim you cannot test.

Artihkkalat mat laktásit