I can connect to my internal network from outside via an OpenVPN tunnel. However I need to manually start the VPN connection on my iPhone or iPad every time before I want to access one of my internal machines. So I looked for a way to automate that and starting the VPN connection with OpenVPN on my iOS devices on demand.

Here I describe the steps which I have done to obtain that:

I assume that you already have a working VPN connection from your iOS device via OpenVPN and have access to the certificate files you created for that.

First you need to create a certificate file in PKCS12 format which contains both your certificate and your private key. I have created that file with the following OpenSSL command:

[codesyntax lang=”text” lines=”no” blockstate=”expanded”]

[/codesyntax]

Now we need to create a mobile configuration profile for iOS. As the “Apple Configuration Tool for Windows” no longer exists and the official tool “Apple Configurator” is only available for Mac I used the “OpenVPN iOS Configuration Profile Utility“. You might need to install RubyGems before if you not have it setup already on your machine (I did all these steps on my Raspberry Pi where I had that installed before).

I used the following command to create my profile:

[codesyntax lang=”text” lines=”no”]

[/codesyntax]

Unfortunately currently the “ovpnmcgen” tool does not support the “DNSDomainMatch” directive which is needed for automatic enabling VPN as soon as you access a host in your internal network.

So you manually need to add the following parameters to the “OnDemandRules” section in your “the_name_of_the_generated_output_file.mobileconfig” file . I have highlighted the lines you need to add:

[codesyntax lang=”xml” lines=”no” highlight_lines=”19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35″]

[/codesyntax]

You need to replace “urs.local” with the domain name of your internal network. Accessing a host with this domain name (e.g. “myhost.urs.local”) will then automatically trigger a VPN connection.

Now you do have a configuration file which you can install as a profile in your iOS device. You need to somehow transfer it to your device. You can either mail it to you (might be unsecure as someone can get access to your file …) or transfer it via iTunes or (as I did) place it on your own Owncloud server and open it with Safari on your iOS device.

To install the profile you need first to enter your iOS password and after that the password for your private key you used while creating the PKCS12 file.

As soon as you have installed the profile you are ready to go.

With the configuration described above a VPN connection will be established automatically as soon as you try to access a hostname in your local network (here: “urs.local”). If you come back home with your device and connect to your own Wifi network the VPN will be disconnected again automatically.

On demand VPN with iOS and OpenVPN
Tagged on:         

9 thoughts on “On demand VPN with iOS and OpenVPN

  • Pingback:My Raspberry Pi - Urs-o-Log

  • 16.02.2016 at 21:05
    Permalink

    Thank you for this tutorial. Easy to follow and concise!. My VPN is working on demand following your steps but I have two questions. How can I configure IPs instead of domain names? (I think that starting with IOS 9 is not possible). And, how can I stop VPN when is idle (for example after 10 minutes of inactivity?

    Reply
  • 16.02.2016 at 21:39
    Permalink

    You are right, since September 2015 Apple does no longer allow IP addresses but only domain names.

    Regarding the automatic disconnect, try to play with something like that:

    DisconnectOnIdle
    1
    DisconnectOnIdleTimer
    900

    Reply
    • 16.02.2016 at 21:42
      Permalink

      Sorry, WordPress has removed all lower than and greater than characters 🙁 Here again, change all brackets in these lines with lower than and greater than characters:

      (key)DisconnectOnIdle(/key)
      (integer)1(/integer)
      (key)DisconnectOnIdleTimer(/key)
      (integer)900(/integer)

      Let me know if you got it working.

      Reply
      • 17.02.2016 at 21:25
        Permalink

        Hi Michel
        I have modified my mobileconfig file inserting OnIdle code between these lines and is not working:

        (key)VPN(/key)
        (dict)
        ….
        (key)DisconnectOnIdle(/key)
        (integer)1(/integer)
        (key)DisconnectOnIdleTimer(/key)
        (integer)600(/integer)
        ….
        (key)AuthenticationMethod(/key)
        (string)Certificate(/string)
        (key)OnDemandEnabled(/key)
        (integer)1(/integer)
        (key)OnDemandRules(/key)

        Maybe I’m doing something wrong but my VPN still up after ten minutes of inactivity.
        Thank you!

        Reply
          • 20.02.2016 at 00:56
            Permalink

            Seems that DisconnectOnIdle don’t work with OpenVPN but there’s a workaround for this. If I disable “reconnect on wake up” in OpenVPN app settings I get more or lees what I want. That is, when the device goes to sleep, VPN will still down after wake up until a new on demand rule is tiggered. For me this behavior is OK.
            Thank you Michael for your article and your help!

  • 23.07.2016 at 00:13
    Permalink

    This also applies if I have purchased a VPN through any provider?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *