Rabbit hole 01: private DNS
|
Reading time: 22 minutes
Copy permalink
Today I went a step further in reclaiming my freedom, and you can too.
Today I'll write about the Domain Name System (DNS), how to self-host your own server, and the advantages, disadvantages, and privacy trade-offs of different ways of resolving Internet hosts.
Problem statement
Your browsing might not be private, and others can decide what you can see and what you cannot while browsing the Internet.
What we learned
DNS, privacy, Internet censorship, DNS over HTTPS, DNS over TLS, Oblivious DNS over HTTPS, ECH
Evolution of the DNS ecosystem and related technologies. How to own your DNS infrastructure with some compromises.
Table of Contents
Summary
- DNS converts
google.cominto an addressable IP address such as142.251.140.238 - Traditional DNS is not encrypted, meaning that an observer on the network path between you and your recursive resolver can see the DNS names you ask for
- Your ISP or DNS resolver, whether its behavior is enforced or influenced by your government or not, can observe your DNS activity and potentially use it for tracking
- A DNS resolver can also refuse, alter, or filter DNS answers, creating one possible censorship mechanism
- Public DNS resolvers can improve performance, availability, and privacy from your ISP (when the client-to-resolver connection is encrypted), but they remain centralized services that you have to trust
- You can make a few changes or own part of your DNS infrastructure, shifting the trust and reducing the number of actors that can decide what you can and cannot resolve
If you only care about my final recommendations, go to Appendix TL;DR
Brief DNS overview
Once upon a time, there was Internet. And so there was DNS, the Domain Name System.
DNS was designed to provide a human-readable naming system for network resources, mapping domain names such as myserver.com to resource records such as IP addresses that computers use to locate and communicate with those resources.
Your device is a stub resolver. It normally asks one recursive resolver. That resolver either has the answer cached or walks the DNS hierarchy: root → TLD → authoritative server.
The following schema shows the different servers involved in a typical resolution:
-
Client → Recursive resolver
- Asks:
www.example.com→ ? - Usually ISP, company, or public DNS.
- Asks:
-
Resolver → Root
- Asks: “Who handles
.com?” - Root returns the
.comTLD servers.
- Asks: “Who handles
-
Resolver → TLD
- Asks: “Who is authoritative for
example.com?” - TLD returns the authoritative nameservers.
- Asks: “Who is authoritative for
-
Resolver → Authoritative nameserver
- Asks: “What is
www.example.com?” - Authoritative server returns the actual record.
- Asks: “What is
This system was designed a long time ago, and its main goal was not protecting users' privacy, but making name resolution work, fast and reliably. Traditional DNS queries and responses are normally sent in plaintext, which means they can be read or modified by networks, ISPs, or anybody able to monitor the relevant transmissions. Even if a website uses HTTPS, the DNS lookup itself is a separate operation and may still be exposed.
This lack of privacy has consequences for surveillance and censorship: whoever can observe or control DNS resolution can learn something about the domains users are trying to reach and can potentially interfere with resolution.
That trade-off — a fast, reliable system that was never built with privacy in mind — is where the practical problems start.
It's always DNS
ISPs and network operators can restrict access to websites by interfering with DNS resolution. This is often done when courts or regulators order domains to be blocked, although DNS is only one of several mechanisms that can be used for Internet censorship.
Public DNS services such as Google's 8.8.8.8 and Cloudflare's 1.1.1.1 made it possible to use a resolver other than the one provided by your ISP. This removed the ISP resolver as the only DNS chokepoint, but it did not remove the concept of a chokepoint.
You would now be trusting Google, Cloudflare, Quad9, or another provider to handle your requests. The question becomes how secure and private those centralized services are. The problem exists in at least two different dimensions:
- How secure the DNS resolution is, including protection against interception, tampering, and forged answers
- How private the DNS resolution is, including who can observe, retain, correlate, or filter your queries
Switching from ISP DNS to a public resolver can therefore change who you trust without eliminating trust.
Public resolvers can themselves be subject to legal orders or provider policies. Google, for example, documents jurisdiction-specific blocking behavior for its Public DNS service. The same general principle has appeared in legal disputes involving other public resolvers.
The lesson is simple: switching from your ISP to 8.8.8.8 or 1.1.1.1 moves the chokepoint. It does not remove it.
All of this shows that, as individuals, we no longer control which publicly available content we can access nor who might keep a record of our browsing activity.
That chokepoint is not just an abstract idea — it maps onto specific points in how DNS resolution actually works. The next section breaks those down.
Threat model
In more precise terms, there are two DNS hops, each with a different privacy problem:
Client ───────────────► Recursive resolver
HOP 1
Recursive resolver ───► Authoritative DNS
HOP 2
Hop 1: Client → Recursive
We want to protect:
DNS queries from on-path observers such as ISPs or local networks The association between our identity and our queries at the recursive resolver
DoH, DoT, and DoQ encrypt the first part. ODoH addresses the second by separating the client's identity from the DNS request.
Hop 2: Recursive → Authoritative
We want to reduce or protect:
DNS information disclosed to authoritative servers — QNAME minimization reduces unnecessary disclosure DNS traffic from passive observers — encrypted recursive-to-authoritative transport can protect it where supported DNS answer authenticity and integrity — DNSSEC protects against forged or modified DNS data
We are not trying to achieve perfect anonymity. The goal is to control which party can see which information and reduce the number of parties we need to trust.
The rest of this post walks through the technologies that address each of these hops, and how they combine into a setup you can run and own yourself.
Technologies and ideas around DNS
Evolution
In a simplified way, this is the timeline of the DNS scene as new concepts and RFCs appeared over time:
-
DNS (the baseline)
- Plaintext and unauthenticated, usually resolved by whatever your ISP hands you
-
Public DNS resolvers
- Public recursive resolvers allowed you to use an alternative to your ISP
- Anycast deployments can provide low-latency access from many locations
- Providers advertise different combinations of speed, availability, privacy, filtering, and logging policies
-
DNSSEC
- Adds cryptographic signatures so a validating resolver can verify the authenticity and integrity of DNS data
- DNSSEC does not encrypt DNS queries or hide which names are being queried
-
QNAME minimization
- Limits DNS query disclosure by sending only the minimum required domain labels to each authoritative nameserver, rather than the full QNAME
-
DNS over TLS (DoT) / DNS over HTTPS (DoH) / DNS over QUIC (DoQ)
- Encrypt DNS traffic between a DNS client and its resolver
- DoT uses TLS over TCP
- DoH transports DNS inside HTTPS
- DoQ transports DNS over QUIC
-
Oblivious DNS over HTTPS (ODoH)
stub → relay → target- The DNS request is encrypted before reaching the relay
- The relay knows the source IP but cannot read the DNS request
- The target can read the DNS request but sees the relay's address instead of the client's
-
Unilateral Opportunistic Deployment of Encrypted Recursive-to-Authoritative DNS
- Allows recursive resolvers to opportunistically use encrypted transport when communicating with authoritative servers
- Falls back when encrypted transport is unavailable
DNS over HTTPS / DNS over TLS
Paraphrasing Cloudflare DNS article (highly recommended):
Think of a normal, unencrypted DNS query as being like a postcard sent through the mail: anyone handling the mail may happen to catch a glimpse of the text written on the back side, so it is not wise to mail a postcard that contains sensitive or private information.
DNS over TLS and DNS over HTTPS are two standards developed for encrypting plaintext DNS traffic in order to prevent malicious parties, advertisers, ISPs, and others from being able to interpret the data. Continuing the analogy, these standards aim to put an envelope around all postcards going through the mail, so that anyone can send a postcard without worrying that someone is snooping on what they are up to.
Basically, DNS over TLS (DoT) and DNS over HTTPS (DoH) both encrypt your DNS lookups, making it harder for others to see, change, or fake the DNS traffic between your device and the resolver.
- DoT: TCP/853 by default. Its traffic is clearly distinguishable as DNS over TLS, which can make network policy and blocking straightforward.
- DoH: normally HTTPS over port 443. Because it uses HTTPS, it can be harder to distinguish from ordinary web traffic.
- DoQ: QUIC over UDP/853 by default. It provides encrypted DNS transport using QUIC and is useful where QUIC's transport characteristics are advantageous.
- DoT vs. DoH: neither is universally “better.” DoT is easier for network administrators to identify and control as a distinct DNS protocol; DoH blends more naturally with ordinary HTTPS traffic.
- All three: encrypt the DNS traffic in transit, but none of them hides the query from the recursive resolver receiving it.
DoH and DoT therefore solve a very specific problem: they protect the path to the resolver. They do not make the resolver blind to your DNS requests.
More information: Cloudflare DNS Article
Oblivious DNS over HTTPS
Oblivious DNS over HTTPS (ODoH) takes the privacy of DoH one step further: it separates your identity from your request so that no single party has access to both pieces of information at the same time.
With normal DoH, your DNS provider can still see “this IP address asked for this website.” The connection is encrypted, but the resolver terminates that encrypted connection and therefore sees both the client IP and the DNS query.
ODoH separates those two pieces of information. Your device encrypts the DNS request for the target resolver, then sends it through a relay. The relay can see your IP address, but cannot read the DNS request. The target can read the request, but sees the relay's address instead of yours.
The relay is therefore essential: ODoH needs both an ODoH relay and an ODoH target. They are designed so that neither one alone can see both your identity and your DNS queries.
ODoH is defined in RFC 9230, published in 2022. It is an Experimental RFC rather than an Internet Standards Track specification.
ODoH only provides its split-trust property when the relay and target do not collude or share enough information to reconstruct the association. If both parties are operated by the same organization, or their logs are combined, the privacy benefit can disappear.
A global/passive observer can still potentially correlate traffic patterns even though the relay and target individually cannot see both pieces of information.
Designing a private DNS infrastructure
We start with the original DNS concept. The main problems are:
- Plaintext transport
- Not secure
- Usually controlled by your ISP
- Centralized recursive resolution
- Not private
- The resolver can see your queries and can associate them with your client
- Coercively constrained
- The resolver can potentially filter or alter the answers it gives you (legal requirements)
Then we introduced public DNS services offered by large companies through globally distributed Anycast networks. These can provide better performance, availability, and an alternative to ISP-controlled resolution. We still have some important trust and privacy problems:
- Plaintext transport
- Centralized recursive resolution
- Not private (unverifiable privacy claims)
- The resolver can see your queries and can associate them with your client
- The provider's policies and retention practices must be trusted
- Coercively constrained
- The resolver can potentially filter or alter the answers it gives you (legal requirements)
So we add DoH/DoT/DoQ, adding encryption to the client-to-resolver path. We still have:
- Centralized recursive resolution
- Not private (unverifiable privacy claims)
- The resolver can see your queries and can associate them with your client
- The provider's policies and retention practices must be trusted
- Coercively constrained
- The resolver can potentially filter or alter the answers it gives you (legal requirements)
So we configure ODoH, separating our identity from our request so that the relay and target do not individually have the complete picture. We still have:
- Centralized relay and target infrastructure
- Dependence on the relay and target not colluding
- Dependence on the target to provide correct DNS answers
At this point, the three issues boil down to one common obstacle: the centralized servers.
It is tempting to think that we can simply run our own recursive resolver and remove the public recursive resolver from the equation.
And we can.
A self-hosted recursive resolver can perform iterative resolution directly against the DNS hierarchy. It does not have to forward every query to another recursive resolver.
The pool of valid options so far:
- Forward queries to one or more public recursive resolvers while maintaining our own cache
- Use ODoH and separate our identity from the recursive resolver
- Resolve names ourselves by talking directly to root, TLD, and authoritative servers
Each option has a different trade-off.
Option #1: multiple recursive resolvers
Our server can query different recursive resolvers while maintaining a local cache.
No single public resolver necessarily gets our entire history, but our own server internet provider could still see our queries, unless DoH is used with each query. Each upstream resolver can also see the queries it receives from our server. Plus they are still vulnerable to attacks or changes of their terms and conditions that can compromise our privacy.
This distributes trust, but it does not provide cryptographic unlinkability. Correlation is still possible. No real strong anonymity.
Option #2: ODoH
We can accept the trade-offs and use ODoH.
Our self-hosted server becomes a local DNS proxy/forwarder. It can send the request through an ODoH relay to a target recursive resolver.
The relay sees our source IP but not the query. The target sees the query but sees the relay rather than our source IP.
This gives the strongest identity/query separation of the three approaches, but we now depend on the relay and target maintaining the separation.
Option #3: recursive resolution ourselves
We can configure our server to resolve domain names directly by walking the DNS hierarchy.
The source servers are the root, TLD, and authoritative DNS servers. These are distributed across many independently operated organizations and are not consumer recursive resolvers whose job is to maintain a user's query history. Though they can still see the source IP of your recursive resolver.
This approach gives us the most ownership, but it introduces another problem: the recursive-to-authoritative path.
After our resolver has the question, it still has to walk:
root → TLD → authoritative
That walk has traditionally used ordinary DNS transport. Plaintext recursion still exposes names to the network in front of your resolver. DoH, DoT, and ODoH were primarily designed for the first hop, from the client to a recursive resolver.
ODoH cannot simply be aimed at a root server: an ODoH target is a recursive DNS service, while root and TLD servers are authoritative servers.
A normal NS record gives us names and addresses for authoritative servers, not a DoH URL. A recursive resolver therefore cannot simply assume that the other side speaks HTTPS.
The recursive-to-authoritative hop has its own mechanisms, including DoT and DoQ. Most authoritative servers, however, still support traditional DNS on port 53, and a resolver cannot require encrypted transport from every authoritative server without risking failed resolutions.
This is where RFC 9539, Unilateral Opportunistic Deployment of Encrypted Recursive-to-Authoritative DNS, comes in.
RFC 9539 is the pragmatic workaround: a resolver can probe for encrypted DNS transport and use it when the authoritative server supports it, while retaining the ability to use ordinary DNS when it does not.
But that's the catch.
Opportunistic encryption does not mean encryption is guaranteed.
An active attacker can interfere with the encrypted connection attempt and cause the resolver to fall back to ordinary DNS. RFC 9539 primarily improves protection against passive monitoring; it does not provide robust protection against active attackers.
The resolver also cannot assume that every authoritative server on the Internet has upgraded. The RFC is designed around unilateral adoption: operators can deploy it without requiring the entire DNS ecosystem to coordinate first.
A few root-server operators have experimented with encrypted transport, but there is still no guarantee that a complete resolution path from root through TLD to authoritative server will be encrypted.
The point of RFC 9539 is therefore not “DNS is now encrypted end to end.” It is a phased rollout that allows encryption where possible without breaking resolution where it is not.
That leaves us with an important trade-off.
We can recurse ourselves and accept that some recursive-to-authoritative queries may still be visible on the wire.
Or we can forward with ODoH and let someone else perform the recursive work while separating our identity from the queries.
The setup below does the second.
Final setup and future
We need:
- A way to prevent our ISP or local network from reading our DNS requests
- A way to prevent the public recursive resolver from directly associating those requests with us
We can fulfill these requirements with ODoH.
We still need both a relay and a target recursive service that we trust to provide correct answers and respect the intended privacy separation. That is the compromise.
The advantage is that we can change the relay or target if we stop trusting our current choice.
My final setup looks like this:
Client
│
│ DoH
│
▼
Self-hosted DNS
proxy / forwarder
│
│ ODoH
│
▼
Relay
│
│ ODoH
│
▼
Global Public DNS
Recursive Resolver
│
│ DNS query (mostly plaintext DNS, maybe RFC 9539)
│
├── 1. Root ──────► "Which TLD?"
│ │
│◄───────────────────┘
│
├── 2. TLD ───────► "Which authoritative server?"
│ │
│◄───────────────────┘
│
└── 3. Authoritative
───────────► "Here is the final IP"
◄───────────┘
The self-hosted component in this setup is not doing the recursive walk itself. It is providing local control over the DNS client side and forwarding the request through ODoH.
Who can see what?
The goal of the final architecture is not to make every component blind, but to split the information between them.
| Participant | Our IP | DNS query |
|---|---|---|
| Local network / ISP | Yes | Not normally, if the client connection is encrypted |
| Self-hosted proxy | Yes | Yes |
| ODoH relay | Yes | No |
| ODoH target / recursive resolver | No — sees the relay | Yes |
| Authoritative DNS | No — sees the recursive resolver | Yes, for the names it receives |
The key ODoH property is:
Relay → knows who is asking, but not what they ask
Target → knows what is being asked, but not who originally asked
The self-hosted proxy is not part of this anonymity boundary: it can see both the client and the DNS request. Its purpose is to provide local control and forward the request through ODoH.
This separation depends on the relay and target not colluding or combining their information.
Bonus - ECH and RFC 9849
While researching ISP censorship, I came across another technique networks can use to restrict access to websites. It's called SNI / domain-based blocking.
Encrypted DNS only hides the lookup. The browser then opens a TLS connection to an IP address. Without ECH, the TLS ClientHello can expose the hostname through SNI.
A network that never saw the DNS query can therefore still learn the hostname and potentially block it.
ECH, defined in RFC 9849, encrypts the relevant TLS ClientHello information so that the hostname is no longer exposed to an on-path observer in the same way.
ECH does not hide the destination IP, does not replace DNS encryption, and requires support from both the client and the server.
The practical stack is therefore layered:
- Encrypted DNS hides the DNS question from the network path to the resolver
- QNAME minimization reduces the DNS information disclosed to authoritative servers
- DNSSEC protects the authenticity and integrity of DNS data, but does not encrypt it
- ECH hides the TLS hostname when supported
- HTTPS encrypts the HTTP content
- A VPN or similar tunnel can hide the destination IP from the local network, but moves that visibility to the VPN provider
None of these mechanisms alone provides complete anonymity. They solve different parts of the problem.
Appendix 1 - TL;DR
For maximum privacy and ownership:
- No solution exists end to end
- You must choose which parties you trust and which information each party can see
For not-so-strong privacy and full ownership:
- Self-host your own recursive DNS service with:
- DNSSEC
- QNAME minimization
- Opportunistic encrypted recursive-to-authoritative transport where supported
- Direct resolution against root/TLD/authoritative servers
- Point your OS/browser/VPN to it (see NOTE)
- Accept that recursive-to-authoritative traffic may still use plaintext DNS when encrypted transport is unavailable
- Your local network can see that your server is communicating with DNS infrastructure, but cannot necessarily see the DNS names if the relevant encrypted transport is used
- Authoritative servers can see the recursive resolver's source IP
For strong privacy and some ownership:
- Self-host your own DNS proxy/forwarder with:
- DoH or DoT from the client to your server
- DNSSEC validation where appropriate
- QNAME minimization if the upstream resolver supports/uses it
- Opportunistic encrypted recursive-to-authoritative transport where supported
- ODoH to a relay and recursive target operated independently
- Point your OS/browser/VPN to it (see NOTE)
- You depend on the relay and recursive target
- The privacy property depends on them not colluding or combining their logs
For convenience:
- Encrypt the client-to-resolver hop
- Expect that jurisdictional blocks can still exist
- Read the provider's logging and privacy policy
- Prefer operators that publish meaningful transparency information
- Choose a public DNS service with features that match your threat model, such as:
- Limited retention
- Anonymization
- Ad Blocking
- DNSSEC
- DoH/DoT
- (optionally) ODoH, but you will need find a relay too
- Some examples are:
- Quad9
- Cloudflare
Mullvad DNS- Numa (relay only)
- Point your OS/browser/VPN to it (see NOTE)
Note
Point your OS/browser/VPN to it:
- Configure encrypted DNS at the layer that actually performs DNS resolution.
- If your operating system supports system-wide DoH or DoT, configure it there.
- Alternatively, configure a browser's DoH settings (better if it supports ODoH)
- (optionally) Configure your VPN server to use those specific DNS servers See technical section on this post for steps on your operating system and browser.
Tip
Some open source, self-hosted options for DNS resolvers and DNS clients:
Not having encrypted DNS at the operating-system level means applications may use whatever DNS configuration is available to them, which might be plaintext. Browser DoH, a local stub (stubby, dnscrypt-proxy, Numa), or a VPN DNS setting can still encrypt.
Not having DoH configured in your browser means every webpage you visit with it will hit the DNS set by default, usually inherited from the operating system's resolver configuration, which might be plaintext.
Not having server ownership means your DNS requests will go through someone else's service. That service may or may not be private, may or may not log activity, and may be subject to filtering, legal orders, or other policies.
Appendix 2 - DoT and DoH implementation
Use system-wide encrypted DNS where your operating system supports it; use browser settings if it cannot inherit secure/private configuration from your operating system.
The exact menus vary by OS version.
| Platform | Protocol | High-level setup |
|---|---|---|
| macOS 13+ | DoT | Install/create a DNS Settings configuration profile with DNSProtocol = TLS, your resolver IP(s), and its TLS hostname. macOS supports DoT natively. |
| Linux | DoT | Use systemd-resolved if available: configure a resolver with DNS= and DNSOverTLS=yes, then restart/enable systemd-resolved. Alternatively use stubby or dnscrypt-proxy. |
| Windows 11 | DoT | Don't use Windows' built-in encrypted DNS for DoT; current Windows settings are for DoH. For DoT, use a local resolver such as cloudflared, stubby, or another DoT-capable client, then point Windows DNS at 127.0.0.1. |
| iOS 16+ | DoT | Install a DNS configuration profile/app that uses Apple's DNS Settings framework with DNSProtocol = TLS, server IP(s), and ServerName. iOS supports system-wide DoT. |
| Android 9+ | DoT | Settings → Network & Internet → Private DNS → Private DNS provider hostname → enter your resolver's DoT hostname → Save. |
| Firefox | DoH | Settings → Privacy & Security → DNS over HTTPS → Advanced settings → choose Custom or Max Protection → select/enter your DoH provider. |
| Chrome | DoH | Settings → Privacy and security → Security → Use secure DNS → enable → choose current provider or custom provider. |
System-level and browser-level encrypted DNS are not mutually exclusive. If a browser is configured to use its own DoH service, it may bypass the operating system's DNS configuration for its own queries.
If you want strict encryption, disable plaintext fallback where the relevant implementation offers that option. Be aware that some automatic encrypted-DNS modes intentionally fall back to ordinary DNS when the secure resolver cannot be reached.
Some examples
For Cloudflare:
DoT hostname: cloudflare-dns.com / one.one.one.one / 1dot1dot1dot1.cloudflare-dns.com
IPv4: 1.1.1.1
1.0.0.1
DoH URL: https://cloudflare-dns.com/dns-query
For Quad9:
DoT hostname: dns.quad9.net
IPv4: 9.9.9.9
149.112.112.112
DoH URL: https://dns.quad9.net/dns-query
Important distinction
- DoT: an encrypted DNS transport using TLS. It can be configured at the operating-system level, through a local DNS client, or by other software.
- DoH: an encrypted DNS transport using HTTPS. It can also be configured at the system level, through a local client, or directly by a browser.
- A browser using its own DoH configuration can bypass the operating system's DNS configuration.
- An operating system using encrypted DNS can protect DNS queries generated by applications that use the system resolver.
Resources
-
Basic DNS
-
DNS Security and Privacy Foundations
-
Encrypted DNS Transport
-
Oblivious DNS
-
Related Privacy Technology
UPDATE 1 (05/09/2026) Mullvad DNS shutdown