Deep Dive: Understanding Apple IKEv2 VPN Configuration Profiles
Understand an IKEv2 VPN configuration profile for Apple Devices
Apple devices support VPN configuration through mobile configuration profiles—XML files that define connection settings, security parameters, and behavior rules. For IKEv2 VPNs, these profiles offer granular control over encryption algorithms, authentication methods, and on-demand connection rules that aren't accessible through the standard Settings interface.
This guide breaks down the structure of an IKEv2 VPN configuration profile, explaining each parameter so you can customize profiles for your own VPN infrastructure.
Profile Structure Overview
An Apple configuration profile is a property list (plist) XML file with a .mobileconfig extension. It contains one or more payloads, each configuring a specific feature. For VPN, we need a com.apple.vpn.managed payload.
Here's the skeleton structure:
<?xml version='1.0' encoding='UTF-8'?>
<!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>
<!-- VPN payload goes here -->
</array>
<key>PayloadDisplayName</key>
<string>VPN Configuration Name</string>
<key>PayloadIdentifier</key>
<string>com.yourcompany.vpn.profile</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>unique-uuid-here</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
The outer dictionary defines the profile container. The interesting configuration lives inside PayloadContent.
The VPN Payload
Here's a complete IKEv2 VPN payload with all common parameters:
<dict>
<key>IKEv2</key>
<dict>
<key>AuthenticationMethod</key>
<string>None</string>
<key>RemoteAddress</key>
<string>vpn.example.com</string>
<key>RemoteIdentifier</key>
<string>vpn.example.com</string>
<key>ExtendedAuthEnabled</key>
<true/>
<key>IKESecurityAssociationParameters</key>
<dict>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>ChildSecurityAssociationParameters</key>
<dict>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>EnablePFS</key>
<true/>
<key>DeadPeerDetectionRate</key>
<string>Medium</string>
<key>DisableMOBIKE</key>
<integer>0</integer>
<key>DisableRedirect</key>
<integer>0</integer>
<key>EnableCertificateRevocationCheck</key>
<integer>0</integer>
<key>UseConfigurationAttributeInternalIPSubnet</key>
<integer>0</integer>
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>PayloadDescription</key>
<string>Configures VPN settings</string>
<key>PayloadDisplayName</key>
<string>vpn.example.com</string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.unique-id</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string>unique-uuid-here</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>My VPN Connection</string>
<key>VPNType</key>
<string>IKEv2</string>
</dict>
Parameter Reference
Connection Settings
RemoteAddress
<key>RemoteAddress</key>
<string>vpn.example.com</string>
The hostname or IP address of your VPN server. Use a DNS name when possible for flexibility.
RemoteIdentifier
<key>RemoteIdentifier</key>
<string>vpn.example.com</string>
The server's IKE identity. Usually matches the server's certificate subject or SAN. Must match what your server presents during negotiation.
AuthenticationMethod
<key>AuthenticationMethod</key>
<string>None</string>
For username/password authentication (EAP), set to None. The actual authentication happens via ExtendedAuth (EAP-MSCHAPv2). Other options include Certificate for certificate-based authentication.
ExtendedAuthEnabled
<key>ExtendedAuthEnabled</key>
<true/>
Enables EAP authentication. When true, the device prompts for username and password (or uses saved credentials).
Security Association Parameters
The IKE Security Association (Phase 1) and Child Security Association (Phase 2) parameters define the cryptographic algorithms used.
EncryptionAlgorithm
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
Options include:
AES-256-GCM- AES-256 in Galois/Counter Mode (recommended)AES-256- AES-256 in CBC modeAES-128-GCM- AES-128 in GCM modeAES-128- AES-128 in CBC mode3DES- Triple DES (not recommended)
AES-256-GCM provides authenticated encryption, combining confidentiality and integrity in one operation. It's the modern choice.
IntegrityAlgorithm
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
Options include:
SHA2-512- SHA-2 with 512-bit outputSHA2-384- SHA-2 with 384-bit outputSHA2-256- SHA-2 with 256-bit outputSHA1-96- SHA-1 (deprecated, avoid)
When using GCM encryption, the integrity algorithm provides additional assurance but GCM already includes authentication.
DiffieHellmanGroup
<key>DiffieHellmanGroup</key>
<integer>20</integer>
The Diffie-Hellman group for key exchange. Higher numbers indicate stronger (and slower) groups:
14- 2048-bit MODP (minimum acceptable)15- 3072-bit MODP16- 4096-bit MODP19- 256-bit ECP (P-256)20- 384-bit ECP (P-384, recommended)21- 521-bit ECP (P-521)
Group 20 (P-384) offers excellent security with reasonable performance.
LifeTimeInMinutes
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
How long the security association remains valid before rekeying. 1440 minutes (24 hours) is typical. Shorter values increase security slightly but add overhead.
Connection Behavior
EnablePFS
<key>EnablePFS</key>
<true/>
Perfect Forward Secrecy. When enabled, compromise of long-term keys doesn't compromise past session keys. Always enable this.
DeadPeerDetectionRate
<key>DeadPeerDetectionRate</key>
<string>Medium</string>
How frequently to check if the VPN server is still reachable:
None- DisabledLow- Less frequent checksMedium- Balanced (recommended)High- Frequent checks
Higher rates detect failures faster but consume more battery on mobile devices.
DisableMOBIKE
<key>DisableMOBIKE</key>
<integer>0</integer>
MOBIKE (IKEv2 Mobility and Multihoming) allows the connection to survive IP address changes—crucial for mobile devices switching between Wi-Fi and cellular. Set to 0 (enabled) unless you have specific reasons to disable.
DisableRedirect
<key>DisableRedirect</key>
<integer>0</integer>
Whether to follow IKE redirects from the server. Generally leave enabled (0).
Traffic Routing
OverridePrimary (Full Tunnel)
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
When set to 1, all traffic routes through the VPN (full tunnel). Set to 0 for split tunnel where only specific destinations use the VPN.
For security-focused VPN usage, full tunnel (1) is recommended—it ensures all traffic is protected.
On-Demand Rules
On-demand rules control when the VPN automatically connects or disconnects.
Always Connect:
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
The VPN connects automatically whenever the device has network connectivity.
Connect Except on Specific Networks:
<key>OnDemandRules</key>
<array>
<dict>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>SSIDMatch</key>
<array>
<string>HomeNetwork</string>
<string>TrustedOffice</string>
</array>
<key>Action</key>
<string>Disconnect</string>
</dict>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
This disconnects on trusted Wi-Fi networks (by SSID) and connects everywhere else.
Connect Only for Specific Domains:
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>EvaluateConnection</string>
<key>ActionParameters</key>
<array>
<dict>
<key>Domains</key>
<array>
<string>internal.company.com</string>
</array>
<key>DomainAction</key>
<string>ConnectIfNeeded</string>
</dict>
</array>
</dict>
</array>
The VPN connects only when accessing specific domains.
Installing Profiles
iOS/iPadOS
- Transfer the
.mobileconfigfile via AirDrop, email attachment, or web download - The device shows "Profile Downloaded" notification
- Go to Settings → General → VPN & Device Management
- Tap the downloaded profile
- Tap Install, enter device passcode if prompted
- Review the profile contents and confirm installation
macOS
- Double-click the
.mobileconfigfile - System Preferences/Settings opens to the Profiles pane
- Review the profile and click Install
- Enter administrator credentials if prompted
Generating UUIDs
Each profile and payload needs unique UUIDs. Generate them with:
uuidgen
Or in Python:
import uuid
print(uuid.uuid4())
Complete Example Profile
Here's a ready-to-customize template. Replace the values in angle brackets:
<?xml version='1.0' encoding='UTF-8'?>
<!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>IKEv2</key>
<dict>
<key>AuthenticationMethod</key>
<string>None</string>
<key>ChildSecurityAssociationParameters</key>
<dict>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>DeadPeerDetectionRate</key>
<string>Medium</string>
<key>DisableMOBIKE</key>
<integer>0</integer>
<key>DisableRedirect</key>
<integer>0</integer>
<key>EnableCertificateRevocationCheck</key>
<integer>0</integer>
<key>EnablePFS</key>
<true/>
<key>ExtendedAuthEnabled</key>
<true/>
<key>IKESecurityAssociationParameters</key>
<dict>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
<key>IntegrityAlgorithm</key>
<string>SHA2-384</string>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>LifeTimeInMinutes</key>
<integer>1440</integer>
</dict>
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
<key>RemoteAddress</key>
<string><YOUR_VPN_SERVER></string>
<key>RemoteIdentifier</key>
<string><YOUR_VPN_SERVER></string>
<key>UseConfigurationAttributeInternalIPSubnet</key>
<integer>0</integer>
</dict>
<key>IPv4</key>
<dict>
<key>OverridePrimary</key>
<integer>1</integer>
</dict>
<key>PayloadDescription</key>
<string>Configures VPN settings</string>
<key>PayloadDisplayName</key>
<string><YOUR_VPN_SERVER></string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.<UNIQUE_ID></string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string><GENERATE_UUID></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><FRIENDLY_NAME></string>
<key>VPNType</key>
<string>IKEv2</string>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>IKEv2 VPN (<YOUR_VPN_SERVER>)</string>
<key>PayloadIdentifier</key>
<string><GENERATE_UUID></string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string><GENERATE_UUID></string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
The profile parameters must match your VPN server's configuration. If you're building an IKEv2 server, ensure the cipher suites, DH groups, and authentication methods align.
Footnotes:
[1] Apple Configuration Profile Reference: https://developer.apple.com/documentation/devicemanagement/vpn
[2] IKEv2 Cipher Suites: https://wiki.strongswan.org/projects/strongswan/wiki/IKEv2CipherSuites
[3] Apple Enterprise IT Documentation: https://support.apple.com/guide/deployment/