Every time you visit a website, your device asks a DNS resolver to translate a domain name into an IP address. Before your browser makes a single HTTPS request — before any encryption kicks in — that lookup travels across the network in plain text. Your ISP can see it. Anyone monitoring the network can see it. Every app, every service, every domain you query: a readable log, moving in the open, all day long.
This is simultaneously one of the oldest and most persistently overlooked privacy problems in everyday computing. The web moved to HTTPS years ago. DNS, the first thing that happens before any of that, largely didn’t.
DNS over HTTPS (DoH) and DNS over TLS (DoT) fix this at the transport layer — your queries are encrypted before they leave your device. Apple has supported both protocols natively since iOS 14 and macOS Big Sur, but the controls aren’t in any settings menu. You configure them through a configuration profile: a small XML file you install once that tells the OS which resolver to use and how to talk to it.
By the end of this guide, you’ll have:
- A working encrypted DNS configuration on your iPhone, iPad, or Mac
- An understanding of what DoH and DoT actually do (and what they don’t)
- The profile code for several well-regarded privacy-focused DNS providers
- Enough context to adapt the profile for your own self-hosted resolver
Prerequisites:
- iOS 14 or later, iPadOS 14 or later, or macOS Big Sur (11.0) or later
- A text editor capable of saving a
.mobileconfigfile (any plain-text editor works) - Basic comfort with copy-pasting XML and running a terminal command
If you’re newer to DNS itself, record-types is a good place to get grounded first. If you’re interested in running your own resolver with ad-filtering at the network level, see blocky — encrypted DNS and a self-hosted resolver work well together.
What Encrypted DNS Actually Protects (and What It Doesn’t)
Before diving into config files, it’s worth being honest about what you’re getting.
Encrypted DNS hides your DNS queries from observers on the network path — your ISP, anyone on your Wi-Fi, or anyone performing a man-in-the-middle attack between you and the resolver. That’s a meaningful and real improvement over the default.
What it doesn’t do: it doesn’t hide your queries from the DNS provider you’re sending them to. You’re trading one party’s visibility (your ISP) for another’s (your chosen resolver). This is why provider choice matters — you want a resolver with a credible, audited no-logging policy, ideally one that isn’t in the business of monetising your data.
It also doesn’t fully hide your browsing from your ISP, because HTTPS still leaks the server hostname through the TLS Server Name Indication (SNI) extension during the handshake. The Encrypted Client Hello (ECH) extension is gradually closing that gap, but support is not yet universal. Treat encrypted DNS as one layer in a privacy posture, not a complete solution on its own.
With that said — encrypting your DNS queries is still meaningfully better than not encrypting them. Your ISP’s passive logging of every domain you visit is the most routine privacy intrusion in daily internet use. This is a direct fix for that.
DoH vs. DoT: The Practical Difference
Both protocols do the same job — encrypt your DNS queries — but they take different routes.
DNS over TLS (DoT) wraps DNS queries in a TLS connection and sends them over port 853. It’s a dedicated protocol on a dedicated port, which makes it clean and simple, but also easy for network administrators (or restrictive ISPs) to detect and block. On a network that deliberately restricts DNS, DoT is the first thing to go.
DNS over HTTPS (DoH) sends DNS queries inside regular HTTPS traffic on port 443 — the same port your browser uses for every website. To a network observer, it’s indistinguishable from web traffic. This makes it significantly harder to block without breaking the web entirely.
For most people at home on a trusted network, the choice is largely academic — both work reliably, and the latency difference is negligible. If you travel frequently or use a lot of hotel, airport, or corporate Wi-Fi, DoH is the more resilient choice. If you’re running a self-hosted resolver on your own network and want maximum simplicity, DoT is slightly cleaner.
When in doubt: use DoH.
Choosing a DNS Provider
Your encrypted DNS traffic goes to a resolver, and that resolver can still see everything you ask. Choose accordingly.
Quad9 (9.9.9.9) — Operated by a Swiss non-profit. Blocks known malware and phishing domains using threat intelligence from multiple sources. No query logging. Free. A solid default if you want a layer of protection against malicious domains without running your own resolver. Documentation
Cloudflare (1.1.1.1) — Fast, globally distributed, and run by a large US company with a documented privacy policy committing to no sale of query data and limited retention. Cloudflare also offers 1.1.1.3 (family filtering with malware and adult content blocking) if that’s useful. Documentation
Mullvad DNS — Run by the Swedish VPN provider. No logging, no account required, optional ad and tracker blocking. A reasonable choice if you’re already in the Mullvad ecosystem. Documentation
DNS.SB — Run by the infrastructure company xTom. No query logging, operates nodes at 30+ locations across 6 continents, supports both DoH and DoT. Less well-known than the above options but with a solid privacy track record and a recently-updated policy. Used in the examples below.
Self-hosted — If you’re already running something like Blocky, Unbound, or Pi-hole with DoH/DoT support, you can point your Apple devices at it directly. This is the highest-trust option and is covered briefly in the per-network section below. Running your own resolver means nobody outside your infrastructure sees your queries — but it requires you to keep that infrastructure running and reachable.
There’s no universally correct answer here. The right choice depends on your threat model. For most people, Quad9 or Mullvad is a reasonable starting point: non-profit or privacy-focused operator, audited no-logging policy, and a genuine stake in not abusing the position.
How Configuration Profiles Work
Apple doesn’t expose encrypted DNS settings in the standard Settings UI. The controls are intentionally absent — this is a managed device feature, designed for enterprise MDM deployments, but available to anyone willing to write the XML.
A configuration profile (.mobileconfig) is a structured XML file that tells the OS to apply a specific configuration. When you install one, iOS or macOS reads it, validates the structure, and applies the settings system-wide. The DNS profile type (com.apple.dnsSettings.managed) instructs the OS to use your specified resolver instead of whatever’s assigned by DHCP.
The key thing this buys you over changing a DNS IP address in network settings: the configuration profile enforces the protocol. It doesn’t just point at a server — it tells the OS to use DoH or DoT, so the encrypted transport is guaranteed system-wide rather than per-app.
Building the Profile
You’ll need a text editor and the terminal open. The structure is the same for both DoH and DoT — only a few fields differ.
Generating UUIDs
Every payload in an Apple configuration profile requires a unique UUID. Generate fresh ones for your profile with:
uuidgenRun it three times — you’ll need two PayloadUUID values (one for the outer profile, one for the DNS payload) and one PayloadIdentifier suffix. Replace all placeholder UUIDs in the examples below before installing.
Don’t reuse UUIDs between profiles. If you install two profiles with the same UUID, Apple will treat the second as an update to the first.
DNS over HTTPS Profile
Save this as encrypted-dns-doh.mobileconfig, replacing the UUIDs and adjusting the provider fields as needed:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>DNSSettings</key>
<dict>
<key>DNSProtocol</key>
<string>HTTPS</string>
<key>ServerAddresses</key>
<array>
<string>185.222.222.222</string>
<string>45.11.45.11</string>
<string>2a09::</string>
<string>2a11::</string>
</array>
<key>ServerURL</key>
<string>https://doh.dns.sb/dns-query</string>
</dict>
<key>PayloadDescription</key>
<string>Configures device to use DNS over HTTPS</string>
<key>PayloadDisplayName</key>
<string>DNS over HTTPS (DNS.SB)</string>
<key>PayloadIdentifier</key>
<string>com.apple.dnsSettings.managed.doh</string>
<key>PayloadType</key>
<string>com.apple.dnsSettings.managed</string>
<key>PayloadUUID</key>
<string>REPLACE-WITH-UUIDGEN-OUTPUT-1</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>Enables encrypted DNS using DNS over HTTPS</string>
<key>PayloadDisplayName</key>
<string>Encrypted DNS (DoH)</string>
<key>PayloadIdentifier</key>
<string>com.example.dns.doh</string>
<key>PayloadOrganization</key>
<string>North Engineer</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>REPLACE-WITH-UUIDGEN-OUTPUT-2</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>What these fields do:
DNSProtocol: HTTPS— instructs the OS to use DNS over HTTPS specificallyServerAddresses— fallback IP addresses used if the DoH endpoint itself is unreachable (a bootstrap mechanism; these queries may be unencrypted, but they’re only used when the DoH server can’t be reached)ServerURL— the DoH endpoint the OS will use for all queriesPayloadRemovalDisallowed: false— allows you to remove the profile from Settings; set totrueonly in supervised MDM deploymentsPayloadUUID— must be unique per profile; generate withuuidgen
DNS over TLS Profile
The structure is nearly identical. The meaningful differences are DNSProtocol: TLS and a ServerName field (for TLS certificate validation) instead of ServerURL:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>DNSSettings</key>
<dict>
<key>DNSProtocol</key>
<string>TLS</string>
<key>ServerAddresses</key>
<array>
<string>185.222.222.222</string>
<string>45.11.45.11</string>
<string>2a09::</string>
<string>2a11::</string>
</array>
<key>ServerName</key>
<string>dns.sb</string>
</dict>
<key>PayloadDescription</key>
<string>Configures device to use DNS over TLS</string>
<key>PayloadDisplayName</key>
<string>DNS over TLS (DNS.SB)</string>
<key>PayloadIdentifier</key>
<string>com.apple.dnsSettings.managed.dot</string>
<key>PayloadType</key>
<string>com.apple.dnsSettings.managed</string>
<key>PayloadUUID</key>
<string>REPLACE-WITH-UUIDGEN-OUTPUT-3</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>Enables encrypted DNS using DNS over TLS</string>
<key>PayloadDisplayName</key>
<string>Encrypted DNS (DoT)</string>
<key>PayloadIdentifier</key>
<string>com.example.dns.dot</string>
<key>PayloadOrganization</key>
<string>North Engineer</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>REPLACE-WITH-UUIDGEN-OUTPUT-4</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>What changed from the DoH profile:
DNSProtocol: TLS— uses DNS over TLS on port 853 instead of HTTPS on port 443ServerNamereplacesServerURL— this is the hostname used to validate the server’s TLS certificate, not a full URL
Installing the Profile
iOS / iPadOS
-
Transfer the
.mobileconfigfile to your device. The easiest methods are AirDrop from a Mac, or emailing it to yourself and opening the attachment in Mail on the device. You can also host it on a local web server and open it in Safari — note that Safari is required; Chrome and Firefox won’t trigger the profile installer. -
After tapping the file, iOS will show a “Profile Downloaded” notification. The file is staged but not yet installed.
-
Go to Settings → General → VPN, DNS & Device Management.
-
Tap the downloaded profile under “Downloaded Profile.”
-
Tap Install, enter your passcode when prompted, and confirm on the final review screen.
macOS
-
Double-click the
.mobileconfigfile. System Settings will open automatically. -
Navigate to System Settings → Privacy & Security → Profiles if it doesn’t open there directly.
-
Click on the downloaded profile and click Install.
-
Enter your administrator password if prompted.
Verifying It Works
Check DNS settings on iOS: Settings → General → VPN, DNS & Device Management → DNS. You should see your provider listed under the encrypted configuration.
Check DNS settings on macOS: System Settings → Network → (your active connection) → Details → DNS.
Test with Cloudflare’s checker: Visit 1.1.1.1/help — it shows which resolver is handling your queries and whether HTTPS is in use.
Test for DNS leaks: dnsleaktest.com runs multiple rounds of queries and lists the resolvers that responded. You should see only your configured provider.
Confirm the resolver from the terminal (macOS):
dig +short txt whoami.ds.akahelp.netThis returns information about which DNS resolver answered the query. Cross-reference with your configured provider’s IP ranges.
Provider-Specific Configurations
If you want to use Quad9, Cloudflare, or Mullvad instead of DNS.SB, swap out only the DNSSettings block in either profile above. Everything else stays the same.
Quad9 (DoH with malware blocking)
<key>DNSProtocol</key>
<string>HTTPS</string>
<key>ServerAddresses</key>
<array>
<string>9.9.9.9</string>
<string>149.112.112.112</string>
<string>2620:fe::fe</string>
<string>2620:fe::9</string>
</array>
<key>ServerURL</key>
<string>https://dns.quad9.net/dns-query</string>Quad9 blocks domains associated with malware and phishing at the DNS level. Legitimate domains pass through unaffected. This is a useful default for devices used by less technical family members.
Cloudflare (DoH — standard)
<key>DNSProtocol</key>
<string>HTTPS</string>
<key>ServerAddresses</key>
<array>
<string>1.1.1.1</string>
<string>1.0.0.1</string>
<string>2606:4700:4700::1111</string>
<string>2606:4700:4700::1001</string>
</array>
<key>ServerURL</key>
<string>https://cloudflare-dns.com/dns-query</string>Cloudflare (DoH — malware + adult content blocking)
<key>DNSProtocol</key>
<string>HTTPS</string>
<key>ServerAddresses</key>
<array>
<string>1.1.1.3</string>
<string>1.0.0.3</string>
<string>2606:4700:4700::1113</string>
<string>2606:4700:4700::1003</string>
</array>
<key>ServerURL</key>
<string>https://family.cloudflare-dns.com/dns-query</string>Mullvad (DoH with ad blocking)
<key>DNSProtocol</key>
<string>HTTPS</string>
<key>ServerAddresses</key>
<array>
<string>194.242.2.3</string>
</array>
<key>ServerURL</key>
<string>https://adblock.dns.mullvad.net/dns-query</string>Mullvad’s ad-blocking resolver is a reasonable middle ground if you want some filtering without running your own DNS server. It won’t be as comprehensive as a self-hosted Blocky or Pi-hole instance, but it requires zero infrastructure.
Per-Network Rules
By default, the profile applies to every network your device connects to. For most personal devices, that’s fine. If you need to exclude internal domains — say, you work at a company that uses internal DNS for internal.company.com — you can add an OnDemandRules block to your profile:
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>EvaluateConnection</string>
<key>ActionParameters</key>
<array>
<dict>
<key>DomainAction</key>
<string>NeverConnect</string>
<key>Domains</key>
<array>
<string>local</string>
<string>internal.company.com</string>
</array>
</dict>
</array>
</dict>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>This tells the OS: for the listed domains, skip the encrypted resolver and fall back to whatever DNS the network provides. For everything else, use the profile. The local entry is important — it prevents the profile from interfering with mDNS and local service discovery (.local hostnames for printers, AirPlay receivers, and so on).
If you’re running a self-hosted resolver at home and want your devices to use it only on your home network, you can configure OnDemandRules to match by SSID and activate only on that network. Apple’s profile documentation covers the full set of matching conditions.1
Known Limitations
VPN: When you’re connected to a VPN, the VPN’s DNS configuration takes precedence over the profile. This is correct and expected behaviour — VPN DNS prevents DNS leaks that would expose your traffic outside the tunnel. The profile effectively pauses while the VPN is active.
Captive portals: Many hotel and airport Wi-Fi networks use captive portals that require the device to receive an unencrypted DNS response pointing to the login page before you can authenticate. The encrypted DNS profile can break this. If you can’t get past a captive portal, temporarily disable the profile under VPN, DNS & Device Management, connect and authenticate, then re-enable it. The OS typically detects captive portals automatically and may suspend the profile on its own.
Split-horizon DNS: If your organisation runs different DNS responses internally vs. externally (common in corporate environments), pointing at an external resolver means you’ll only ever see external answers. Internal service hostnames may not resolve at all. Use OnDemandRules to exclude the relevant domains, or remove the profile on corporate networks.
Profile expiration: Configuration profiles can include an expiry date, and some community-distributed profiles have one baked in. Profiles you create yourself using the templates above do not expire unless you add an expiry field. If you download a pre-built profile from a third party, check whether it expires — an expired profile silently stops applying its DNS configuration, and you won’t necessarily notice.
Troubleshooting
Profile won’t install: Validate the XML before installing. An unclosed tag or malformed character will prevent installation with a generic error. Run the file through an XML linter (the macOS xmllint tool, or any online validator) to check for syntax errors. Verify that all UUIDs are unique and correctly formatted (8-4-4-4-12 hex characters, uppercase by convention).
DNS not resolving at all: The encrypted DNS server may be temporarily unreachable, or your network may be blocking port 443 (DoH) or port 853 (DoT). Try the other protocol, or try a different provider. Temporarily removing the profile will restore your network’s default DNS and tell you quickly whether the profile is the problem.
Some sites or services don’t load: If your provider uses malware or content blocking, a legitimate domain may be caught in the filter. Check the provider’s documentation for how to verify or whitelist a domain, or switch to an unfiltered resolver temporarily to confirm.
Corporate network issues: Some enterprise networks require that you use their internal DNS for internal resources. If you hit this, remove the profile for the duration — or use OnDemandRules to route internal domains through the corporate resolver while encrypting everything else.
Shortcuts and Community Resources
If you’d rather not write XML by hand, Paul Miller maintains a well-regarded GitHub repository of pre-built configuration profiles for a range of providers: github.com/paulmillr/encrypted-dns. The profiles are auditable, regularly updated, and cover more providers than this guide lists. The trade-off is that you’re trusting a community-maintained source rather than building from first principles. Read the profile before installing it.
upset.dev/dns-profile-generator offers a web-based generator if you want a quick custom profile without touching XML directly.
Closing Thoughts
This is a small change with a real effect. Installing one file, once, encrypts every DNS query on your device for as long as the profile is active. Your ISP stops seeing a readable log of every domain you visit. The configuration survives reboots, app updates, and network changes automatically.
It’s not a complete privacy solution — nothing is — but it’s one of the more asymmetric improvements you can make for the effort involved. Half an hour of work, and the most routine passive surveillance of your internet use disappears.
The next person who goes looking for how to do this on Apple devices shouldn’t have to start from scratch.
Footnotes
Footnotes
-
Apple’s configuration profile reference for DNS settings: developer.apple.com/documentation/devicemanagement/dnssettings ↩