in iOS

Configure and manage VPN connections programmatically in iOS 8

Update 3: If you’re going to create an on-demand VPN connection, checkout my article about creating on-demand VPN connection programmatically in iOS 8 after reading this.

Update 2: The beta 5 issue has been fixed in the GM release. Everything is currently working just fine.

Update: This solution does not work on iOS 8 beta 5 due to a weird “Missing name” issue; however, it works find on iOS 8 beta 1 to 4. If you know anything new about managing the VPN connections in iOS 8, let me know by commenting down below.

Connecting to VPN servers programmatically had been always an impossible task to do for developers because of Apple’s limitations.

In my previous post I’ve described that Apple introduced a brand-new Network Extension framework which gives developers the opportunity to configure VPN preferences programmatically but I didn’t describe how!

This post is a guide to manage VPN configurations in iOS 8 and OS X (10.10) Yosemite while there’s no official documentation published yet. I Also have to thank quellish who helped me a lot in this.

Requirements

  1. The very first and the most critical things you need is an actual device with iOS 8 beta 1 or above to test the app on! This tutorial cannot be tested on iPhone simulator. If you’re going to write a Mac application, OS X Yosemite Preview 3 or above has to be installed.
  2. Since this test doesn’t work on simulator, you have to be a member of iOS/Mac developer program. Also, you need to make some changes to your provisioning profile. You cannot use your iOS 7 provisioning profiles to develop iOS 8 VPN applications.
  3. Xcode 6 beta. By the time of this post (August 2nd, 2014), Xcode 6 is in beta 4 and just like I’ve mentioned in my previous post, you need to to a member of iOS/Mac program to have access to beta tools.
  4. Last but absolutely not least, you need a Mac since Xcode cannot be run on Windows or Linux machines.

Getting Started

The first thing you need to do before actually start writing any codes is to update your provisioning profiles. If you haven’t created any profiles yet, you need to create one now! To do this, login to your developer account, then click on “Certificate, Identifiers & Profiles”:

Provisioning profile update

Select Identifiers, then select the application you want to update its provisioning profile. If you don’t have any, you can create one using the plus sign. By selecting an app, a list will be appeared. This is a list of features the app is going to use, for example if you want to have iCloud functionality in your application, you have to turn iCloud feature on; otherwise, you won’t be able to test and deploy your iCloud based apps. The following is showing that list:

Identifiers list

By the introduction of iOS 8, a new item has been added to this list which is “VPN Configuration & Control”. This is exactly what we’re looking for! So enable this feature by clicking on it and then ticking its checkbox. When you turn this feature on a modal window will be displayed which describes its functionality:

Enable VPN Config

Enable VPN Configuration & Control feature and click “Done”. Then, download the provisioning profile again and replace it with the old one. We’re done here, now lets get back to Xcode.

Note: In this post I assume that you’re familiar with iOS development and Objective-C. If you’ve never developed any app in for iOS or Mac, you may need to learn some basic concepts and then return to this post.

Open Xcode and create a new iOS 8 single view application project. Then, place a button in the middle of screen and then connect it to your ViewController.

What we’re going to do is to setup VPN preferences on viewDidLoad: method and then connect to our specified VPN server when the button is tapped.

Before getting started, you have to know how all this work! If you understand the structure of Network Extension framework, then it will be much easier to develop apps based on it.

NetworkExtension.framework

Apple has done a brilliant job developing this framework. Every app can access system preferences but in its own sandbox; which means you cannot access other apps’ sandboxes.

First of all, saved preferences have to be loaded from OS to be able to be accessed. Once they’re loaded, it’s possible to make your changes. After changes have been made, they need to be saved. Unsaved preferences won’t be applied. Your app’s preferences can also be removed if you no longer need them. As a result, to create a VPN configuration we need to do the following:

  • Load our app’s preferences
  • Make our changes
  • Save preferences

Note that you need to load your app’s preferences even if you haven’t set any configuration yet.

After VPN connection is created we can connect to or disconnect from it.

Network extension contains three major classes:

  • NEVPNManager
  • NEVPNProtocol
  • NEVPNConnection

NEVPNManager is the most important class in this framework. It’s responsible for load, save and remove preferences. In fact, all VPN tasks have to be done through this class.

Create a new VPN connection

To get started a new instance of this class has to be created:

NEVPNManager *manager = [NEVPNManager sharedManager];

After NEVPNManager is initialized, system preferences can be loaded using loadFromPreferencesWithCompletionHandler: method:

[manager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
    // Put your codes here...
}];

As I’ve mentioned in above code, the load method accepts a compilation handler block. This block is fired whenever the load process is completed. This block also has a parameter which is an NSError. the NSError parameter will be nil if the loading operation completed; otherwise, it will be non-nil. Accordingly:

[manager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
    if(error) {
        NSLog(@"Load error: %@", error);
    } else {
        // No errors! The rest of your codes goes here...
    }
}];

After loading process is completed, It’s time to set up our VPN connection.

