Running MacOS Network system extension showing waiting for attach .

Hi @eskimo, @meaton,

Im new to Mac Development, we are having our own custom DNS app with the use of NEDNSSetting, it just resolving all the traffic on device when we activate our own custom DNS option in System Setting->Network Preferences. Now we have to add DNSProxy into the app. But as per My research till now and after reading similar replies on developer forum, NEDNSSetting and NEDNSProxy service can not be run together or it's complex to run them together. So I have remove earlier DNSSetting implementation and added NEDNSProxy, Below is what I have done so far:

Custom Class I have created:

import Foundation
import SystemExtensions
import NetworkExtension
import os
@available(macOS 10.15, *)

public final class ConfigureProxyManager: NSObject {
    public static let shared = ConfigureProxyManager()
    public func installSystemExtension() {
        let request = OSSystemExtensionRequest.activationRequest(
            forExtensionWithIdentifier: "com.***.MacOS-DNSProxyNetworkExtension",

            queue: .main
        )

        request.delegate = self
        OSSystemExtensionManager.shared.submitRequest(request)
        print("System Request has been submitted successfully")
    }

    public func startNetworkExtension() {

        print("Enter in startNetworkExtension")
        NEDNSProxyManager.shared().loadFromPreferences { error in
            precondition(Thread.isMainThread)

            if let nsError = error as NSError? {
                /* Handle error */
                return
            }

            let proto = NEDNSProxyProviderProtocol()
            proto.serverAddress = "localhost" /* Here we have to pass custom DNS*/
            proto.providerBundleIdentifier = "com.***.MacOS-DNSProxyNetworkExtension"

            NEDNSProxyManager.shared().providerProtocol = proto
            NEDNSProxyManager.shared().isEnabled = true
            NEDNSProxyManager.shared().localizedDescription = "Custom DNS Proxy"
            NEDNSProxyManager.shared().saveToPreferences { saveError in

                if let nsError = saveError as NSError? {

                    /* Handle error */

                    return

                }

                /* Handle Success Case */
            }
        }
    }
}

@available(macOS 10.15, *)

extension ConfigureProxyManager: OSSystemExtensionRequestDelegate {

    public func request(_ request: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction {

        return .replace

    }

    public func requestNeedsUserApproval(_ request: OSSystemExtensionRequest) {

        print("Enter in requestNeedsUserApproval")

    }

    public func request(_ request: OSSystemExtensionRequest, didFailWithError error: Error) {

        print("Enter in didFailWithError")

    }

    /* Other delegate methods here */

    public func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result) {

        switch result {

        case .completed:

            startNetworkExtension()

            //manager = NEDNSProxyManager.shared()

        case .willCompleteAfterReboot: break

             /* Proceed with result here */

        @unknown default: break

            /* Proceed with result here */
        }
    }
}

Extension DNSProxyProvider

import NetworkExtension

import os

class DNSProxyProvider: NEDNSProxyProvider {

    private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "DNSProxyProvider")


    override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) { os_log("Entered in startProxy Method")

        // Add code here to start the DNS proxy.

        completionHandler(nil)

    }

    override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        // Add code here to stop the DNS proxy.
        completionHandler()
    }

    override func sleep(completionHandler: @escaping () -> Void) {
        // Add code here to get ready to sleep.
        completionHandler()
    }

    override func wake() {
        // Add code here to wake up.
    }

    override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
        // Add code here to handle the incoming flow.
        logger.log("Flow Enter in handlenewflow method")
        return false
    }

Extension Main File

import Foundation
import NetworkExtension

autoreleasepool {

    NEProvider.startSystemExtensionMode()

}

dispatchMain()

Container app entitlement

