Example of DNS Proxy Provider Network Extension

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?

Answered by DTS Engineer in 860650022

If you want to support the DNS-over-TLS standard — RFC 7858 and friends — then you don’t need a DNS proxy provider. Rather, you can configure the system to use its built-in DNS-over-TLS implementation using the Network Extension DNS settings API.

DNS proxy providers are useful when the DNS server speaks a custom protocol. And creating such a provider is way more complex than applying custom DNS settings. Moreover, such providers have significant deployment limitations, as described in TN3134 Network Extension provider deployment. My advice is that you avoid this path if at all possible.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

If you want to support the DNS-over-TLS standard — RFC 7858 and friends — then you don’t need a DNS proxy provider. Rather, you can configure the system to use its built-in DNS-over-TLS implementation using the Network Extension DNS settings API.

DNS proxy providers are useful when the DNS server speaks a custom protocol. And creating such a provider is way more complex than applying custom DNS settings. Moreover, such providers have significant deployment limitations, as described in TN3134 Network Extension provider deployment. My advice is that you avoid this path if at all possible.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for the quick response! In the information I came across before asking this question, it sounded like a toggle to turn system wide DNS on or off from within the app was impossible without the Network Extension? So just to clarify, will the DNS Settings API allow it to be turned on and off from within the app?

Accepted Answer
will the DNS Settings API allow it to be turned on and off from within the app?

Sure. In the DNS settings API you use NEDNSSettingsManager to apply your settings, and it has an isEnabled property that does what you want.

IMPORTANT The limitations on DNS proxy providers are privacy focused. A DNS proxy has a privileged network position, allowing on-device code to see all the DNS names used by the user. The DNS settings API doesn’t work that way, because you just apply settings that are then used by the built-in resolver. That’s why you can use the DNS settings API in any context, where DNS proxy providers have hard deployment limits.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

We have an initial version working now, thank you!

Well, it looks like I may have spoken too soon. The isEnabled property on NEDNSSettingsManager appears to be read only. Which means that we cannot flip .isEnabled ourselves from the app, which would mean that the user has to select it in Settings. And that property even says, "DNS settings must be enabled by the user in Settings or System Preferences."

(The "working" version I mentioned was someone going into Settings and turning it on manually.)

We need the ability to turn it on and off from within the app. Am I missing something?

Actually, slight Edit. We are ok with going in to iOS Settings once when it's first loaded to switch to our DoT settings, but after that we'd like to be able to turn it on and off from within the app and haven't yet figured out how to do that without access to the isEnabled property on NEDNSSettingsManager. We can remove it altogether. But then we have to go back into Settings when we re-load it to enable it, which we are trying to avoid (and other apps seem to be able to disable and enable from within the app).

Example of DNS Proxy Provider Network Extension
 
 
Q