iOS 8 supports two major protocols. IPSec and IKEv2. It’s the first time that Apple offers IKEv2 protocol in its operating systems. This protocol is supported by all major operating systems including Android, Windows Phone, Windows Desktop, Linux and now iOS and Mac. In this post I’m going to talk about IPSec and in my next posts I’ll talk about IKEv2 as well. In addition to these protocols, Apple gives you the ability to create your own protocol if needed! This feature is a very important features for those who have implemented their own protocol; because now it’s possible to implement that protocol on iOS and Mac as well. OK, lets set up our IPSec protocol:

NEVPNProtocolIPSec *p = [[NEVPNProtocolIPSec alloc] init];
p.username = @"[Your username]";
p.passwordReference = [VPN user password from keychain];
p.serverAddress = @"[Your server address]";
p.authenticationMethod = NEVPNIKEAuthenticationMethodSharedSecret;
p.sharedSecretReference = [VPN server shared secret from keychain];
p.localIdentifier = @"[VPN local identifier]";
p.remoteIdentifier = @"[VPN remote identifier]";
p.useExtendedAuthentication = YES;
p.disconnectOnSleep = NO;

In the first line, I’ve created a new instance of NEVPNProtocolIPSec. This class is inherited from NEVPNProtocol class. NEVPNProtocol class is an abstract class you can use to create your own protocols.

Then, we specified our username and password in the second and third line. Notice that the password is a reference from Keychain; so, you need to store your password in Keychain first and then retrieve it.

The fourth line is our server address. Server address can be an IP, a host name or a URL.

Next is authentication method. iOS 8 supports three authentication methods

  • NEVPNIKEAuthenticationMethodNone: Do not authenticate with IPSec server.
  • NEVPNIKEAuthenticationMethodCertificate: Use a certificate and private key as the authentication credential.
  • NEVPNIKEAuthenticationMethodSharedSecret: Use a shared secret as the authentication credential.

As you can see, I’ve used Shared Secret method; but, you can use whatever method you want.

The next line is Shared Secret reference. Again it’s reference from Keychain; so, you need to get Shared secret from there. If you’re going to use certificate rather than shared secret. There’s no need to fill sharedSecretReference property; instead, you have to fill identityData property. Identity data is the PKCS12 data for the VPN authentication identity. The value for this property must be a NSData in PKCS12 format:

p.identityData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"clientCert" ofType:@"p12"]];

The next two lines are local and remote identifiers. These two are strings identifying the local and remote IPSec endpoints for authentication purposes.

The next property we need to set is useExtendedAuthetication. This is a flag indicating if extended authentication will be negotiated. This authentication is in addition to the IKE authentication used to authenticate the endpoints of the IKE session. For IKE version 1, when this flag is set X-Auth authentication will be negotiated as part of the IKE session, using the username and password properties as the credential. For IKE version 2, when this flag is set EAP authentication will be negotiated as part of the IKE session, using the username, password, and/or identity properties as the credential depending on which EAP method the server requires.

The last property to set is disconnectOnSleep. This boolean indicates whether the VPN connection must be disconnected when the device goes to sleep or not.

OK that’s enough for protocol. The next thing we have to do is to assign the protocol we’ve just created to the VPN manager. To do so, the setProtocol: method can be used.

[manager setProtocol:p];

IPSec and IKEv2 protocols have a very cool feature called On-demand. This feature enable connect to connect automatically whenever user attempted to connect to the internet. In iOS 8, it’s possible to enable on-demand on the connection. But, I’m going to cover this feature in another post; therefore, lets leave it for now and set the onDemandEnabled property to NO for now.

[manager setOnDemandEnabled:p];

The last thing we must set is the description of VPN preference we’re going to create. To do so, just set its localized description property by using setLocalizedDescription: method

[manager setLocalizedDescription:@"[You VPN configuration name]"];

We’re almost done. We’ve set up the configuration but haven’t saved it yet. To save the configuration simply call the saveToPreferencesWithCompletionHandler: method:

[manager saveToPreferencesWithCompletionHandler:^(NSError *error) {
    if(error) {
        NSLog(@"Save error: %@", error);
    }
    else {
        NSLog(@"Saved!");
    }
}];

This method simply saves your specified configuration to the system settings.

Connect to the VPN connection we’ve just created

Now that you’ve saved your settings to system’s preferences, it’s time to connect to it. NEVPNManager has a property called connection. This property is an object of NEVPNConnection class. It hold information which is responsible for VPN connection. To connect to VPN server you’ve just created, simply call startVPNTunnelAndReturnError: method of NEVPNConnection class just like below:
Run the application on your device and you’ll see and new connection will be create and you can connect to it by tapping the button. Also, you can disconnect from VPN server programmatically as well by calling stopVPNTunnel method of NEVPNConnection:

- (IBAction)buttonPressed:(id)sender {
    NSError *startError;
    [[NEVPNManager sharedManager].connection startVPNTunnelAndReturnError:&startError];
    
    if(startError) {
        NSLog(@"Start error: %@", startError.localizedDescription);
    } else {
        NSLog(@"Connection established!");
    }
    
}

