DNS Proxy network extension doesn't start even after saving preferences successfully

Hello, I'm having some problems starting my DNS proxy network extension.

Even after I call NEDNSProxyManager.saveToPreference() successfully I don't see any logs from my dns proxy.

This is the code from the user space app:

import SwiftUI
import NetworkExtension
func configureDNSProxy() {
let dnsProxyManager = NEDNSProxyManager.shared()
dnsProxyManager.loadFromPreferences { error in
if let error = error {
print("Error loading DNS proxy preferences: \(error)")
return
}
dnsProxyManager.localizedDescription = "my DNS proxy"
let proto = NEDNSProxyProviderProtocol()
proto.providerBundleIdentifier = "com.myteam.dns-proxy-tests.ne"
dnsProxyManager.providerProtocol = proto
// Enable the DNS proxy.
dnsProxyManager.isEnabled = true
dnsProxyManager.saveToPreferences { error in
if let error = error {
print("Error saving DNS proxy preferences: \(error)")
} else {
NSLog("DNS Proxy enabled successfully")
}
}
}
}
@main
struct dns_proxy_testsApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
init() {
configureDNSProxy()
}
}

This is the code for my network extension(DNSProxyProvider.swift):

import NetworkExtension
class DNSProxyProvider: NEDNSProxyProvider {
override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) {
NSLog("dns proxy ne started")
completionHandler(nil)
}
override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
NSLog("dns proxy ne stopped")
completionHandler()
}
override func sleep(completionHandler: @escaping () -> Void) {
NSLog("dns proxy ne sleep")
completionHandler()
}
override func wake() {
NSLog("dns proxy ne wake")
}
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
NSLog("dns proxy ne flow")
return true
}
}

The bundle identifier for my network extension is: com.myteam.dns-proxy-tests.ne and both the user space app and the network extension have the DNS Proxy capability. Both have the same app group capability with the same group name group.com.myteam.dns-proxy-test.

The info.plist from the network extension look like this(I didn't really modify it from the default template created by xcode)

<?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>NetworkExtension</key>
<dict>
<key>NEMachServiceName</key>
<string>$(TeamIdentifierPrefix)com.example.app-group.MySystemExtension</string>
<key>NEProviderClasses</key>
<dict>
<key>com.apple.networkextension.dns-proxy</key>
<string>$(PRODUCT_MODULE_NAME).DNSProxyProvider</string>
</dict>
</dict>
</dict>
</plist>

In the logs I do see DNS Proxy enabled successfully and also I see:

NESMDNSProxySession[Primary Tunnel:my DNS proxy:<...>:(null)] starting with configuration: {
name = my DNS proxy
identifier = <..>
applicationName = dns-proxy-tests
application = com.myteam.dns-proxy-tests
grade = 1
dnsProxy = {
enabled = YES
protocol = {
type = dnsProxy
identifier = <...>
identityDataImported = NO
disconnectOnSleep = NO
disconnectOnIdle = NO
disconnectOnIdleTimeout = 0
disconnectOnWake = NO
disconnectOnWakeTimeout = 0
disconnectOnUserSwitch = NO
disconnectOnLogout = NO
includeAllNetworks = NO
excludeLocalNetworks = NO
excludeCellularServices = YES
excludeAPNs = YES
excludeDeviceCommunication = YES
enforceRoutes = NO
pluginType = com.myteam.dns-proxy-tests
providerBundleIdentifier = com.myteam.dns-proxy-tests.ne
designatedRequirement = identifier "com.myteam.dns-proxy-tests.ne" <...> /* exists */
}
}
}

But then I see:

Checking for com.myteam.dns-proxy-tests.ne - com.apple.networkextension.dns-proxy

But then finally

Found 0 registrations for com.myteam.dns-proxy-tests.ne (com.apple.networkextension.dns-proxy)

So I think that last log probably indicates the problem.

I'm a bit lost at what I'm doing wrong so I'd be super thankful for any pointer!

Answered by DTS Engineer in 831297022

I suspect that the sysextd crash is a known issue that seems to be caused by a race condition in the code (r. 99777199).

The nesessionmanager crash is more likely to be caused by the properties in your sysex. The crashing thread looks like this:

5 Foundation 0x191f5c120 -[NSString initWithFormat:] + 52
6 nesessionmanager 0x100138ac0 -[NESMProviderManager createSystemExtensionErrorWithCode:extensionInfo:] + 440
7 nesessionmanager 0x100139558 -[NESMProviderManager createLaunchdPlistEntriesFromExtensionBundle:extensionInfo:error:] + 2464
8 nesessionmanager 0x1001399d8 __84-[NESMProviderManager listener:validateExtension:atTemporaryBundleURL:replyHandler:]_block_invoke + 212

NE is trying to validate your sysex, that’s failed, and it’s crashed trying to generate the error O-:

Both of these are obviously bugs in our OS — these subsystems should fail rather than crash — and I encourage you to file bug reports about them. Include a sysdiagnose log and a copy of your built app (the broken one, not the fixed one). Please post your bug numbers, just for the record.

However, frame 7 in the NE crash suggests that you have an app group mismatch. NE wants your Mach service name to be ‘inside’ an app group. For example, in my test project I have this:

% codesign -d --entitlements - QNE2DNSProxyMac.app/Contents/Library/SystemExtensions/com.example.apple-samplecode.QNE2DNSProxyMac.SysEx.systemextension
[Dict]
[Value]
[Array]
[String] SKMME9E2Y8.com.example.apple-samplecode.QNE2DNSProxyMac
% plutil -p QNE2DNSProxyMac.app/Contents/Library/SystemExtensions/com.example.apple-samplecode.QNE2DNSProxyMac.SysEx.systemextension/Contents/Info.plist
{
"NetworkExtension" => {
"NEMachServiceName" => "SKMME9E2Y8.com.example.apple-samplecode.QNE2DNSProxyMac.service"
"NEProviderClasses" => {
"com.apple.networkextension.dns-proxy" => "com_example_apple_samplecode_QNE2DNSProxyMac_SysEx.DNSProxyProvider"
}
}
}

My app group, SKMME9E2Y8.com.example.apple-samplecode.QNE2DNSProxyMac, is a prefix of the Mach service name, SKMME9E2Y8.com.example.apple-samplecode.QNE2DNSProxyMac.service, and that’s what NE is checking for.

Share and Enjoy

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

However, frame 7 in the NE crash suggests that you have an app group mismatch. NE wants your Mach service name to be ‘inside’ an app group. For example, in my test project I have this:

My app group, SKMME9E2Y8.com.example.apple-samplecode.QNE2DNSProxyMac, is a prefix of the Mach service name, SKMME9E2Y8.com.example.apple-samplecode.QNE2DNSProxyMac.service, and that’s what NE is checking for.

Ah! Very nice, that was it! :D

I'll report this bug

DNS Proxy network extension doesn't start even after saving preferences successfully
 
 
Q