Can't get NEPacketTunnelProvider to work

I`m trying to make my own OpenVPN client using NetworkExtension. I'm following these instructions:


https://github.com/ss-abramchuk/OpenVPNAdapter


But I cant get it to work. I create my manager succesfully, without any errors. But then when I call startTunnel() nothing happens. No error (I have my try/catch in place) and nothing in the log. I have the NetworkExtension entitlements in both my targets. This is the code in question:


NETunnelProviderManager.loadAllFromPreferences { (managers, error) in
            guard error == nil else {
                NSLog("Unexpected error: \(error).");
                return
            }
           
            /
            if (managers?.count != 0)
            {
                do
                {
                    NSLog("Found VPN with target \(managers?[0].localizedDescription)")
                    managers?[0].isEnabled = true;
                    try managers?[0].connection.startVPNTunnel();
                }
                catch
                {
                    NSLog("Unexpected error: \(error).");
                }
            }
           
            /
            else
            {
                NSLog("Not found, creating new");
                let manager = NETunnelProviderManager();
               
                /
                guard
                    let configurationFileURL = Bundle.main.url(forResource: "config", withExtension: "ovpn"),
                    let configurationFileContent = try? Data(contentsOf: configurationFileURL)
                    else {
                        fatalError()
                }
               
               
               
                let tunnelProtocol = NETunnelProviderProtocol()
                tunnelProtocol.serverAddress = ""
                tunnelProtocol.providerBundleIdentifier = "com.vpn.xxx.TunnelManager";
               
                tunnelProtocol.providerConfiguration = ["ovpn": configurationFileContent]
               
                manager.protocolConfiguration = tunnelProtocol
                manager.localizedDescription = "My VPN"
               
                manager.isEnabled = true
               
                /
                manager.saveToPreferences(completionHandler: { (error) in
                    if let error = error  {
                        print(error);
                    }
                    manager.loadFromPreferences(completionHandler: {(error) in
                        do
                        {
                            try manager.connection.startVPNTunnel();
                        }
                        catch
                        {
                            NSLog("Unexpected error: \(error).");
                        }
                    })
                });
            }


I changed the blunde identifier for privacy reasons.


I hope somebody can help me with my problem, if you need the contents of another file, or any other information, please ask.

Thanks in advance.

,Additional info:


I'm using XCode 9.3

My deployment target is IOS 9.0, I tried running the app in IOS 9.0 and 11.


I'm observing the connection status with NEVPNStatusDidChange, it starts in connecting, and inmediatly goes to disconnected.


Debug and NSLogs from my provider don't work. I suspect my target is not beign called.


If you need more info please tell me. Thanks in advance.


EDIT: As I suspected, looking at the device log, I get this message:


Failed to create an NSExtension with type com.vpn.xxx.TunnelManager: (null)

EDIT: As I suspected, looking at the device log, I get this message …

Most problems like this are caused by packaging issues. There’s a standard list of things I check here:

  • The entitlements of both the host app and the provider — Make sure to check the entitlements of the built binary, not the .entitlements file (which is just one of the inputs to the code signing process).

    Note For this step and the next, you can find detailed instructions in my Debugging Entitlement Issues post.

  • The entitlements whitelisted in the provisioning profile.

  • The bundle ID of both the host app and the provider

    IMPORTANT The provider’s bundle ID must be an immediate child of the host app’s bundle ID, for example, com.example.MyApp and com.example.MyApp.MyProvider.

  • The NSExtension dictionary within the Info.plist of the provider — Specifically:

    • Make sure NSExtensionPointIdentifier is com.apple.networkextension.packet-tunnel

    • Make sure NSExtensionPrincipalClass is correct, including the leading if you’re using Swift for your provider

    Again, make sure to check this is the built binary, not in your your source code. iOS runs your binary, not your source (-:

If that all checks out I add a log statement to the first line of the provider’s initialiser

class MyProvider : NEPacketTunnelProvider {

    override init() {
        NSLog("QQQ provider init")
        … stuff …
        super.init()
        … more stuff …
    }

    … even more stuff …
}

I then look for that log to see if the provider was loaded at all.

Share and Enjoy

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

Can't get NEPacketTunnelProvider to work
 
 
Q