NEVPNConnectionErrorDomainPlugin error code 7

i am using the network extension to connecting my ikev2 server


but it always disconnect from server after I call the startVPNTunnal function , and the last connection error information shows like below


_lastDisconnectError NSError * domain: NEVPNConnectionErrorDomainPlugin- code: 7 0x0000000283a5da70


my code is like this



fileprivatefunc connect() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(1 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) {
            self.vpnManager.loadFromPreferences { (error) in
      
                if let error = error {
                    print(error.localizedDescription)
                    self.delegate?.vpnConnectionStatusDidChanged(manager: self, status: .invalid)
                    return
                }
      
                do {
                    try self.vpnManager.connection.startVPNTunnel()
                    print("success")
                } catch let error{
                    print("failed: " + error.localizedDescription)
                    self.delegate?.vpnConnectionStatusDidChanged(manager: self, status: .disconnected)
                }
      
            }
        }
    }


func savePassword(_ password: String, inKeychainItem: Data?) -> Data? {
        guard let passwordData = password.data(using: String.Encoding.utf8, allowLossyConversion: false) else { return nil }
        var status = errSecSuccess
  
        if let persistentReference = inKeychainItem {
            // A persistent reference was given, update the corresponding keychain item.
            let query: [NSObject: AnyObject] = [
                kSecValuePersistentRef : persistentReference as AnyObject,
                kSecReturnAttributes : kCFBooleanTrue
            ]
            var result: AnyObject?
      
            // Get the current attributes for the item.
            status = SecItemCopyMatching(query as CFDictionary, &result)
      
            if let attributes = result as? [NSObject: AnyObject] , status == errSecSuccess {
                // Update the attributes with the new data.
                var updateQuery = [NSObject: AnyObject]()
                updateQuery[kSecClass] = kSecClassGenericPassword
                updateQuery[kSecAttrService] = attributes[kSecAttrService]
          
                var newAttributes = attributes
                newAttributes[kSecValueData] = passwordData as AnyObject?
          
                status = SecItemUpdate(updateQuery as CFDictionary, newAttributes as CFDictionary)
                if status == errSecSuccess {
                    return persistentReference
                }
            }
        }
  
        if inKeychainItem == nil || status != errSecSuccess {
            // No persistent reference was provided, or the update failed. Add a new keychain item.
      
            let attributes: [NSObject: AnyObject] = [
                kSecAttrService : UUID().uuidString as AnyObject,
                kSecValueData : passwordData as AnyObject,
                kSecAttrAccessible : kSecAttrAccessibleAlways,
                kSecClass : kSecClassGenericPassword,
                kSecReturnPersistentRef : kCFBooleanTrue
            ]
      
            var result: AnyObject?
            status = SecItemAdd(attributes as CFDictionary, &result)
      
            if let newPersistentReference = result as? Data , status == errSecSuccess {
                return newPersistentReference
            }
        }
        return nil
    }


func connect(vpn_protocol:SGVPNProtocol, ip: String, username: String, password: String, psk: String) {
    
        vpnManager.loadFromPreferences { (error) in
        
            if error != nil {
                print("Load error: \(error?.localizedDescription as String?)")
                return
            } else {

                let configuration = NEVPNProtocolIKEv2()
            
                configuration.username = username
                configuration.passwordReference =  self.savePassword(password, inKeychainItem: nil)
                configuration.authenticationMethod = .none
                configuration.useExtendedAuthentication = true
                configuration.disconnectOnSleep = false
           
                configuration.serverAddress = ip
                configuration.remoteIdentifier = ip
                configuration.localIdentifier = ""

                self.vpnManager.protocolConfiguration = configuration
                self.vpnManager.localizedDescription = "xxxx"
                self.vpnManager.isEnabled = true
                self.vpnManager.isOnDemandEnabled = false

                self.vpnManager.saveToPreferences(completionHandler: { (error) in
                    if error != nil {
                        print(error!.localizedDescription)
                        self.delegate?.vpnConnectionStatusDidChanged(manager: self, status: SGVPNStatus.invalid)
                        return
                    }
                
                    self.vpnManager.loadFromPreferences(completionHandler: { error in
                        self.connect()
                    })
                })
            
            }
        }
    }


