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!
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"