Encrypted DNS is one of the cheapest privacy wins available to a sysadmin in 2026 — and one of the most misunderstood. DNS over HTTPS (DoH) seals the resolution traffic inside TLS 1.3 over port 443, indistinguishable on the wire from any other HTTPS flow. This guide is the practical implementation walkthrough for IT operations: what DoH protects (and what it does not), how to deploy it on Windows / Linux / macOS endpoints, on resolvers (unbound, dnsdist), on the network edge with pfSense / OPNsense, plus the monitoring + policy patterns that keep DoH from breaking your existing security tools.
Contents
- What DoH actually protects against
- Picking a DoH provider — or self-hosting
- Windows 10/11 endpoints
- Linux endpoints (systemd-resolved + stubby)
- macOS endpoints (configuration profile)
- DoH on your own resolver (unbound + dnsdist)
- Edge enforcement on pfSense / OPNsense
- Monitoring and the legitimate-bypass case
- Pitfalls and rollback
- FAQ
What DoH actually protects against
DoH protects against three concrete leaks. On-path observation: cafe Wi-Fi, hotel networks, hostile ISPs can no longer see which hostnames a client resolves. Off-path query injection: a forged DNS reply at the captive portal level is no longer cheap because the attacker needs to compromise the TLS session. Pervasive monitoring: ISPs that monetised plaintext DNS for analytics now see a single Cloudflare or Google IP and a TLS handshake.
DoH does not protect against three things people mistakenly think it does. It does not hide the destination — TCP SYN packets and SNI still expose the IP and host you connect to immediately after the lookup. It does not hide queries from the DoH provider — Cloudflare, Google, NextDNS see every query you send them. And it does not encrypt the data plane — only the resolution lookup is sealed; the actual HTTPS connection that follows is independent.
Picking a DoH provider — or self-hosting
| Provider | Endpoint | Notable trait | Logging policy |
|---|---|---|---|
| Cloudflare | https://cloudflare-dns.com/dns-query | Fastest globally, 1.1.1.1 family | 24-hour scrubbed, audited |
| Quad9 | https://dns.quad9.net/dns-query | Malware filtering by default | No logs (advertised) |
| NextDNS | https://dns.nextdns.io/<id> | Per-profile filtering UI | User-configurable |
| AdGuard | https://dns.adguard-dns.com/dns-query | Ad-block by default | No logs (advertised) |
| Self-hosted | https://dns.example.com/dns-query | You control the entire chain | What you decide |
For corporate use, the cleanest answer is usually self-hosted DoH in front of an internal recursive resolver — your queries never leave the network and DoH still gives you the on-path protection.
Windows 10/11 endpoints
Windows ships native DoH support since Windows 10 21H2 and Windows 11 22H2. Either UI (Settings → Network → DNS settings → Encryption Only) or PowerShell.
Set-DnsClientDohServerAddress `
-ServerAddress 1.1.1.1 `
-DohTemplate 'https://cloudflare-dns.com/dns-query' `
-AllowFallbackToUdp $false `
-AutoUpgrade $true
Set-DnsClientServerAddress -InterfaceAlias 'Ethernet' -ServerAddresses 1.1.1.1, 1.0.0.1
Get-DnsClientDohServerAddress | Format-Table
Group Policy: Computer Configuration → Administrative Templates → Network → DNS Client → Configure DNS over HTTPS (DoH) name resolution set to Allow DoH or Require DoH. The Required setting blocks plaintext fallback even if the endpoint becomes unreachable.
Linux endpoints (systemd-resolved + stubby)
Two clean paths on modern Linux: systemd-resolved for DoT (DNS over TLS) — same threat model, simpler config — or stubby / dnsdist for true DoH.
# DoT via systemd-resolved (Ubuntu 24.04+, Fedora 39+, Debian 12+) sudo tee /etc/systemd/resolved.conf.d/doh.conf <<'EOF' [Resolve] DNS=1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com DNSOverTLS=yes DNSSEC=yes Cache=yes EOF sudo systemctl restart systemd-resolved resolvectl status # confirm "+DNSOverTLS=yes"
For true DoH, stubby with a DoH-capable upstream is the lightest option:
sudo apt install -y stubby sudo sed -i 's/listen_addresses:.*/listen_addresses: [ 127.0.0.1@5353 ]/' /etc/stubby/stubby.yml # Point /etc/resolv.conf or NetworkManager at 127.0.0.1:5353
macOS endpoints (configuration profile)
macOS Ventura+ enforces DoH via signed configuration profile (.mobileconfig). The cleanest delivery is MDM (Jamf, Mosyle, Kandji). For a single laptop you can install the profile manually:
<dict>
<key>DNSSettings</key>
<dict>
<key>DNSProtocol</key><string>HTTPS</string>
<key>ServerURL</key><string>https://cloudflare-dns.com/dns-query</string>
</dict>
<key>PayloadType</key><string>com.apple.dnsSettings.managed</string>
</dict>
Install via System Settings → Privacy & Security → Profiles. Verify with scutil --dns and look for protocol: HTTPS on each resolver entry.
DoH on your own resolver (unbound + dnsdist)
The corporate pattern: dnsdist as the DoH front-end, unbound as the recursive resolver behind it, both on the same box. Hetzner CAX21 box or N100 mini-PC handles thousands of QPS comfortably.
# /etc/dnsdist/dnsdist.conf
addDOHLocal('0.0.0.0:443', '/etc/letsencrypt/live/dns.example.com/fullchain.pem',
'/etc/letsencrypt/live/dns.example.com/privkey.pem',
{ '/dns-query' }, { reusePort=true, idleTimeout=30 })
newServer({ address='127.0.0.1:5353', name='unbound', useClientSubnet=false })
# /etc/unbound/unbound.conf.d/local.conf server: interface: 127.0.0.1@5353 access-control: 127.0.0.1/32 allow cache-min-ttl: 60 cache-max-ttl: 86400 prefetch: yes qname-minimisation: yes hide-identity: yes hide-version: yes
Point clients at https://dns.example.com/dns-query. You now own every step of the resolution chain.
Edge enforcement on pfSense / OPNsense
Two opposing policies, both legitimate.
- Allow only your DoH endpoint. Block TCP 443 to the well-known public DoH IPs from the user LAN, force clients to use your in-house DoH. pfSense’s pfBlockerNG and OPNsense’s IDS rules both ship lists of public DoH endpoints.
- Allow any DoH, block plaintext DNS. Drop outbound UDP/53 except from the resolver, so clients are forced into encrypted resolution even if the OS defaults regress.
Monitoring and the legitimate-bypass case
The most overlooked side-effect of DoH: it breaks pcap-based DNS visibility. Two answers depending on your goals.
- If you need detection visibility, terminate DoH on your own resolver and forward the resulting plaintext queries into your SIEM. Wazuh and the SOC homelab stack can decorate the indexed events with DNSDB enrichment.
- If you need policy enforcement (block social media, gambling, malware C2 by hostname), do it at the resolver level rather than at the wire. Maintaining a sinkhole of DoH endpoints is a Sisyphean task.
Pitfalls and rollback
- Captive portals break under “Require DoH”. Hotel and airport Wi-Fi rely on intercepting DNS to redirect you to the captive portal. Set the OS policy to Allow rather than Require, or maintain a captive-portal exception list.
- Split-horizon DNS for internal hostnames. Your internal
company.localrecords only exist on your internal resolver. Configure DoH only as a fallback for external names; internal queries must still hit the internal resolver first. - TLS cert pinning on the DoH endpoint. If your DoH endpoint expires its Let’s Encrypt cert silently, every client loses DNS. Monitor cert expiry with a 7-day alert and renew via cron.
- QUIC + DoH3. The newer DoH3 (over QUIC / UDP 443) is faster and harder to block, but support is still uneven on Windows. Plan for DoH2 over TCP/443 as the baseline and DoH3 as an upgrade.
FAQ
DoH vs DoT — which should I deploy?
DoT (DNS over TLS, port 853) is simpler to operate on Linux and easier to inspect with a transparent proxy. DoH (port 443) hides better in HTTPS noise and is harder for hostile networks to block. For corporate visibility, DoT is friendlier; for hostile-network roaming users, DoH is the better default.
Will DoH break my malware filtering?
Only if you filter at the wire. If you self-host DoH or use Quad9 / NextDNS / AdGuard with their filtered categories, you get the same protection as before plus encryption. The losing pattern is “I rely on Sophos UTM to read DNS over UDP 53 and block by hostname” — that visibility disappears once clients move to DoH.
How do I monitor DoH from a SIEM if traffic is encrypted?
Terminate DoH on a resolver you own (the unbound + dnsdist pattern above), log the queries on that resolver, and forward the logs to your SIEM. The plaintext only exists for the millisecond between dnsdist decoding the HTTPS payload and unbound resolving it — capture it there.
Does Windows Defender know about DoH?
Yes. Windows Defender and Defender for Endpoint can both consume DoH and feed their own threat-intelligence DNS feeds. The MDE feature called Defender SmartScreen DoH is a managed policy that forces all client DNS through Microsoft’s filtered DoH endpoint with policy enforcement.
Can mobile devices use DoH?
iOS 14+ and Android 9+ both support DoH at the OS level via configuration profiles. Mobile management platforms (Intune, Jamf, Mosyle) can push the profile fleet-wide. Per-app DoH on iOS via the NEAppProxyProvider API is also possible for enterprise apps.
What about Encrypted Client Hello (ECH)?
ECH closes the last big DNS-adjacent leak: the SNI field in the TLS handshake. As of 2026, ECH is supported by Chrome 117+, Firefox 118+ and Cloudflare DoH endpoints, but you still need the destination origin to opt in. Treat ECH as additive — DoH plus ECH is the strongest combination, DoH alone is already a major improvement.
Run your own DoH stack
Pair this guide with a self-hosted VPN — WireGuard split or full tunnel — and your DoH traffic exits where you choose, not where your ISP routes you.