error information:



Printing description of self.vpnManager._connection->_lastDisconnectError:

Error Domain=NEVPNConnectionErrorDomainPlugin Code=7 "The VPN session failed because an internal error occurred." UserInfo={NSLocalizedDescription=The VPN session failed because an internal error occurred.}

(lldb)




i have done the capacities setting for Personer VPN and Network Extension

Replies

i am using the network extension to connecting my ikev2 server but it always disconnect from server after I call the startVPNTunnal function

First things first, if you set up this VPN configuration via a configuration profile, does that work?

You can use Apple Configurator to create and install such a profile.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

hi


I use this server on my mac, ios, and windows. all these works good


how to use Apple Configurator to create a vpn profile? any tutoral ?


i use different apple id on my phone, and I added that account to apple development device. but I cant access the "device register plan" in the prepare page of Apple Configurator

how to use Apple Configurator to create a vpn profile?

Try this:

  1. Run Configurator.

  2. Choose File > New Profile.

  3. Set up the General slice.

  4. Switch to the VPN slice.

  5. Click Configure.

  6. Set up the VPN slice.

  7. Choose File > Close and save it somewhere convenient.

  8. Attach your device via USB.

  9. Drag the profile from the Finder and drop it on your device in Configurator’s All Devices window.

  10. Run through the installation workflow on the device.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

the vpn connection works fine in this way

the vpn connection works fine in this way

Excellent news.

Did you use just a VPN payload (

com.apple.vpn.managed
)? Or did you need to add some other payload type? Like perhaps
com.apple.security.root
?

If you only used a VPN payload, you should be able to create an equivalent configuration programmatically using

NEVPNManager
. If you post the VPN payload (make sure to redact the password), I’ll reply back with some advice on how to set that up.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I posted all the code for my connection configuration above


i am using the vnp manager provicded by ios to build the connection configuration, and use manager.startVPNTunnal() to start the connection.


the problem is I always go discconnecting notification after I call startvontunnal(), and also there is an internal error


Printing description of self.vpnManager._connection->_lastDisconnectError:

Error Domain=NEVPNConnectionErrorDomainPlugin Code=7 "The VPN session failed because an internal error occurred." UserInfo={NSLocalizedDescription=The VPN session failed because an internal error occurred.}

I posted all the code for my connection configuration above

Right. I was hoping you’d be be able to post the configuration profile here (it’s a bunch of XML), because then I can check your code (which doesn’t work) against your profile (which does).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

sure




<plist version=1.0>

<dict>

<key>PayloadContent</key>

<array>

<dict>

<key>IKEv2</key>

<dict>

<key>AuthName</key>

<string>vpn77</string>

<key>AuthPassword</key>

<string>a123456</string>

<key>AuthenticationMethod</key>

<string>None</string>

<key>ChildSecurityAssociationParameters</key>

<dict>

<key>DiffieHellmanGroup</key>

<integer>14</integer>

<key>EncryptionAlgorithm</key>

<string>AES-256</string>

<key>IntegrityAlgorithm</key>

<string>SHA2-256</string>

<key>LifeTimeInMinutes</key>

<integer>1440</integer>

</dict>

<key>DeadPeerDetectionRate</key>

<string>Medium</string>

<key>DisableMOBIKE</key>

<false/>

<key>DisableRedirect</key>

<false/>

<key>EnableCertificateRevocationCheck</key>

<false/>

<key>EnablePFS</key>

<false/>

<key>ExtendedAuthEnabled</key>

<true/>

<key>IKESecurityAssociationParameters</key>

<dict>

<key>DiffieHellmanGroup</key>

<integer>14</integer>

<key>EncryptionAlgorithm</key>

<string>AES-256</string>

<key>IntegrityAlgorithm</key>

<string>SHA2-256</string>

<key>LifeTimeInMinutes</key>

