DoT (DNS over TLS)
DNS over TLS (DoT) carries ordinary DNS messages inside a TLS connection on TCP port 853, per RFC 7858 as updated by RFC 8310. It encrypts only the stub-to-resolver hop, so it is not end-to-end, gives no answer integrity, and your resolver still sees every query.
Also known as DNS over TLS, DNS-over-TLS.
Full Explanation
DNS over TLS (DoT) encrypts DNS lookups. It carries ordinary DNS messages inside a TLS connection on TCP port 853. This replaces cleartext UDP or TCP port 53. RFC 7858 (2016) specifies DoT. RFC 8310 (2018) updates it and generalises its usage profiles. DoT is not end-to-end encryption. RFC 7858 scopes it to traffic between stub clients and recursive servers. So the resolver you point at still sees every query in the clear. It is not DoH (DNS over HTTPS). DoH is the sibling protocol that carries the same queries in HTTP on port 443. DoT is also not DNSSEC. TLS protects the channel, not the answer. DoT sits on its own port. That makes it trivial to identify. An administrator can police it easily, and a network can block it just as easily.
How it works
A DoT client, either a stub resolver or a forwarder, opens a TCP connection to port 853 on its resolver. RFC 7858 section 3.1 requires a server that supports DoT to listen there by default. It also forbids cleartext on that port: “DNS clients MUST NOT send and DNS servers MUST NOT respond to cleartext DNS messages on any port used for DNS over TLS”. The first data exchange on the connection must be the TLS handshake. The client then authenticates the server if its profile requires it, since section 3.2 explicitly allows a client to choose not to authenticate the server. RFC 8310 defines the mechanism now in general use. The client is configured with an authentication domain name, for example dns.google. It verifies the entire certification path. Then it matches that name against the certificate’s subjectAltName extension.
Inside the session the DNS wire format is unchanged. Every message keeps the two-octet length field of DNS-over-TCP (RFC 7858 section 3.3). This is the concrete difference from DoH. RFC 8484 section 6 notes that its media type omits “the format defined in Section 4.2.2 of [RFC1035] that includes two length bytes”. Clients should pipeline multiple queries over one session and match replies by Message ID. Both ends should reuse an existing connection rather than close it after each response. DoT assumes long-lived, idle-tolerant connections. RFC 8310 section 9 sets the crypto floor: “DNS clients and servers MUST implement only (D)TLS 1.2 or later”. It also bans TLS compression. Stateless session resumption is mandatory.
RFC 8310 section 5 restates the profiles as two outcomes a user can reason about. Under Strict Privacy, “the DNS client requires both an encrypted and authenticated connection to a privacy-enabling DNS server. A hard failure occurs if this is not available.” Under Opportunistic Privacy, the client tries for the same thing, but it MAY fall back to an encrypted but unauthenticated connection, and eventually to cleartext, in order to obtain a response. A client MUST NOT drop from Strict to Opportunistic during the resolution of a given query (section 5.1).
In practice that profile is one switch in a system resolver. In systemd-resolved, DNSOverTLS takes yes or opportunistic, and defaults to no. With yes, a hostname supplied as address#server_name validates the certificate and sets SNI. Otherwise, “the certificate is checked against the server’s IP”. In that mode, if the server does not speak DoT, every request fails. In opportunistic mode, its manual warns, “the resolver is not capable of authenticating the server, so it is vulnerable to ‘man-in-the-middle’ attacks”. Because the setting lives in the system resolver, it covers every application on the host. Android’s guidance for apps that ship their own DNS client is that it should either use “encrypted DNS to the same hostname as the system, or is disabled in favor of the system resolver”.
Operating-system support follows that model. Android has secured DNS transport with DoT since SDK level 28 (Android 9), exposed as the Private DNS setting. Android added DNS over HTTP/3 in SDK level 30. So OS-level encrypted DNS is no longer DoT-only. Apple platforms treat it as managed configuration rather than a toggle. The DNSSettings payload is used “to configure DNS over HTTP (also known as DoH) or DNS over TLS (also known as DoT)”. It is available from iOS 14, iPadOS 14, macOS 11 and visionOS 1 onward.
Two later standards remove the need to configure a resolver by hand. Discovery of Designated Resolvers (RFC 9462) publishes a resolver’s encrypted configuration in SVCB records, where a DoT endpoint is designated with alpn=dot. The DHCP and Router Advertisement options of RFC 9463 let a host “learn an Authentication Domain Name together with a list of IP addresses and a set of service parameters to reach such encrypted DNS resolvers”. Note that port 853 is not DoT alone. It is registered to IANA under the service name domain-s (RFC 7858 section 6). TCP 853 is DoT, while UDP 853 is DNS over QUIC (RFC 9250).
Why it matters for a CDN
DNS-based edge selection keys on the address a CDN’s authoritative nameservers see. RFC 7871 states the problem plainly: “the source address is that of the Recursive Resolver rather than of the query originator.” DoT changes neither the DNS wire format nor the resolution path. So it changes none of that arithmetic. A DoT query reaches the same recursive resolver and is forwarded onward exactly as a cleartext one would be.
What DoT changes is which resolver users end up on. That is because turning on encrypted DNS usually means configuring one of a handful of large public resolvers. RFC 7871 warns that this class of resolver “handles query sources that are often not topologically close”. This produces “less than desirable responses from topology-sensitive Authoritative Nameservers”. The mitigation is EDNS Client Subnet (ECS). Resolver policy differs sharply. Google Public DNS re-enabled ECS for its DNS-over-TLS service on 2019/06/27. Cloudflare documents that 1.1.1.1 “does not include client IP information in its queries to authoritative servers” and does not send the ECS header, with one documented debug-domain exception. A user who switches to DoT on 1.1.1.1 therefore leaves your authoritative servers nothing to route on but Cloudflare’s resolver address. The same user on Google’s DoT service still supplies a client subnet. Encrypted DNS and accurate edge selection are compatible, but only where the chosen resolver forwards ECS and the authoritative side honours it.
What CDNs do
- Cloudflare is both a CDN and the operator of 1.1.1.1. It supports DoT on 1.1.1.1, 1.0.0.1 and the corresponding IPv6 addresses (2606:4700:4700::1111 and 2606:4700:4700::1001) on port 853. Clients that cannot take an IP address can reach it by hostname as one.one.one.one. Its DoT endpoint supports TLS 1.3 and TLS 1.2.
- Google Public DNS offers “DNS resolution over TLS-encrypted TCP connections as specified by RFC 7858”. Its authentication domain name is dns.google. It lists TLS 1.3, TCP Fast Open and the DNS-over-TCP implementation requirements of RFC 7766 as supported.
- Quad9 is a Swiss-based non-profit resolver. It supports “DNS over TLS (DoT), DNS over HTTPS (DoH), and DNSCrypt”. Its threat-blocking 9.9.9.9 service also blocks “DNS requests destined for domains associated with malicious intent”.
- The authoritative side is the side a CDN actually runs. RFC 9539 (Experimental, 2024) describes deploying DoT on the recursive-to-authoritative hop unilaterally and without server authentication. RFC 7858 had left this out of scope. The mechanism is optional, but “an authoritative server choosing to implement the protocol described in this document MUST implement at least one of either DoT or DoQ on port 853”. Probing resolvers target TCP port 853 with an ALPN of “dot”. This is the one place where DoT is a CDN-side feature rather than a client setting.
Watch out for
- It is not end-to-end privacy. RFC 7858 covers “queries and responses between stub clients and recursive servers”. The resolver sees every lookup. So does the recursive-to-authoritative hop, unless that is separately encrypted.
- The dedicated port cuts both ways. RFC 7858 already anticipated that “the well-known port might be blocked by some firewalls”. DoH’s advantage here is narrower than it is usually stated. RFC 8484 says port 443 and traffic mixing “can deter unprivileged on-path devices from interfering with DNS operations”. Note the word unprivileged: a network’s own operator is not deterred. Dropping port 853 remains a supported enterprise control.
- Strict mode fails closed by design. “A hard failure occurs” when no encrypted, authenticated connection is available. That is what breaks strict DoT behind captive portals. RFC 7858 section 4.2 notes that web-based login “may rely on DNS interception and spoofing”.
- Opportunistic mode downgrades quietly. systemd-resolved’s manual says the mode “makes DNS-over-TLS vulnerable to ‘downgrade’ attacks, where an attacker might be able to trigger a downgrade to non-encrypted mode”. RFC 8310 notes there is no requirement to notify the user which kind of connection was actually used.
- It adds no answer integrity. RFC 7858 is explicit that “DNSSEC and DNS over TLS are independent and fully compatible protocols, each solving different problems.” A forged answer from upstream arrives encrypted and unverified.
- Setup cost is front-loaded. Against UDP, TCP adds a round trip, and “the TLS handshake adds another two RTTs of latency” in the TLS 1.2 terms of RFC 7858 section 5. TLS 1.3 and resumption cut that, but a client that opens a fresh connection per lookup pays it every time.
Best practice
- Configure an authentication domain name. Run Strict Privacy wherever you can guarantee port 853 egress. RFC 8310 says the Strict profile “SHOULD always be implemented in DNS clients that implement the Opportunistic Privacy profile”.
- Do not assume a bare IP address means no authentication. systemd-resolved with DNSOverTLS=yes checks the certificate against the server’s IP when no address#server_name hostname is given. What actually loses authentication is selecting opportunistic mode, not omitting the hostname.
- Keep DNSSEC validation switched on alongside DoT. DoT hides the lookup from the network path. Only DNSSEC tells you the answer was not forged.
- Reuse the connection. Pipeline queries, keep the session open, and enable the stateless session resumption that RFC 8310 section 9 makes mandatory. This way the handshake is amortised rather than paid per lookup.
- Choose the resolver with edge routing in mind. Pick one topologically close to your users, or one that forwards EDNS Client Subnet. Otherwise your users inherit whatever locality the resolver’s egress address implies.
- Where port 853 is blocked, prefer discovery over falling back to cleartext. RFC 9462 exists for exactly the case where “a client has a DoT configuration for foo.resolver.example.com but is on a network that blocks DoT traffic”. It lets the client find a designated DoH server for the same resolver.
- If you operate authoritative DNS for a CDN, evaluate the opportunistic DoT of RFC 9539 on port 853. It is Experimental and unauthenticated. Treat it as protection against passive observers only, and pad responses as its section 3.5 recommends.
Examples
# Test DoT with kdig (from knot-dns)
kdig @1.1.1.1 +tls example.com A
# Returns standard DNS response over TLS
# Configure systemd-resolved for DoT
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com
DNSOverTLS=yes
sudo systemctl restart systemd-resolved
resolvectl status
# Shows: DNS over TLS: yes
# Configure Unbound for DoT upstream
# /etc/unbound/unbound.conf
server:
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
# Android: Settings > Network > Private DNS
# Set to: one.one.one.one
# Test DoT connectivity
openssl s_client -connect 1.1.1.1:853 \
-servername cloudflare-dns.com 2>/dev/null | \
head -5
# Shows TLS certificate details
Frequently Asked Questions
DNS over TLS (DoT) carries ordinary DNS messages inside a TLS connection on TCP port 853, per RFC 7858 as updated by RFC 8310. It encrypts only the stub-to-resolver hop, so it is not end-to-end, gives no answer integrity, and your resolver still sees every query.
# Test DoT with kdig (from knot-dns)
kdig @1.1.1.1 +tls example.com A
# Returns standard DNS response over TLS
# Configure systemd-resolved for DoT
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com
DNSOverTLS=yes
sudo systemctl restart systemd-resolved
resolvectl status
# Shows: DNS over TLS: yes
# Configure Unbound for DoT upstream
# /etc/unbound/unbound.conf
server:
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
# Android: Settings > Network > Private DNS
# Set to: one.one.one.one
# Test DoT connectivity
openssl s_client -connect 1.1.1.1:853 \
-servername cloudflare-dns.com 2>/dev/null | \
head -5
# Shows TLS certificate details
Yes. DoT (DNS over TLS) is also known as DNS over TLS, DNS-over-TLS. DNS over TLS (DoT) carries ordinary DNS messages inside a TLS connection on TCP port 853, per RFC 7858 as updated by RFC 8310. It encrypts only the stub-to-resolver hop, so it is not end-to-end, gives no answer integrity, and your resolver still sees every query.
Related CDN concepts include:
- DNS (Domain Name System) (DNS) — The distributed, hierarchical naming system that resolves names like example.com to addresses. A query-response lookup …
- TLS (Transport Layer Security) (TLS) — TLS (Transport Layer Security) is the protocol that turns a plain byte stream into a …
- A Record — An A record is the DNS record type that maps a hostname to one 32-bit …
- DoH (DNS over HTTPS) (DoH) — DNS over HTTPS (DoH), defined in RFC 8484, carries each DNS query and answer inside …