If you have any idea, suggestion or anything else regarding this post, please leave your comments down below. I’ll blog about IKEv2 and On-demand features in the near future. Stay tuned.

  • Ben

    How are you retrieving the password from the keychain? I’ve stored the password for my account in the keychain, and I have tried retrieving the persistent reference (which the docs imply are necessary) into the protocol.passwordReference field but it still prompts me for a password when I go to connect to the VPN service (once I enter it, it connects, so everything else seems good).

    • ramezanpour

      I have this issue as well. I’m working on it. Please let me know if you found anything interesting.

      • Ben

        Glad to know I’m not alone on that one! I’ve been filing Radar reports on the VPN (dis)functionality in iOS 8 and I’ll put that one in as well!

      • zqqf16

        I resolved this problem by using “[searchDictionary setObject:@YES forKey:(__bridge id)kSecReturnPersistentRef];”
        🙂

        • ramezanpour

          Can you test the functionality in iOS 8 beta 5? As you may know, there’s a “missing name” error around.

          • I didn’t get the “missing name” error in beta 5.

            I write a simple demo at https://gist.github.com/zqqf16/cbcbd2254e6cb965f1a3

          • ramezanpour

            I copied and paste your code to a new application but It still returns “missing name” error. Have you ever tested this on a real device?

          • Yes, I have test it on my iPhone 5 and 5s.

          • ramezanpour

            Then can you please tell me what exactly have you done?

          • mobilemann

            he’s literally just shown you a git hub project lol

          • ramezanpour

            For you considration, the github project just copied my code 🙂

          • mobilemann

            oops. I’ll be quite now.

          • ramezanpour

            🙂

    • guest

      Did any of you get the solution for this problem?

  • Lev Stipakov

    Does it work for beta 5?

    My code (similar to yours) was working fine until beta5, and now I got

    > Error Domain=NEConfigurationErrorDomain Code=2 “Missing name” UserInfo=0x170078940 {NSLocalizedDescription=Missing name}

    I am a bit stuck.

    • Ben

      I ran into that once I started using two applications with VPN entitlements. The first worked and the second didn’t.

      I suspect there’s an issue with having more than one app with VPN entitlements but I never figured out exactly the issue.

      • ramezanpour

        I get this error when I try to save the VPN configuration using NEVPNIKEAuthenticationMethodCertificate authentication method. Everything works fine when using NEVPNIKEAuthenticationMethodNone or NEVPNIKEAuthenticationMethodSharedSecret. It seems there’s another property we have to set. Any idea?

      • Lev Stipakov

        I tested again with single VPN app on the device (tried iPad Mini and iPhone 4s), got the same error message.

        • ramezanpour

          Any solution for “Missing name” issue?

          • Lev Stipakov

            Nope. I am aggressively waiting for beta 6.

    • Bernd

      For me the same! Also “Missing Name” @beta5

      • ramezanpour

        Did you find anything to solve this problem?

        • obelixsix

          Now that Gold Master is out has anyone tested?

  • vishal

    I am getting error NEConfigurationErrorDomain Code=2 “Missing name” and cannot continue further to saveToPreference!! Any one has any solutions.?

  • anon8mizer

    After you set up the VPN connection, does it make all network traffic from only this app to go through the VPN tunnel, or does this force all network traffic from other apps on the device to go through this tunnel as well? Thx.

    • ramezanpour

      Haven’t tested it yet. Do you have any problems with it?

      • Erik Villegas

        I have the same question as anon8mizer. If my app crashes and doesn’t get a chance to close the VPN connection, does the phone and other apps continue to use the VPN? I’m looking to integrate VPN only for network requests originating from my app.

        • ramezanpour

          1) VPN configuration is saved in system settings; as a result, your connection won’t be killed if your app crashes.
          2) You need to create an appropriate on-demand rule to achieve this.

  • Sumaiya

    Hey… I am facing an issue , i get an error [The operation couldn’t be completed. (NEVPNErrorDomain error 1.)] on startVPNTunnelAndReturnError

    can some one help me here? VPN is not connecting at all.

    • Timur Suleimanov

      not sure if that’s still actual, but you should try to load preferences before connecting to VPN

  • hdu

    Are you aware of any changes of the on-demand rules in iOS8? I found that it requires a multi-level domain matches in iOS8. For example, match http://www.abc.com with abc.com instead of .com

    • ramezanpour

      On-demand rules can be set to accept all urls.

  • Mircea

    Do you have any knowledge regarding integration with the openVPN protocol?

    • ramezanpour

      IPSec v1 and v2 are implemented built-in; although, you can implement your own protocol if you want.

      • K

        Do you have any pointers about implementing a custom protocol using NEVPNProtocol? I’d like to do this but can’t seem to find what methods to implement or any examples.

        • ramezanpour

          As far as I know, there’s no documentation about it yet.

          • Camilo Aguilar

            @ramezanpour:disqus have you have anything related to create your own openvpn protocol? Maybe extending NEVPNProtocol

          • ramezanpour

            As far as I know, there are new features in iOS 9 which can be used to developed a custom VPN protocol. As a result, it looks possible to create the OpenVPN protocol as well.

          • Alex Wayne

            Hello! I have a small question concerning VPN. Is there a way to detect VPN programmatically in iOS?

          • Alex Wayne

            Hello! I have a small question concerning VPN. Is there a way to detect VPN programmatically in iOS?

  • Sumaiya

    And also i get this error when i save the configuration : [Missing identity]… anybody facing the same issue? i am testing on iOS GM seed

    • ramezanpour

      [NEVPNManager sharedManager] setIdentityData:];

      • Sumaiya

        After loading the preferences and configuring the IPSec protocol when save preferences is called i am getting error is Missing Identity.
        Is my configuration wrong?

        if (error) {

        NSLog(@”Load config failed [%@]”, error.localizedDescription);

        return;

        }

        if (self._vpnManager.protocol) {

        // config exists

        NSLog(@”configuration already exits”);

        }

        // config IPSec protocol

        NEVPNProtocolIPSec *p = [[NEVPNProtocolIPSec alloc] init];

        p.username = @”test1″;

        // get password persistent reference from keychain

        NSString *srchkey= @”VPNPassword”;

        NSData * srchdata =[keychain find:srchkey];

        if(srchdata == nil)

        {

        NSLog(@”Keychain data not found”);

        }

        else

        {

        NSLog(@”Data is =%@”,[[NSString alloc] initWithData:srchdata encoding:NSUTF8StringEncoding]);

        }

        p.passwordReference = [keychain find:srchkey];

        p.serverAddress = @”vpn.mediainsiderspanel.com”;

        // PSK

        p.authenticationMethod = NEVPNIKEAuthenticationMethodCertificate;

        p.identityData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@”clientCert”ofType:@”p12″]];

        p.identityDataPassword = @”samuser1″;

        p.localIdentifier = @”client.mediainsiderspanel.com”;

        p.remoteIdentifier = @”vpn.mediainsiderspanel.com”;

        p.useExtendedAuthentication = YES;

        p.disconnectOnSleep = NO;

        self._vpnManager.protocol = p;

        self._vpnManager.localizedDescription = @”IPSec Demo”;

        self._vpnManager.onDemandEnabled = p;

        [self._vpnManager saveToPreferencesWithCompletionHandler:^(NSError *error) {

        NSLog(@”Save config failed [%@]”, error.localizedDescription);

        }];

        }];

        Is there anything that i am missing can someone help me out in solving this issue?

        • Sowmya

          I am seeing the same ‘Missing Identity’ error when I try to save the configuration in the preferences. Any solution for this? (on iOS 8.2)

  • MajorG

    Do you know if it can be ‘signed’. The profile installation UI says

    Signed by : Not signed
    Description: Application-created VPN profile

    • ramezanpour

      I’m trying to find a solution for it too! If you find anything, please keep me posted as well 🙂

      • Stefan Manly

        Any update on this? Can’t ship my App only because of the unsigned profile. 🙁

      • Mircea

        Did you find any solution for this?

    • Timur Suleimanov

      have the same problem 🙁 seems like this produces other errors, so i can’t connect with certificate on IKEv2

  • Pingback: How to get persistent reference to a keychain item in iOS – Mohammad M. Ramezanpour()

  • Birajendu Sahu

    The profile saved using this connection manager class pops up the profile install dialog box. Is there a way to save the vpn profile with out profile install dialog box?

    • ramezanpour

      As far as I know, no! Apple needs user’s confirmation so the Profile Installation dialog must be shown.

      • Birajendu Sahu

        thanks

      • Ashok

        Is there any update on this issue?

  • Igor

    Is there any possibility to leverage L2TP protocol ? As far as it looks like there is only Cisco IPSec and IKEv2 and that is quite strange because in iOS VPN Settings where PPTP, L2TP additionally available.

    • ramezanpour

      There are APIs to implement both L2TP and PPTP protocols which are private. This means that it’s impossible to use these APIs in your applications. Only Apple is currently using these APIs.

      • Igor

        That is just so in Apple’s way. I spent some time investigating chances of implementation custom protocol by extending from abstract NEVPNProtocol and I have to admit that the amount of information provided just made me think this framework was made for Apple by Apple. There is nothing to find in headers.

        • ramezanpour

          This is almost true! Unfortunately, the information about NetworkExtension framework are very limit.

          • Igor

            $ nm /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/NetworkExtension.framework/NetworkExtension tells lots more regarding its internals

            Any way we are in the up hill position and therefor need wait a bit. I still having a hope that docs are just on its way to developers.

          • ramezanpour

            Lets see…

          • Mircea

            Any success implementing l2tp or pptp?

          • Igor

            l2tp or pptp are still considered as private API. To play a bit with that the old trick may work:

            NSBundle *b = [NSBundle bundleWithPath:@”/System/Library/Frameworks/NetworkExtension.framework”];

            [b load]; //BOOL success = [b load];

            Class NEVPNProtocolL2TP = NSClassFromString(@”NEVPNProtocolL2TP”);

            NEVPNProtocol *p = [[NEVPNProtocolL2TP alloc] init];

            // then just utilise “performSelector”
            [p performSelector:@selector(setSharedSecretReference:) withObject:sharedSecretData];

          • ashok

            Were you able to implement L2TP using the above trick?

          • tsiddiqui

            Does now Apple provides APIs to implement both L2TP and PPTP protocols ?

  • Alex

    Hey guys,

    Was anyone able to get “always on” vpn working ? p.disconnectOnSleep = NO does not work. VPN will disconnect a few moments after the screen goes off. I have tested it with IPSec PSK and Certificate setups, none works as expected. This was tested with iOS 8 and 8.0.2. None works as expected.

    VPN will be kept ON only if device is connected to charger. I haven’t tested IKEv2 vpn, maybe it’s intented to be used with IKEv2 only.

    Does anyone have a clue?

    Thanks

    • ramezanpour

      You may need to enable OnDemand feature by turning onDemandEnabled property and set an appropriate OnDemand rule. This should solve your issue 🙂

      • Talha

        do you have any idea or snippet for how to set on demand rules I have tried to set rules but didn’t get any success on it..

      • shiv

        Can u tell me if this VPN setup is per app vpn or device level vpn

    • Jonathan Aguele

      Hi alex, were you able to get this sorted out?

  • Bantu

    Does anyone have idea about how do we set on demand enable action property?
    I tried to set but it gives an error that it is a readonly property and its default value is 0 so it results in error “Invalid Action”, anyone for help?

  • Pingback: Create an on-demand VPN connection programmatically in iOS 8 – Mohammad M. Ramezanpour()

  • Eric

    What’s the VPN server used by you? Is it the strongSwan server? If so, would you please share more details about the server side configuration? Thanks a lot.

    • ramezanpour

      Sorry but I can’t publish server configurations. But yes, I am using strongSwan.

  • Oliver Spencer

    Thanks for the great code – however two questions. Firstly, when I install the profile, it always asks me for both the user password and Secret – regardless of whether I’ve entered them in the code.
    Also (and more importantly), how do I specify the Group Name of the VPN connection? Without this I continually get an error that the Secret Key is incorrect (as I do if I set the Group Name incorrectly in the iPhone VPN function in Settings). Thank you!

    • ramezanpour

      Your first question: I published a new post regarding it: http://ramezanpour.net/post/2014/09/26/how-to-get-persistent-references-to-keychain-items-in-ios/
      As far as I know, Group name is not an essential in connecting to an IPSec server and as far as I know, Apple hasn’t provided anything for it yet.

      • Oliver Spencer

        Thank you for the quick reply. Interesting point – unfortunately if I get the Group Name wrong the server rejects the connection. Odd that Apple don’t support it in this implementation as it’s a field in the IPSec config within the inbuilt VPN configuration settings – and it works fine as long as the Group Name is set correctly. Thanks for the link – will check out now. By the way, where did you get the info regarding your code? I’ve been struggling to find anything. In fact, I wanted to write the code in Swift, however it refused to allow me to use a manager.protocol = p command to set the protocol, I’m assuming it’s a problem with Apple’s code at this point (I keep getting the error s”expected member name following .” and “expected identifier in protocol declaration”.

        • Oliver Spencer

          Got it! If you set the localIdentifier to the Group Name, that appears to work 🙂

          • Dmitry Zbr

            thanks man!!! you saved my life!:)))

        • ramezanpour

          You can set your server to skip group name so you can connect from your app.
          Actually There’s no documentation for this framework yet. The only thing I used to achieve this is the NetworkExtension header files. This post the result of try and fail method ;). Also, Apple has provided a very limited documentation for each property and method.

        • Moritz Köchig

          It is possible to set the protocol property in swift. You have to do it manager.`protocol` = p. protocol is a protected identifier, so you have to put it in ` to access it.

      • Oliver Spencer

        It seems to be working fine now – apart from one thing: my authentication is via a Safeword token – i.e. one-time passwords that cannot be re-used. Whenever I try to set the one-time passcode programatically, the VPN still prompts for the password. Interestingly, whenever this is done, when I try to re-enter the same passcode into the dialog that appears, authentication fails which indicates the VPN has already used it although not connected and instead prompted again for the password; when I generate a new passcode it then works. It therefore looks like if you programmatically set password, it uses it multiple times (twice?) to log in. Is this something to do with the requirement to set the kSecReturnPersistentRef to YES, and, if I’m correct, is there any way to stop the VPN using the same password to login several times? Thanks again.

    • Jonathan Aguele

      Hi oliver, can you please share how you were able to set the password and shared secret in code, iv used ramezanpour code in his other post, but its not working for me, i keep getting “” unable to add item with key…” in the console. Any help/code will be helpful. Thanks

  • 朋 李

    this code leads me to add vpn profile,but it let me enter shared Secret for the vpn profile,why it appear,do i have a choice to skip it?

  • Dima Bobrov

    How can I add a group name?

  • Hunt3rDe

    Thanks, great manual, but I have one question:
    – how can I set group name at ipsec vpn protocol?
    My vpn gateway allows connections only with group name 🙁

    • ramezanpour

      As far as I know, IPSec protocol in iOS doesn’t have any group name property to set. IKEv2 has a CommonName property.

      • Hunt3rDe

        At iPad vpn configuration, there is an “group name” field (see screenshot). Is that the same thing? I have to fill this field, otherwise server didn’t answer. Did you have any idea?

        Thank you in advance.

        • ramezanpour

          I know there’s a such option in the Settings app but as far as I know, there’s no such property in code.

          • Hunt3rDe

            Many thanks for infos.

            🙂

          • ashok

            What is the VPN server you guys are using to check the client created programatically. I tried to connect to vpn servers found at http://www.vpngate.net/en/ using built-in vpn client in iPhone.Using L2TP i was able to establish connection successfully but using IPSec i was not able to connect to the server. What is group name used? what is the vpn server used by you guys to verify your client? It would be great if someone helps.

  • Timur Suleimanov

    Someone faced the problem when startVPNTunnelAndReturnError didn’t return any error and VPN didn’t connect? Is there an easy way to detect if something went wrong? I had never had an error in startVPNTunnelAndReturnError call….

    • kwak

      Yep, I’m facing the same problem..

    • ramezanpour

      I believe there’s a problem with your configuration. Check your configuration and re-save it again to the system preferences.

      • Timur Suleimanov

        No, the problem is not here. You can reproduce this by making ‘authentication failed’ error. Client will try to connect to server, which will return ‘auth_failed’. And client won’t even know about this, because startVPNTunnelAndReturnError won’t return error. This method returns an error only when there’s a problem with configuration.

      • Ashok Thota

        Even I am also facing the same error. When I checked in device log first the status showed connected but it got disconnected with reason 7. Can you guys help me out ?

        Thanks in advance

  • tmachida2002 .

    How to use http proxy with Person VPN on iOS8 ??

    • tmachida2002 .

      Sorry, I have no problem now…
      Because, Proxy server settings..

      • Manjula Jonnalagadda

        Do they go into entitlements?

  • Avinash

    Very nice tutorial. Thanks a lot. Would you be aware if you can create a generic tunnel interface using the Network Extensions framework. Not sure why apple to is stubborn about providing such an API, given that its been existing in Android for a while.

  • Tyler

    Thanks for this! You mentioned that Apple lets you create your own protocols. I’m interested in writing a custom protocol, but can’t find any information on it. Do you know where I can find anything on that?

  • eX_ploit

    Can it be used with L2TP protocol?

  • Fuxin_Zhang

    Thanks a lot for this . I’m also interested in writing a custom L2TP/IPSEC protocol, but can’t find any information on it. Something about it?

    • Guest

      Do you have any idea about implementing a custom protocol using NEVPNProtocol? And After you set up the VPN connection, does it make all device network traffic from only this app or not?

      • Fuxin_Zhang

        Not yet.Setting up the VPN connection programmatically means that you is settting up the system VPN connection , even though your app crashed , other apps continue to use the VPN.

  • Swapnil Gavali

    Do you have any idea about implementing a custom protocol using NEVPNProtocol? And After you set up the VPN connection, does it make all device network traffic from only this app or not?
    Please provide more information on it

  • Waseem

    Great Work! the problem i am facing is that, i am connecting to server perfectly with IKEV2, but when i disconnects, the connection disconnects from IOS8 but it remain in connected state on Windows Server 2008 R2 and server disconnects it after timeout.how i can fix the issue?

    • Jonathan Aguele

      Hi Waseem, im sorry i dont have an answer for you, but i hope you can help me out while you wait for an answer.

      Im curios how you are able to save and retrieve a persistent reference to a keychain item, i tried the code in this link: http://ramezanpour.net/post/2014/09/26/how-to-get-persistent-references-to-keychain-items-in-ios/, however it doesnt work for me. Im sure im doing something wrong. Can you please share some code on how you were able to get it working. Thanks.

  • Ashok Thota

    Hi ramezanpour
    Can you please tell me what is local identifier and remote identifier.
    I am unable to establish the vpn connection. When I connect i am not getting any error, but connection was not established. Please help me out
    Thanks in advance

  • Dan

    Is this a system wide VPN? Can any app just install VPN, without confirmation, and tunnel all traffic? It seems to have severe security implications. Anyone knows?

  • Janardhan

    Hello all, Nice article, thank you for sharing with code,
    here i have doubt that what is Local Identifier and Remote identifiers?
    p.localIdentifier = @”[VPN local identifier]”;
    p.remoteIdentifier = @”[VPN remote identifier]”;

    can you give brief explanation please.

    • Moritz Köchig

      I am interested in this too. I did not find any clear information on Google.

  • alex_j

    How can add proxy server settings to IPSec protocol?

  • sreedeep paul

    Hi I wanted to know can we know the VPN name the device is connected to by this framework?

    • ramezanpour

      Hi. You can’t.

  • pititz

    Great Tutorial, it work’s …
    but i am having trouble after i re-save the configuration.. i get “VPN Connection An unexpected error occurred” prompt when i try to connect. can someone help me?

    • pititz

      At least tell me if its a server problem or am i doing something wrong in my code?

      • pititz

        Never mind… i got it working … i was re-saving the hole configuration, not just modifying that part that i need and save that.It works great now for all the servers i need.

  • Greg Quinn

    Mohammad – nice discussion, thanks. Would be great to include Swift examples.

  • Goltsev Eugene

    Hi ramezanpour and others!
    Kindly asking for help – I’ve tried to
    implements things, described in this post; also I’ve read tons of
    different info on internet – but I still can’t create VPN and make it
    work.
    I’ve tried also to download ready .mobileconfig files – they are installed ok, but I’m not able to manage them from my app.
    If possible – can you share working code? Certainly, without your credentials – I’ll replace them with my one’s.

    Great thanks in advance.

  • 1. Is it possible to configure per-app vpn with the Network Extension?
    2. Does apps that uses this functionality can be uploaded to the appstore?

  • Manjula Jonnalagadda

    Do you know how I can setup Proxy? Should I be adding it in the Entitlements file?

  • prakash eppala

    Hi i have question.What is local identifier and remote identifiers
    What exactly are they and how we get them..

  • prakash eppala

    error in __connection_block_invoke_2: Connection interrupted i got this error while loading the preferences can any one help me

  • David Clark

    Firewalls and anti-virus will not cut it anymore if that is what you’ve been relying on to keep you safe so far. And you can’t go constantly updating your software in order to stay protected. The one-shot gun-shot solution (as I like to call it) is VPN.

    This is a how-to tutorial for iPhone VPN setup. The tutorial given below was tested on iOS 8 with the latest iPhone. But don’t worry if you are using any other version of the iPhone though because they all have the same VPN configuration features – more or less.

    • ramezanpour

      Is this an ad or what?

      • prakash eppala

        Hey Mohammad,can you help me out on the above problem
        i’m getting the error log “error in __connection_block_invoke_2: Connection interrupted” while loading and Saving preferances

  • Larry Smith

    Can RSA SecurID: KeyFob be used as a authentication method? Or do you have to have a certificate or shared secret?

    • ramezanpour

      As of iOS 8, only certificates and shared secret can be used.

      • Larry Smith

        thanks for the information

  • Lovelace

    How to work with the NetworkExtension.framework, how to import it? How to get the Headers? class-dump returns nothing useful for me.

    • Lovelace

      NetworkExtensions.framework can be imported without any problems on MAC OS X 10.11 and XCode 7.
      But I still become nil for [NEVPNManager sharedManager].

      There are no capabilities (Personal VPN), where I should give the entitlements. Therefore I do not know where is the problem.

      What do I miss?

      • ramezanpour

        Network Extension is not available in OS X Yosemite. Apple recently announced that it will be available on OS X El Capitan.

        • Lovelace

          Yes, but I tried it in MAC OS X 10.11 (OS X El Capitan) and XCode 7 and still get nil from [NEVPNManager sharedManager].

    • I was having same issue. But you need to create new certificate from developer center which has ENABLED VPN option. and using that if you run your app the nil issue will get solved.

      • Lovelace

        Do you know where exactly is placed the “Enable VPN” option in the development center?

        • when you create new APPID from developer center . You need to make “VPN Configuration & Control” enable. and by using that AppId you need to make certi and provisioning profile. Using which you need to run your code in device. So that NEVPNManager nil issue will get solved. Thanks

          • Lovelace

            Thank you very much. But I want to create an OS X App on OS El Capitan, not for iOS and the have the same Issue – [NEVPNManager sharedManager] => nil.

    • ramezanpour

      Network Extension is not available in OS X Yosemite. Apple recently announced that it will be available on OS X El Capitan.

      • Lovelace

        Thank you . But I want to create an OS X App on OS El Capitan and I still have the same Issue – [NEVPNManager sharedManager] => nil.

        • ramezanpour

          I have done this couple of months ago and it was working just fine.

  • Hi . Can you please Let us know any method from which We can Save a certificate, which is generated on server and Download from app. as From any of the URL. like http://api.myapps.co/Myappnew/XYXFOL/XYZY1863-signed.mobileconfig and save it to the app

  • David Clark

    A very useful setup guide for new users as i have also tutorial setup for iPhone VPN setup. The tutorial given below was tested on iOS 8 with the latest iPhone. But don’t worry if you are using any other version of the iPhone though because they all have the same VPN configuration features – more or less.

  • Ann Moroz

    Is it possible to do that with pptp vpn? Thank you?

    • ramezanpour

      No. By the time apple supports IPSec and IKEv2 protocols only.

      • Ann Moroz

        Thank you for your reply.

  • pixbroker

    Does this work with 2-factor VPN as well?

  • adamncsu

    I’m trying to get this working with a Cisco AnyConnect VPN. But I’m not sure what the protocol is. Has anyone tried this with AnyConnect?

  • Piyush Dubey

    @ramezanpour:disqus Hello
    Could you please help me with this error “error in __connection_block_invoke_2: Connection interrupted”.? I am getting this error when user navigates from VPN settings to our app after profile installation. Please guide me, where I am doing wrong. I have been stucked to this issue since 5 days.

  • Manjula Jonnalagadda

    Are you doing any work on NEAppProxyProvider?

  • Dimson

    Hi! I have a question about loadPreferencesWithCompletitionHandler and savePreferencesWithCompletitionHandler. I believe you can help me.

    Does blocks of this functions invoked when, for example, on-demand connection establishing?
    If yes, then does it triggers app to become active?
    If no, then what can I do if I need some preparations to do before VPN connection? Can I setup some sort of callback before connection?

    Thank you in advance!

  • VPN on iOS is not that much reliable as compare to Android.

  • Derek Ray

    I set the onDemandRules, but it never works, does anybody has solved this problem?

  • Sawan Cool

    how to identityData pass in Mac application, i have created CiscoConfig file and made key kSCValNetIPSecAuthenticationMethodCertificate but i dont know how to pass certificate Data in Machine Authentication setting? i am using https://github.com/halo/macosvpn this code. Please help me i will be very thankful

  • offp

    Hi! Can you sniff the packets that are going through a VPN connection set by this app?

  • freaked_out

    Anyone tried OpenVPN? Is it possible to set up an opnevpn connection using NetworkExtension framework?

  • manojkumar

    Hello where can we get shared sharedSecretReference please tell me

  • JF Xu

    now I succeed with ipsec but how to use the ikev2?

  • Bogdan Velesca

    Hello, can anyone help me with making a vpn connection without using username and password, just certificates ? I loaded the p12 certificate and installed the pem certificate from the server and after I call startvpn it doesn’t give any error but it does not reach the vpn server. Also I registered for NEVPNStatus notification and at first it says: NEVPNStatusConnecting , then NEVPNStatusDisconnecting and in the end NEVPNStatusDisconnected.

    I would need an example of code to connect to a vpn programatically using IKEV2 -EAP and certificates. It should use NETunnelProviderManager instead of NEVPNManager. I’ve been googling for 2 days and I haven’t found any example of how such a configuration can be done.

    The vpn server I use is strongswan. I tested it on Android and it is connecting, but on iOS it doesn’t even reach the server.

    • Bogdan Velesca

      Anyone?

  • joy

    hellp,my friend. my commany use PPTP protocol ,so how can i configure and manage VPN ,I really need you help.

  • joy

    hello,my friend! my commany use PPTP protocol ,so how can i configure and manage VPN ,I really need you help.

  • joy

    Hellp,my friend. My commany use PPTP protocol ,so how can i configure and manage VPN ,I really need you help,thanks!

  • joy

    Hello,my friend. My commany use PPTP protocol ,so how can i configure and manage VPN ,I really need you help,thanks!

  • Emre Celik

    Hi, I’am trying to create IPSEC VPN but it’s giving No VPN Shared secret was provided error. I’ve already defined secret referance and I can create and connect personel vpn with same information from my iphone. Does anyone know this ?

  • tsiddiqui

    Does now Apple provides APIs to implement both L2TP and PPTP protocols ?

  • Emre Celik

    What about if more than one vpn config installed and default vpn seems different yours ?

  • Rock

    above code i have successfully implement. and i have use “http://www.vpngate.net” website for VPN(its L2TP VPN). but when i connect VPN display error “server not respond”. so how can i get “ipsec vpn”. if any link available pls share it.

  • Александр

    Отличная инструкция по настройке vpn http://blog.vpsville.ru/blog/howto/123.html

  • RD

    Hello,

    Thanks for your post on usage of networking extension framework. I’ve gone through your posts, but need a little clarification. Thanks in advance for your help.

    Questions:
    1)Our app uses Cisco AnyConnect app for vpn on the iOS device. Will i be able to use the network extension framework API (like NEVPNManager) classes to find out the status of the (any connect connected or disconnected) vpn on the iOS device programmatically or is it just supposed to be used only for programmatically custom created VPN connections in iOS?

    2) Can I use the same to find out all the vpn connections existing on the device (say if i have 2 vpns under “VPN Configurations” section and 3 Personal VPNs)?

    3)To use the network extension framework API (like NEVPNManager) classes, do i need to send an entitlement request to Apple? or just generating/downloading the VPN config & Control provisioning profile enough?

    This is very urgent for me.

    Thanks again & Regards,

    RD

  • Andre

    Hi, does the password have to be retrieved from the keychain? I used a NSString and converted it to NSData, and I get an error ‘Error Domain=NEVPNErrorDomain Code=1 “(null)” ‘. Am I doing something wrong? I can’t find any information to help fix this issue. Hopefully someone can help.

    • Password should be as a keychain persistent Reference, simple string in NSData format not working.

      • Andre

        Is there no way around that as we never use or have used the keychain?

  • 唐晓波

    can you tell me ,how can i Import my certificate

  • 唐晓波

    can you tell me ,how can i Import my certificate

  • 唐晓波

    please tell me My mistake

  • 唐晓波

    IKEv2 how to hide the VPN connection server IP and user name

  • 唐晓波

    please tell me,I am very worried

  • Dinesh Dhanekula

    I created VPN on Demand feature by using framework Network Extension framework,I want to disconnect the VPN when the specific URL or site is open in the browser. For Example: when I write http://www.google.com my VPN has to disconnect and VPN has to work on other sites.

  • 唐晓波

    Can you tell me how to implement the ios9 to implement the hidden configuration information and routing table functions

    您可以告诉我怎么实现ios9下面实现隐藏配置信息和路由表功能吗

  • Alex Wayne

    Hey there! I have a small question concerning VPN. Is there a way to detect VPN programmatically in iOS?