<integer>1440</integer>

</dict>

<key>LocalIdentifier</key>

<string>test.xxxx.cc</string>

<key>RemoteAddress</key>

<string>test.xxxx.cc</string>

<key>RemoteIdentifier</key>

<string>test.xxxx.cc</string>

<key>UseConfigurationAttributeInternalIPSubnet</key>

<false/>

</dict>

<key>IPv4</key>

<dict>

<key>OverridePrimary</key>

<integer>0</integer>

</dict>

<key>PayloadDescription</key>

<string>xx VPN xx</string>

<key>PayloadDisplayName</key>

<string>VPN</string>

<key>PayloadIdentifier</key>

<string>com.apple.vpn.managed.CA518586-9AFF-44D1-9E87-F3F0F29C7B8E</string>

<key>PayloadType</key>

<string>com.apple.vpn.managed</string>

<key>PayloadUUID</key>

<string>CA518586-9AFF-44D1-9E87-F3F0F29C7B8E</string>

<key>PayloadVersion</key>

<integer>1</integer>

<key>Proxies</key>

<dict>

<key>HTTPEnable</key>

<integer>0</integer>

<key>HTTPSEnable</key>

<integer>0</integer>

</dict>

<key>UserDefinedName</key>

<string>yyyy</string>

<key>VPNType</key>

<string>IKEv2</string>

</dict>

</array>

<key>PayloadDisplayName</key>

<string>vpnxxx</string>

<key>PayloadIdentifier</key>

<string>yangdeMac-mini.7BF5D337-3CE4-4A1D-A7EB-1B927B9E5C86</string>

<key>PayloadRemovalDisallowed</key>

<false/>

<key>PayloadType</key>

<string>Configuration</string>

<key>PayloadUUID</key>

<string>45F439D6-BEA8-4227-BF1D-6C2CC41E680A</string>

<key>PayloadVersion</key>

<integer>1</integer>

<key>RemovalDate</key>

<date>2019-07-17T03:16:10Z</date>

</dict>

</plist>

Thanks for the profile. Here’s how those settings map to

NEVPNManager
properties:
NEVPNManager
  localizedDescription: 'yyyy'
  isEnabled: true
  isOnDemandEnabled: false
  onDemandRules.count: nil
NEVPNProtocol
  serverAddress: 'vpn.example.com'
  username: 'vpn77'
  passwordReference: 'a123456'
  identityReference: nil
  identityData: nil
  identityDataPassword: nil
  disconnectOnSleep: false
  proxySettings: nil
NEVPNProtocolIPSec
  authenticationMethod: .none
  useExtendedAuthentication: true
  sharedSecretReference: nil
  localIdentifier: 'vpn.example.com'
  remoteIdentifier: 'vpn.example.com'
NEVPNProtocolIKEv2
  deadPeerDetectionRate: .medium
  serverCertificateIssuerCommonName: nil
  serverCertificateCommonName: nil
  certificateType: .RSA
  useConfigurationAttributeInternalIPSubnet: false
  IKESecurityAssociationParameters: AES256, SHA256, group14, 1440
  childSecurityAssociationParameters: AES256, SHA256, group14, 1440
  disableMOBIKE: false
  disableRedirect: false
  enablePFS: false
  enableRevocationCheck: false
  strictRevocationCheck: false

Note Many of these are default values, so you can simplify things by checking the initial value of a property before you add extra code to explicit set it.

One possible gotcha here is the credential, in this case your password. This requires that you pass in a persistent reference to a keychain item, and lots of folks run into problems doing that. For a simple example of how to do it right, check out the code in this post.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

hi

thanks so much, could u remove the server and username password from your reply. thats was my bad




I modified these code, but the unknow error still occured




import Foundation

import NetworkExtension//import SGVPN

import Security

import KeychainAccess

//import vpnStatusChange


