macOS builtin VPN client tricks

I think everyone would agree that when it comes to the VPN configuration macOS builtin VPN client lacks any flexibility and its GUI exposes a fraction of supported features. This is one of the reasons why there are so many third party VPN clients for macOS in the world, I believe. However, I found that the majority of the time I can get away by using the standard macOS VPN client to connect to the desired VPN endpoint.

In this article I am going to describe my journey of configuring macOS VPN client to support Windscribe VPN, but the described approach applies to vast majority of the VPN service providers who support IKEv2.

XXX: This article is still work in progress, but I thought an example published is better than nothing at all.

I happen to be a customer of Windscribe VPN service.

The macOS client is terrible The native builtin VPN client is good enough for me. GUI configuration produces unworkable result.

Apple Configuration Profile Reference VPN Payload

<?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>AuthName</key>
<string>@@LOGIN@@</string>
<key>AuthPassword</key>
<string>@@PASSWORD@@</string>
<key>AuthenticationMethod</key>
<string>None</string>
<key>DeadPeerDetectionRate</key>
<string>High</string>
<key>ExtendedAuthEnabled</key>
<integer>1</integer>
<key>IKESecurityAssociationParameters</key>
<dict>
<key>DiffieHellmanGroup</key>
<integer>20</integer>
<key>EncryptionAlgorithm</key>
<string>AES-256-GCM</string>
</dict>
<key>LocalIdentifier</key>
<string></string>
<key>RemoteAddress</key>
<string>@@REMOTE_SERVER@@</string>
<key>RemoteIdentifier</key>
<string>@@REMOTE_SERVER@@</string>
</dict>
<key>PayloadDisplayName</key>
<string>@@DISPLAY_NAME@@</string>
<key>PayloadIdentifier</key>
<string>com.apple.vpn.managed.@@UUID1@@</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadUUID</key>
<string>@@UUID1@@</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>UserDefinedName</key>
<string>@@DISPLAY_NAME@@</string>
<key>VPNType</key>
<string>IKEv2</string>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>@@DISPLAY_NAME@@</string>
<key>PayloadIdentifier</key>
<string>VPN.@@UUID2@@</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>@@UUID2@@</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>