I am trying to setup a system-wide DNS-over-TLS for iOS that can be turned off and on from within the app, and I'm struggling with the implementation details. I've searched online, searched forums here, used ChatGPT, and I'm getting conflicting information or code that is simply wrong. I can't find example code that is valid and gets me moving forward.
I think I need to use NEDNSProxyProvider via the NetworkExtension. Does that sound correct? I have NetworkExtension -> DNS Proxy Capability set in both the main app and the DNSProxy extension.
Also, I want to make sure this is even possible without an MDM. I see conflicting information, some saying this is opened up, but things like https://developer.apple.com/documentation/Technotes/tn3134-network-extension-provider-deployment saying a device needs to be managed. How do private DNS apps do this without MDM?
From some responses in the forums it sounds like we need to parse the DNS requests that come in to the handleNewFlow function. Is there good sample code for this parsing?
I saw some helpful information from Eskimo (for instance https://developer.apple.com/forums/thread/723831 ) and Matt Eaton ( https://developer.apple.com/forums/thread/665480 )but I'm still confused.
So, if I have a DoT URL, is there good sample code somewhere for what startProxy, stopProxy, and handleNewFlow might look like? And valid code to call it from the main app?
So then it seems we would have to implement DNS Proxy to do what we want?
I don’t think that’ll actually work. Because of the DNS proxy deployment limitations [1], the ability to modify the proxy configuration is limited to development-signed apps. Once you sign your app for distribution, it’ll lose its ability to modify its DNS proxy configurations. Rather, the site admin is expected to configure the proxy using MDM payloads.
Or at least that’s how it works with content filters. I can’t remember whether I’ve ever actually tested this with DNS proxies. However, both occupy a similarly privileged networking position and so I expect them to follow the same rules.
A DNS proxy can (more or less) go into pass through mode by leaning in to the systemDNSSettings property.
Or do you have other thoughts now on how to accomplish this?
I’ve not explored the DNS settings API in depth, but there seems like a lot of potential options you could play around with. For example:
- I’m not sure what happens if you set
dnsSettingstonil. - You could set
matchDomainsso that your configuration only applies to a specific domain. - You could supply a bad DNS server and set
allowFailoverto true.
Of course, these all assume that saveToPreferences() doesn’t trigger another authentication. I think that’s the case, based on my experience with other NE APIs, but I’ve not actually tried it.
Let us know how you get along.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] On iOS. On macOS, this isn’t the case.