In order to use the on-demand connection functionality provided natively by iOS we need the following ingredients:
You can download Apple Configurator from the macOS App Store. It is currently available as version 2 for free. The openVPN profile should include everything required to correctly initiate a VPN connection from you iOS device. I highly encourage you to test the profile on iOS using OpenVPN Connect before attempting to convert it to an on-demand profile.
Before we start working on the profile we need to create a pkcs12 bundle including the credentials required to authenticate with the openVPN connection. The on-demand profile does not allow the user to manually enter a username and password. This information needs to be included in the mobile profile.
# openssl pkcs12 -export -in openVPN.crt -inkey openVPN.key -certfile server.crt -name iPhone -out iPhone.p12
The above openssl command will create a pkcs12 bundle called iPhone.p12. The command will ask you for a password required to import the credentials.
Launch Apple Configurator. Press [Command + N] on the Keyboard or select File -> New Profile from the menu.
We need to fill out some of the sections outlined on the left hand side of the profile editor. Starting with General. You can enter anything you want really, just make sure to choose a unique identifier as installing profiles with the same identifier will overwrite the previously installed profile. You can not install multiple profiles that share an identifier on the same device.
The next section we work on is certificates. Here you will insert your credentials to authenticate the connection. Insert the .p12 file here by clicking the + button in the top right. Enter the password from the openssl command in the respective field so that the credentials can be imported.
Optionally include additional certificates useful or required after you established the VPN connection. In my case I included a host certificate to securely establish a TLS connection to a web server on the VPN.
The last section we need to modify is VPN. Please make sure to double check each value entered as it highly likely that your profile will not be able to establish an on-demand connection if you enter the wrong values. Feel free to experiment with you own values. I will outline some required fields below:
The Custom Data field needs to include all the information from the .ovpn file as key-value pairs. Open your openVPN profile with a text editor. The first option in each line needs to be added as the key, everything afterwards in the same line is added as value.
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadContent</key> <array> <dict> <key>Password</key> <string>my_certificate_password</string> <key>PayloadCertificateFileName</key> <string>iPhone.p12</string> <key>PayloadContent</key> <data> MIIQCAIBAzCCD84GCSqGSIb3DQEHAaCCD78Egg+7MIIPtzCCCA8G CSqGSIb3DQEHBqCCCAAwggf8AgEAMIIH9QYJKoZIhvcNAQcBMBwG ... vjAxMCEwCQYFKw4DAhoFAAQUVsfItyK2mO7WkfLj1qtxql9QwoME CHklj4X4qN1XAgIIAA== </data> <key>PayloadDescription</key> <string>Adds a PKCS#12-formatted certificate</string> <key>PayloadDisplayName</key> <string>iPhone.p12</string> <key>PayloadIdentifier</key> <string>com.apple.security.pkcs12.58843978-B7D8-4050-BD77-8EB88BB41F00</string> <key>PayloadType</key> <string>com.apple.security.pkcs12</string> <key>PayloadUUID</key> <string>58843978-B7D8-4050-BD77-8EB88BB41F00</string> <key>PayloadVersion</key> <integer>1</integer> </dict> <dict> <key>IPv4</key> <dict> <key>OverridePrimary</key> <integer>0</integer> </dict> <key>PayloadDescription</key> <string>Configures VPN settings</string> <key>PayloadDisplayName</key> <string>VPN</string> <key>PayloadIdentifier</key> <string>com.apple.vpn.managed.432DFAA8-91D5-4954-8E7D-5E205595E7D4</string> <key>PayloadType</key> <string>com.apple.vpn.managed</string> <key>PayloadUUID</key> <string>432DFAA8-91D5-4954-8E7D-5E205595E7D4</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>homeVPN</string> <key>VPN</key> <dict> <key>AuthName</key> <string>iPhone</string> <key>AuthenticationMethod</key> <string>Certificate</string> <key>OnDemandEnabled</key> <integer>1</integer> <key>OnDemandMatchDomainsAlways</key> <array/> <key>OnDemandMatchDomainsOnRetry</key> <array/> <key>OnDemandRules</key> <array> ... </array> <key>PayloadCertificateUUID</key> <string>58843978-B7D8-4050-BD77-8EB88BB41F00</string> <key>RemoteAddress</key> <string>DEFAULT</string> </dict> <key>VPNSubType</key> <string>net.openvpn.OpenVPN-Connect.vpnplugin</string> <key>VPNType</key> <string>VPN</string> <key>VendorConfig</key> <dict> <key>auth-user-pass</key> <string>my_username\my_password</string> <key>ca</key> <string>-----BEGIN CERTIFICATE——\nMIIDQTCCAimgAwIBAgIJA … 6XTnCagHl5wV+ZI2eTc\n-----END CERTIFICATE-----\n</string> <key>cert</key> <string>-----BEGIN CERTIFICATE——\nMIID1jCCAr6gAwIBAgIBC … lEq3EyC5qJc4=\n-----END CERTIFICATE-----\n</string> <key>cipher</key> <string>AES-256-CBC</string> <key>comp-lzo</key> <string>adaptive</string> <key>float</key> <string>NOARGS</string> <key>keepalive</key> <string>15 60</string> <key>key</key> <string>-----BEGIN RSA PRIVATE KEY——\nMIIG4wIBAAKCAYEA … psUtuM+qAfu\n-----END RSA PRIVATE KEY-----\n</string> <key>nobind</key> <string>NOARGS</string> <key>ns-cert-type</key> <string>server</string> <key>proto</key> <string>tcp-client</string> <key>remote</key> <string>vpn.my_remote.com 1194</string> <key>resolv-retry</key> <string>infinite</string> <key>tls-auth</key> <string>-----BEGIN OpenVPN Static key V1——\nfee00942b7f0eb65179 … 4b36102a683a4\n-----END OpenVPN Static key V1-----\n</string> <key>vpn-on-demand</key> <string>1</string> </dict> </dict> </array> <key>PayloadDescription</key> <string>Connect via OpenVPN on demand</string> <key>PayloadDisplayName</key> <string>OpenVPN onDemand</string> <key>PayloadIdentifier</key> <string>com.codingmerc.openvpn.ondemand.blog</string> <key>PayloadOrganization</key> <string>CodingMerc, LLC</string> <key>PayloadRemovalDisallowed</key> <false/> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>02BFE2AD-94BC-4980-8DF3-025D9CDA73DF</string> <key>PayloadVersion</key> <integer>1</integer> </dict> </plist>
Make sure that all certificates and information are in the correct format. I redacted my certificate information in the example above.
Lets have a look at the OnDemandRules section of the file. Here you need configure a rule-set when you want your device to establish secure VPN connection on-demand using the openVPN profile included in the mobile configuration.
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Disconnect</string>
<key>DNSServerAddressMatch</key>
<array>
<string>192.168.1.1</string>
</array>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>SSIDMatch</key>
<string>MyVPNSiteWifi</string>
</dict>
If the phone is connected to the Wifi that belongs to my VPN network site I don’t want to connect on-demand. This connection is already considered secure.
<dict>
<key>Action</key>
<string>Connect</string>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
</dict>
If the phone is connected to any other Wifi I need it to establish a VPN connection to my secure site.
<dict>
<key>Action</key>
<string>Connect</string>
<key>InterfaceTypeMatch</key>
<string>Cellular</string>
</dict>
If the phone is connected via cellular only and not connected to a Wifi currently I need it to establish a VPN connection on-demand.
<dict>
<key>Action</key>
<string>Disconnect</string>
</dict>
</array>
If none of the rules above match, the VPN connection should be disconnected.
I did not find an official documentation to all available rules and options. I was able to derive this basic set of information from the example iOS VPN On-Demand Rules found on Derman Enterprises blog.
You can now install the (signed) profile on an iOS device. Just share it via AirDrop or eMail for example or distribute it via MDM. 10/04/2017