<?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>com.apple.developer.networking.networkextension</key>

	<array>

		<string>dns-proxy</string>

	</array>

	<key>com.apple.security.app-sandbox</key>

	<true/>

	<key>com.apple.security.files.user-selected.read-write</key>

	<true/>

	<key>com.apple.security.network.client</key>

	<true/>

	<key>com.apple.security.network.server</key>

	<true/>

	<key>com.apple.security.temporary-exception.mach-lookup.global-name</key>

	<array>

		<string>com.hyas.protect.agent-spks</string>

		<string>com.hyas.protect.agent-spki</string>

	</array>

        <key>com.apple.developer.system-extension.install</key>

        <true/>

        <key>com.apple.security.application-groups</key>

        <array>

            <string>$(TeamIdentifierPrefix)com.*** </string>

        </array>

</dict>

</plist>

Extension entitlement

<?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>com.apple.security.app-sandbox</key>

	<true/>

	<key>com.apple.security.application-groups</key>

	<array>

		<string>$(TeamIdentifierPrefix)com.***.DNSProxyProvider</string>

	</array>

	<key>com.apple.developer.networking.networkextension</key>

	<array>

		<string>dns-proxy</string>

	</array>

</dict>

</plist>

**This is setup till now I have. **

I trying to debug my system extension its showing waiting for attach, due to that Im not getting call in handleNewFlow method of DNSProxyProvider. What’s wrong Im doing here?

I trying to debug my system extension its showing waiting for attach, due to that Im not getting call in handleNewFlow method of DNSProxyProvider. What’s wrong Im doing here?

At first glance, I don't see anything wrong with your setup. A few things to check along the way here to see where things could wrong:

  1. When you call OSSystemExtensionManager.shared.submitRequest(request) is it at least making it to case .completed in your OSSystemExtensionRequestDelegate delegate? If so, and you are accepting the popup dialog then your extension should be getting installed.

  2. When you call .saveToPreferences are you getting an error?

  3. If (2) is good, then do you see your extension getting hit? Try putting a constructor in DNSProxyProvider to see if this is being hit. This should tell you at least if you system extension code is being invoked.

static let log = OSLog(subsystem: "com.***.MacOS-DNSProxyNetworkExtension", category: "dns_proxy_provider")
private let log: OSLog

override init() {
    self.log = Self.log
    os_log(.debug, log: self.log, "init")
    super.init()
}
  1. If you see your system extension code being invoked, how are you running and testing your extension? Do you build it locally and then drag the executable into the /Applications directory? If not, you should be doing this and then streaming the logs with log stream on your Mac.

Hi @meaton,

Thanks for quick reply, this helps me lot.

So I did this first:

If you see your system extension code being invoked, how are you running and testing your extension? Do you build it locally and then drag the executable into the /Applications directory? If not, you should be doing this and then streaming the logs with log stream on your Mac.

As per this instructions, request is getting completed in OSSystemExtensionRequestDelegate.

When you call .saveToPreferences are you getting an error?

No. Im not getting error. SaveToPreferences works perfectly.

Try putting a constructor in DNSProxyProvider to see if this is being hit. This should tell you at least if you system extension code is being invoked.

