DNS over HTTPS (DoH) encrypts your DNS queries, but the most surprising thing is that it doesn’t actually make your internet browsing faster.

Let’s see DoH in action. Imagine you’re on a Linux machine and you want to use Cloudflare’s DoH resolver at 1.1.1.1. You’d typically edit your /etc/resolv.conf. But with DoH, that file is just a pointer. You need a local DNS stub resolver that can speak DoH. systemd-resolved is a common one.

Here’s a typical /etc/resolv.conf on a system using systemd-resolved:

nameserver 127.0.0.53
options edns0 trust-ad
search example.com

The key is 127.0.0.53. That’s systemd-resolved listening locally. Now, we configure systemd-resolved to use DoH. This is done via resolved.conf. On most systems, this file is located at /etc/systemd/resolved.conf.

Here’s how you’d configure it to use Cloudflare’s DoH endpoint:

[Resolve]
DNS=1.1.1.1 1.0.0.1
FallbackDNS=8.8.8.8 8.8.4.4
DNSOverTLS=yes
# Or for DNS over HTTPS:
# DNSSEC=yes
# DNSServer=https://cloudflare-dns.com/dns-query

Wait, I showed DNSOverTLS=yes and then commented it out to show DNSServer=https://cloudflare-dns.com/dns-query. That’s because systemd-resolved supports both DNS over TLS (DoT) and DoH, but you typically pick one. For DoH, you specify the DoH endpoint URL.

After saving resolved.conf, you need to restart systemd-resolved:

sudo systemctl restart systemd-resolved

And to ensure your changes are applied, you might need to re-enable it:

sudo systemctl enable systemd-resolved

Now, when your applications perform a DNS lookup, they send it to 127.0.0.53. systemd-resolved intercepts this, and instead of sending a plain DNS query to the upstream server, it packages the query into an HTTPS request and sends it to https://cloudflare-dns.com/dns-query. The response comes back over HTTPS, is decrypted by systemd-resolved, and then given to your application.

The mental model is this: your system’s DNS client (like your browser or systemd-resolved) doesn’t talk directly to the internet’s DNS servers anymore. It talks to a local resolver (systemd-resolved in this case), which then acts as a client to a specialized DoH/DoT server. This local resolver handles the translation from standard DNS to DoH/DoT.

What problem does this solve? Primarily, it prevents your ISP, or anyone else on your local network, from seeing which websites you’re looking up. With traditional DNS, your query goes out in plaintext. With DoH, it’s wrapped in HTTPS, making it indistinguishable from regular web traffic to an observer. It also helps protect against DNS spoofing.

The exact levers you control are the upstream DoH resolver URL and the fallback DNS servers. You can choose providers like Cloudflare (https://cloudflare-dns.com/dns-query), Google (https://dns.google/dns-query), or Quad9 (https://dns.quad9.net/dns-query).

Most people think DoH is just about privacy. But the real power is in preventing DNS hijacking and ensuring you’re getting DNS responses from a trusted source, especially when you’re on untrusted networks like public Wi-Fi. The fact that it looks like normal HTTPS traffic means middleboxes can’t easily block or interfere with your DNS queries based on their content.

The next concept you’ll run into is how to verify that DoH is actually working, and how to troubleshoot when it isn’t.

Want structured learning?

Take the full Dns course →