Module 2 · Lesson 6
DNS over HTTPS (DoH) and DNS over TLS (DoT)
⏱ 10 min read
DNS over HTTPS (DoH) and DNS over TLS (DoT)
Every DNS query you send travels in plaintext. Your ISP sees it. Any network observer between you and your resolver sees it. The coffee shop router sees it. Historically, this was considered acceptable: DNS answers aren't secrets, you'd argue. But the query metadata absolutely is — it reveals every site you visit, before TLS comes into play.
DNS over HTTPS (RFC 8484, 2018) and DNS over TLS (RFC 7858, 2016) encrypt DNS queries. The mechanics differ; the goal is the same: your ISP shouldn't get a free browsing history from your DNS traffic.
This is good. It also created real operational problems. Here's both sides.
The Privacy Problem Being Solved
Plain DNS over UDP port 53 has no privacy:
User → ISP resolver → authoritative servers
[plaintext] [plaintext]
Your ISP can log every query. They sell this data in some jurisdictions. More immediately: any on-path attacker can read, modify, or block specific DNS responses. An attacker on a public WiFi network can serve you forged DNS responses for any domain.
Encrypted DNS fixes this at the transport layer: the query content is encrypted between you and your resolver. The ISP sees that you're talking to 1.1.1.1 on port 853 (DoT) or 443 (DoH), but not what you're asking.
DoT: DNS over TLS
DoT runs DNS over a TLS connection on port 853. The protocol is the same wire format as regular DNS (RFC 1035) but wrapped in TLS.
Set up a local DoT-enabled resolver (Unbound):
# unbound.conf
server:
interface: 0.0.0.0@853
tls-service-key: "/etc/unbound/server.key"
tls-service-pem: "/etc/unbound/server.pem"
tls-port: 853
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 8.8.8.8@853#dns.google
Test DoT connectivity:
# Using kdig (knot-dnsutils)
kdig -d @1.1.1.1 +tls-ca +tls-host=cloudflare-dns.com example.com A
# Using curl (DoH)
curl -s -H 'accept: application/dns-json' 'https://1.1.1.1/dns-query?name=example.com&type=A'
DoH: DNS over HTTPS
DoH encodes DNS queries as HTTP/2 or HTTP/3 requests to a well-known URL (/dns-query). The query is either a GET request (base64url-encoded in the URL) or a POST with application/dns-message content type.
This is cleverer than it sounds. DoH traffic is indistinguishable from regular HTTPS at the network level. Port 443, same TLS patterns. You can't selectively block DoH without breaking HTTPS generally, unless you block known DoH endpoints specifically.
This is also exactly why enterprises hate it.
How Browsers Implement DoH
Firefox was first to ship DoH at scale (2019), using Cloudflare as the default DoH provider in the US. The feature is called Trusted Recursive Resolver (TRR). It sends DNS queries to Cloudflare's DoH endpoint instead of the system resolver.
This created an interesting split: Firefox users in the US had their DNS going to Cloudflare; everything else on the system (OS, other apps) went to the ISP resolver. Your OS and your browser could be using different DNS.
Chrome implements DoH as "Secure DNS" and will upgrade to DoH if your current resolver is on its list of known DoH-capable providers. It stays with your configured resolver — just upgrades the transport. More conservative than Firefox's approach.
Configuration (Firefox about:config):
network.trr.mode = 2 (prefer DoH, fallback to system)
network.trr.mode = 3 (DoH only)
network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query
The Problems DoH/DoT Introduce
Centralization
Before DoH: DNS was distributed. Every ISP had resolvers. Enterprises ran their own. Academic institutions ran their own. The DNS ecosystem had hundreds of major resolver operators.
After DoH: A significant fraction of global DNS queries now go to Cloudflare (1.1.1.1) and Google (8.8.8.8). Mozilla's default DoH provider is Cloudflare. Apple's DNS private relay goes through Apple-operated infrastructure. Android's Private DNS defaults to whatever the manufacturer configures.
This is a meaningful centralization risk. It trades ISP visibility for resolver visibility. Cloudflare can now see query patterns for a substantial chunk of the internet. They have a privacy policy, and so far they've behaved well, but concentration of infrastructure is an architectural concern.
Bypassing Corporate DNS Controls
Enterprise DNS is used for more than name resolution:
- Security filtering (blocking malware C2 domains)
- Monitoring (detecting suspicious query patterns)
- Captive portal support
- Internal name resolution (corp.internal, etc.)
DoH bypasses all of this if an endpoint uses a browser with DoH enabled pointing at an external resolver. Your corporate Palo Alto or Cisco Umbrella deployment becomes irrelevant for Firefox traffic.
IT and security teams have responded by blocking known DoH endpoints or forcing DNS over their own infrastructure. It's a constant cat-and-mouse game.
Endpoint Trust
With plain DNS, your ISP resolver is your trust anchor. It might be untrustworthy, but it's a known quantity. With DoH/DoT, you're choosing to trust a specific resolver operator. If Cloudflare has a bad day, or if your DoH client trusts a certificate it shouldn't, your DNS is broken or compromised.
The Honest Assessment
DoH and DoT are net positives for consumer privacy on public networks. Encrypting DNS queries prevents ISP surveillance, on-path eavesdropping, and trivial DNS injection attacks.
The centralization problem is real and not fully solved. The enterprise control bypass problem is a genuine operational headache.
For your own infrastructure:
- Run your own DoT resolver if you want privacy without giving your queries to a third party
- In enterprise environments, enforce DNS through your own infrastructure and block external DoH endpoints if compliance requires it
- On personal devices: 1.1.1.1 (Cloudflare) or 8.8.8.8 (Google) DoT/DoH is better than plain ISP DNS in most threat models
Run Your Own DoT Resolver
The cleanest answer to "I don't want Cloudflare seeing my queries" is to run your own validating resolver with DoT to upstream forwarders:
# Unbound with DoT upstream (Debian/Ubuntu)
apt install unbound
# /etc/unbound/unbound.conf
server:
verbosity: 1
interface: 127.0.0.1
port: 53
do-ip4: yes
do-udp: yes
do-tcp: yes
# DNSSEC validation
auto-trust-anchor-file: "/var/lib/unbound/root.key"
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
This gives you: local resolver with DNSSEC validation, encrypted transport to Cloudflare, no plain UDP port 53 on the network.
Key Takeaways
- DNS queries in plain UDP are visible to ISPs, network operators, and on-path attackers. DoH and DoT encrypt the transport.
- DoT uses port 853 with TLS. DoH uses HTTPS on port 443, making it indistinguishable from web traffic.
- Browsers implement DoH independently of the OS resolver, which creates split DNS environments.
- Major DoH providers (Cloudflare, Google) receive a large fraction of global queries — centralization is a structural concern.
- Enterprise DNS controls are bypassed by browser DoH. Block external DoH endpoints if your compliance model requires DNS monitoring.
- Running your own validating resolver with DoT upstream is the best balance of privacy and control.
Further Reading
- RFC 7858: Specification for DNS over Transport Layer Security (TLS)
- RFC 8484: DNS Queries over HTTPS (DoH)
- Mozilla's DoH/TRR policy: https://wiki.mozilla.org/Trusted_Recursive_Resolver
- IETF DPRIVE working group: https://datatracker.ietf.org/wg/dprive/about/
- Cloudflare's 1.1.1.1 privacy policy: https://www.cloudflare.com/privacypolicy/
Up Next
Lesson 07 puts it all together: a concrete, production-ready checklist for securing DNS infrastructure. No vague advice — specific settings, commands, and monitoring.