I put constructor in DNSProxyProvider, but Im getting following different errors in console application logs.

  1. ASI found [dyld] (sensitive) 'Library not loaded: @rpath/Sparkle.framework/Versions/B/Sparkle

  Referenced from: <7CE344FF-E938-3E0F-B840-B03EAC2B3D5B> /Library/SystemExtensions/6229CF3D-05D5-458C-9AED-92A91E504A52/com.***.MacOS-DNSProxyNetworkExtension.systemextension/Contents/MacOS/com.***.MacOS-DNSProxyNetworkExtension

  Reason: tried: '/Library/SystemExtensions/6229CF3D-05D5-458C-9AED-92A91E504A52/com.***.MacOS-DNSProxyNetworkExtension.systemextension/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle' (no such file), '/Library/SystemExtensions/Frameworks/Sparkle.framework/Versions/B/Sparkle' (no such file), '/Library/SystemExtensions/6229CF3D-05D5-458C-9AED-92A91E504A52/com.***.MacOS-DNSProxyNetworkExtension.systemextension/Contents/Frameworks/Sparkle.framework/Versions/B/Sparkle' (no such file), '/Library/SystemExtensions/Frameworks/Sparkle.framework/Versions/B/Sparkle' (no such file), '/System/Volumes/Preboot/Cryptexes/OS@rpath/Spa<…>'

  1. Formulating fatal 309 report for corpse[36488] com.***.MacOS-DNSProxyNetworkExtension

  2. Unable to find store record for 'file:///Library/SystemExtensions/6229CF3D-05D5-458C-9AED-92A91E504A52/com.***.MacOS-DNSProxyNetworkExtension.systemextension/': Error Domain=NSOSStatusErrorDomain Code=-10811 "kLSNotAnApplicationErr: Item needs to be an application, but is not" UserInfo={_LSLine=175, _LSFunction=_LSFindBundleWithInfo_NoIOFiltered}

  3. com.***.MacOS-DNSProxyNetworkExtension is not a MetricKit client

  4. Sending event: com.apple.stability.crash {"appVersion":"1.0","bundleID":"com.***.MacOS-DNSProxyNetworkExtension","bundleVersion":"1","coalitionName":"NetworkExtension.com.***.MacOS-DNSProxyNetworkExtension.1.0.1","exceptionCodes":"0x0000000000000000, 0x0000000000000000(\n    0,\n    0\n)EXC_CRASHSIGABRT","incidentID":"56FAD6E5-6092-4BB2-9F9B-CD958AE636BE","logwritten":0,"process":"com.hyas.protect.agent.MacOS-DNSProxyNetworkExtension","terminationReasonExceptionCode":"0x1","terminationReasonNamespace":"DYLD"}

I trying to debug my system extension its showing waiting for attach

So in Xcode you chose Product > Run?

If so, that’s not going to work. Xcode is not set up to debug NE extensions, both appex and sysex, in that way. Rather, you have to run your extension and then, once it’s running, choose Debug > Attach to X.

Oh, hey, I wasn’t able to finish my reply this morning and, by the time I got back to it, Matt had already waded in. So anyway, I’ve been meaning to write up my thoughts on this topic for a while and I used your thread as an excuse to do that. See Debugging a Network Extension Provider.

Share and Enjoy

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

It looks like you are having issues loading your Network System Extension and that's what's causing you problems. I would start with a blank NEDNSProxyProvider and see if that loads. While you are testing that, take a look at the amazing new guide that Quinn just wrote for debugging these types of situations with Network System Extensions. That document is here.

Hey @eskimo, Thanks for your input also. Yes as suggested by @meaton I tried few things, and as per my last reply above Im able to load system extension and do the save preferences. But DNSProxyProvider is not loading now. Now as meaton says I will recheck loading Network system extension and also will go through above link Debugging Network Extension Provider.

Hi @eskimo, I followed above link line by line to debug system extension. I added script as suggested in above article it copy my app to application folder when debug and compile successfully. then I run my app through terminal by selecting app through application folder. it doesn't call DNSProxyProvider Constructor. But before that what I noticed Im able to add system extension with enabled state but that enabled state or mode is not showing in green colour I guess in running state it shows in orange colour.

then I run my app through terminal

If you’re able to bulid and debug directly from Xcode, how does Terminal factor into this?

Share and Enjoy

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

Hi @eskimo,

I followed above link line by line to debug system extension. I added script as suggested in above article it copy my app to application folder when debug and compile successfully.

I did this but my app is getting crashed, Please see the attached screenshot. So I thought let's give a try with terminal as per some suggestion on developer forums. But that's not again working.

  1. Why and what is this crash?
  2. Im able to add system extension to network preferences I have attached screenshot but why its not showing running means active with green dot.

The screen shot shows your process dying in __abort_with_payload. That suggests that something within your process has trapped, that is, detected a failure and deliberately crashed. It’s hard to say what that is without more context. The best way to get that is to choose Debug > Detach. That causes the Xcode debugger to detach, at which point the crash will be caught by the system crash reporter. This should generate a crash report, which you can post here.

See Posting a Crash Report for advice on how to post a crash report.

Share and Enjoy

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

Running MacOS Network system extension showing waiting for attach .
 
 
Q