public class SGVPNManager: NSObject {


static let shared = SGVPNManager()

private var vpnManager = NEVPNManager.shared()

weak var delegate: SGVPNManagerDelegate?


override init() {

super.init()

NotificationCenter.default.addObserver(self, selector: #selector(vpnConfigurationDidChanged(notification:)), name: .NEVPNConfigurationChange, object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(vpnStatusDidChanged(notification:)), name: .NEVPNStatusDidChange, object: nil)

}


@objc

public func vpnConfigurationDidChanged(notification: Notification) {

self.connect()

}


@objc

func vpnStatusDidChanged(notification: Notification) {

let status = SGVPNStatus(rawValue: vpnManager.connection.status.rawValue)!

delegate?.vpnConnectionStatusDidChanged(manager: self, status: status)

}


fileprivate func connect() {

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(1 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) {

self.vpnManager.loadFromPreferences { (error) in

self.vpnManager.loadFromPreferences { (error) in

if error != nil {

print(error?.localizedDescription)

self.delegate?.vpnConnectionStatusDidChanged(manager: self, status: .invalid)

return

}

do{

try self.vpnManager.connection.startVPNTunnel()

}catch let error{

print("vpn failed" + error.localizedDescription)

self.delegate?.vpnConnectionStatusDidChanged(manager: self, status: .disconnected)

}

}

}

}

}


var isConnected: Bool {

get {

return vpnManager.connection.status == .connected

}

}

var isConnecting: Bool {

get {

return vpnManager.connection.status == .connecting

}

}

var isDisconnected: Bool {

get {

return vpnManager.connection.status == .disconnected

}

}

var isDisconnecting: Bool {

get {

return vpnManager.connection.status == .disconnecting

}

}


func preLoadPreferences() {

vpnManager.loadFromPreferences { (error) in

if let error = error {

print(error.localizedDescription)

return

}

}

}



/// Save a password in the keychain.

func savePassword(_ password: String, inKeychainItem: Data?) -> Data? {

guard let passwordData = password.data(using: String.Encoding.utf8, allowLossyConversion: false) else { return nil }

var status = errSecSuccess

if let persistentReference = inKeychainItem {

// A persistent reference was given, update the corresponding keychain item.

let query: [NSObject: AnyObject] = [

kSecValuePersistentRef : persistentReference as AnyObject,

kSecReturnAttributes : kCFBooleanTrue

]

var result: AnyObject?

// Get the current attributes for the item.

status = SecItemCopyMatching(query as CFDictionary, &result)

if let attributes = result as? [NSObject: AnyObject] , status == errSecSuccess {

// Update the attributes with the new data.

var updateQuery = [NSObject: AnyObject]()

updateQuery[kSecClass] = kSecClassGenericPassword

updateQuery[kSecAttrService] = attributes[kSecAttrService]

var newAttributes = attributes

newAttributes[kSecValueData] = passwordData as AnyObject?

status = SecItemUpdate(updateQuery as CFDictionary, newAttributes as CFDictionary)

if status == errSecSuccess {

return persistentReference

}

}

}

if inKeychainItem == nil || status != errSecSuccess {

// No persistent reference was provided, or the update failed. Add a new keychain item.

let attributes: [NSObject: AnyObject] = [

kSecAttrService : UUID().uuidString as AnyObject,

kSecValueData : passwordData as AnyObject,

kSecAttrAccessible : kSecAttrAccessibleAlways,

kSecClass : kSecClassGenericPassword,

kSecReturnPersistentRef : kCFBooleanTrue

]

var result: AnyObject?

status = SecItemAdd(attributes as CFDictionary, &result)

if let newPersistentReference = result as? Data , status == errSecSuccess {

return newPersistentReference

}

}

return nil

}


func connect(vpn_protocol:SGVPNProtocol, ip: String, username: String, password: String, psk: String) {


self.vpnManager.loadFromPreferences { (error) in

if error != nil {

print("Load error: \(error?.localizedDescription as String?)")

return

} else {

let configuration = NEVPNProtocolIKEv2()

configuration.serverAddress = ip

configuration.remoteIdentifier = ip

configuration.username = username

do {

try configuration.passwordReference = VPNKeychain.persistentReferenceFor(service: "com.xcom.flashspeedup", account: "com.xcom.flashspeedup", password: password.data(using: .ascii)!) //self.savePassword("a123456", inKeychainItem: nil)

}catch(let e){

print("persitant password error: \(e)")

}

configuration.authenticationMethod = .none

configuration.useExtendedAuthentication = true

configuration.sharedSecretReference = nil

configuration.localIdentifier = ip

configuration.remoteIdentifier = ip

configuration.identityReference = nil

configuration.identityData = nil

configuration.identityDataPassword = nil

configuration.disconnectOnSleep = false

configuration.proxySettings = nil

configuration.deadPeerDetectionRate = .medium

configuration.serverCertificateIssuerCommonName = nil

configuration.serverCertificateCommonName = nil

configuration.certificateType = .RSA

configuration.useConfigurationAttributeInternalIPSubnet = false

//configuration.ikeSecurityAssociationParameters = AES256, SHA256, group14, 1440

//configuration.childSecurityAssociationParameters = AES256, SHA256, group14, 1440

configuration.disableMOBIKE = false

configuration.disableRedirect = false

configuration.enablePFS = false

configuration.enableRevocationCheck = false

configuration.strictRevocationCheck = false

self.vpnManager.protocolConfiguration = configuration

self.vpnManager.localizedDescription = "speedup"

self.vpnManager.isEnabled = true

self.vpnManager.isOnDemandEnabled = false

self.vpnManager.connection.stopVPNTunnel()// = NEVPNConnection()

self.vpnManager.saveToPreferences(completionHandler: { (error) in // saveToPreferences

if error != nil {

print(error!.localizedDescription)

self.delegate?.vpnConnectionStatusDidChanged(manager: self, status: SGVPNStatus.invalid)

return

}

})

}

}

}


func disconnect() {

self.vpnManager.connection.stopVPNTunnel()

self.remove()

}



func remove() {

self.vpnManager.removeFromPreferences { (error) in

if let error = error {

print(error.localizedDescription)

return

}


if UserDefaults.standard.bool(forKey: "FIST_CONNECT_VPN") {

UserDefaults.standard.set(false, forKey: "FIST_CONNECT_VPN")

}

}

}

}



I am not sure it this the correct way to use your keychain function,


let password = "123456"
do {
     try configuration.passwordReference = VPNKeychain.persistentReferenceFor(service: "password", account: "password", password: password.data(using: .utf8)!)
}catch(let e){
      print("persitant password error: \(e)")
}



The problem is on the configuration because I cant build connection for this configuration in the setting page after saveToPreference

could u remove the server and username password from your reply.

I have done so, replacing it with

vpn.example.com
.

IMPORTANT Your Apr 22 post has the server name in it as well, so you’ll want to edit that.

I modified these code, but the unknow error still occured

OK, I’m out of ideas, or at least ideas that I can try here on DevForums. My recommendation is that open a DTS tech support incident and we can discuss this in private.

In your initial request, please:

  • Reference this DevForums thread

  • Emphasise that you have a configuration profile that works

Then, when you get the auto ACK, reply to that with an email that has your configuration profile attached. Make sure it’s a profile that I can install and test, not the redacted one that you posted here.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

yeah that was my bad


how much we should pay for the DTS support? or its free?


why we cant post image here ...... I have screenshot for the iphone log which said there is an internal error

how much we should pay for the DTS support? or its free?

You can find that information on the page I linked to in my previous post.

why we cant post image here

*sigh* I wish I had a good answer for that.

Having said that…

I have screenshot for the iphone log which said there is an internal error

posting screen shots of log messages is generally a bad idea because it means that folks reading your post have to type in the log message if, say, they want to quote your message, or search the headers for matching values, or whatever. It’s much better to post log messages as text.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

It may be that there are some code execution errors in PacketTunnelProvider, which should not exist, causing exceptions in the extension program, such as some shared data codes. Shared data can use NSUserDefaults or handleAppMessage.You must open App Groups. Hope this answer is helpful