DoT, DoH, DoQ: encrypted DNS
DNS over TLS (DoT, port 853), DNS over HTTPS (DoH, port 443), DNS over QUIC (DoQ, port 853). All three encrypt the wire. None of them encrypt the records: those are still public. What changes is who can see which queries you ask.
Encrypted DNS is orthogonal to dnssec: DNSSEC proves a record is authentic; DoT/DoH/DoQ prevent observers from seeing which names you asked for at all. See anatomy-of-a-query for where in the query path each layer applies.
The three protocols at a glance#
| DoT | DoH | DoQ | |
|---|---|---|---|
| RFC | 7858 | 8484 | 9250 |
| Port | 853 (TCP) | 443 | 853 (UDP) |
| Transport | TCP + TLS | HTTPS | QUIC (UDP) |
| Hides on the wire | yes | yes (looks like HTTPS) | yes |
| Blends with web traffic | no (distinct port) | yes (port 443) | no (distinct port) |
| Per-query latency | TCP + TLS handshake | TCP + TLS + HTTP framing | 0-RTT possible |
| Connection reuse | yes | yes | yes |
Testing DoT with kdig#
Cloudflare's 1.1.1.1 and Google's 8.8.8.8 both serve DoT at port 853, and either works as a test target. kdig (from knot-dnsutils) is the easiest CLI for this because mainstream dig only added +tls in BIND 9.18 ("The dig tool is now able to send DoT queries (+tls option)"):
kdig @1.1.1.1 +tls cloudflare.comInstall kdig via apt install knot-dnsutils on Debian/Ubuntu or brew install knot on macOS.
nslookup cannot send queries over DoT. Use
kdigfor DoT testing.
Stock macOS
dig(BIND 9.10.x) does NOT support+tlsor+https. Ifdig +tlsreturns an option error, yourdigpredates 9.18. Installkdiginstead.
The output looks like plain dig output with two extra tells: a ;; TLS session (TLS1.3)-... line at the top, and a footer that reads ;; From 1.1.1.1@853(TLS). That footer is the proof the query really left over port 853 encrypted. To see the certificate the resolver presents on port 853:
openssl s_client -connect 1.1.1.1:853 -servername cloudflare-dns.com </dev/null 2>/dev/null \
| grep -E "subject=|issuer=|Verify"subject=C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = cloudflare-dns.com
issuer=C = US, ST = Texas, L = Houston, O = SSL Corp, CN = SSL.com SSL Intermediate CA ECC R2
Verify return code: 0 (ok)The CN = cloudflare-dns.com confirms you are talking to Cloudflare's DoT service, not an interceptor. Verify return code: 0 (ok) means the certificate chain validates against your system trust store. Two caveats: older OpenSSL and the LibreSSL that ships with macOS print the same fields slash-separated (subject=/C=US/ST=California/...), and the issuer changes whenever Cloudflare rotates CAs, so match on the subject CN and the verify code, not the issuer.
nslookup cannot inspect TLS certificates. Use
openssl s_clientas shown above.
Testing DoH#
The JSON-over-HTTPS variant (application/dns-json, a non-RFC extension offered by Cloudflare and Google) is the easiest to test from any HTTP client:
curl -s -H 'accept: application/dns-json' \
'https://cloudflare-dns.com/dns-query?name=cloudflare.com&type=A'{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [{"name": "cloudflare.com", "type": 1}],
"Answer": [
{"name": "cloudflare.com", "type": 1, "TTL": 295, "data": "104.16.133.229"},
{"name": "cloudflare.com", "type": 1, "TTL": 295, "data": "104.16.132.229"}
]
}(The live response arrives as a single unformatted line; it is pretty-printed here. The TTL is the resolver's cache countdown, so your number will differ on every run.)
"AD": true means the answer was DNSSEC-validated by the resolver. See dnssec for what that means.
For the wire-format standard (RFC 8484 application/dns-message), use kdig:
kdig @1.1.1.1 +https=/dns-query cloudflare.comnslookup cannot send queries over DoH. Use
curlorkdigas shown above.
On Windows 11 and Windows Server 2022+, DoH is an OS-level setting, configured per network interface and only for resolvers on the system's known-DoH-server list (Get-DnsClientDohServerAddress shows the list, Add-DnsClientDohServerAddress extends it; see Microsoft's DoH client docs). There is no built-in one-off command that points a single query at an arbitrary DoH endpoint, so to test a specific DoH server from Windows use curl (bundled since Windows 10 1803) or kdig as shown above.
Testing DoQ#
kdig also speaks DoQ when built with QUIC support (the Debian/Ubuntu package is):
kdig @9.9.9.9 +quic example.comThe first output line reads ;; QUIC session (QUICv1)-(TLS1.3)-... and the footer ;; From 9.9.9.9@853(QUIC), confirming the transport. Quad9 enabled DoQ across its network in March 2026; AdGuard DNS (94.140.14.14) and Control D also answer DoQ. Cloudflare 1.1.1.1 and Google 8.8.8.8 do not serve DoQ as of mid-2026 (a +quic query to either fails with ;; ERROR: failed to query server).
What encrypted DNS does not do#
- Records are still public. dnssec handles authenticity; encrypted DNS handles query privacy. Neither makes records confidential.
- Your destination IP is still visible to anyone on the wire. TLS SNI (until ECH is universally deployed, see HTTPS/SVCB records), TCP destination IP, and the size and timing of packets all leak information even when the query contents are encrypted.
- The resolver still sees every query you make. Encrypted DNS moves trust from the on-path network to the resolver operator.
- It only encrypts the stub-to-recursive hop. The recursive-to-authoritative hop is still plaintext UDP/TCP unless Authoritative DNS over TLS (ADoT) is in use, which is rare in production today.
So encrypted DNS protects you from your ISP, captive portals, and on-path observers seeing the names you look up. It does not hide the existence of the connection or its destination.
When to use which#
- DoH: the only one that blends with browser traffic on port 443. Works on corporate networks that allow web traffic but block port 853. Hardest to selectively block without breaking the web.
- DoT: the cleanest separation for stub-to-recursive on a server or appliance. Easier to inspect and monitor at the network layer if you control the network and want to allow encrypted DNS but log its existence.
- DoQ: newer, runs over QUIC (UDP/853), allows 0-RTT after the first session. Adoption is growing: Quad9 enabled it network-wide in 2026, AdGuard and Control D have deployments, but mainstream OS stub resolvers do not speak it yet.
Which public resolvers support encrypted DNS#
| Endpoint | Plain :53 | DoT :853 | DoH /dns-query | DoQ :853 |
|---|---|---|---|---|
1.1.1.1 (Cloudflare) | yes | yes | yes | no |
8.8.8.8 (Google) | yes | yes | yes | no |
9.9.9.9 (Quad9) | yes | yes | yes | yes |
DoH endpoints typically have a friendlier hostname: cloudflare-dns.com, dns.google, dns.quad9.net. The hostname matters for TLS certificate validation; the IP is what the OS connects to. One caveat: the JSON variant (application/dns-json) is a Cloudflare and Google extra; Quad9's /dns-query speaks only the RFC 8484 wire format.
See also: anatomy-of-a-query · dnssec for the orthogonal authenticity story · HTTPS/SVCB records for ECH and the broader "what TLS still leaks" story · nslookup-and-dig for the baseline tools