Auto toggle VPN on Apple devices
I run a few Apple devices at home (including the Macbook Air I’m typing this on), and I want them all to automagically connect to my VPN when I leave my house – and it turns out it’s pretty easy to set this up!
Below is based upon this gist, thank you deg0nz!
iOS #
There are two common methods to do this – either using the on-demand feature in the Wireguard app, or using the builtin mobileconf functionality. I went with the latter, which also works with other VPN technologies as well.
All you need is a working WireGuard configuration, a XML file and AirDrop to copy the XML to your mobile device. And the WireGuard app installed, of course!
An example configuration looks like this – make sure you replace UUIDs (mostly due to reasons), WireGuard config, WiFi networks and descriptions.
<?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>UserDefinedName</key>
<!-- This is shown in Settings -> VPN -->
<string>wireguard-on-demand</string>
<key>PayloadDisplayName</key>
<!-- This is shown in Settings -> General -> Profile -> [Profile Name] -> More Details -> VPN Settings -->
<string>WireGuard on-demand</string>
<key>PayloadIdentifier</key>
<string>wtf.beh.vpn.wifi.untrusted</string>
<key>PayloadUUID</key>
<string>2EF2C036-516D-4E7F-8700-92EBF27C87A9</string>
<key>VPNType</key>
<string>VPN</string>
<key>VPNSubType</key>
<string>com.wireguard.ios</string>
<key>VendorConfig</key>
<dict>
<key>WgQuickConfig</key>
<string>
[Interface]
PrivateKey = <private wg key goes here>
Address = 192.168.5.2/32
DNS = 192.168.5.1
[Peer]
PublicKey = <server public key goes here>
AllowedIPs = 192.168.5.0/24
Endpoint = <vpn endpoint goes here>
</string>
</dict>
<!-- Adjust your VPN server below -->
<key>VPN</key>
<dict>
<key>RemoteAddress</key>
<!-- vpn endpoint goes here, again! -->
<string>vpn.example.com:1234</string>
<key>AuthenticationMethod</key>
<string>Password</string>
</dict>
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<!-- Disconnect VPN for trusted WiFi networks -->
<dict>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>SSIDMatch</key>
<array>
<!-- Add your trusted WiFi SSIDs below -->
<string>Trusted SSID 1</string>
<!-- <string>Trusted SSID 2...and as many as you'd like</string> -->
</array>
<key>Action</key>
<string>Disconnect</string>
</dict>
<!-- VPN state for all other WiFi networks -->
<dict>
<key>InterfaceTypeMatch</key>
<string>WiFi</string>
<key>Action</key>
<string>Connect</string>
</dict>
<!-- VPN default state, matches when connected via cellular -->
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>WireGuard unicorn non-home</string> <!-- This is the profile name -->
<key>PayloadIdentifier</key>
<string>wtf.beh.vpn.wifi.config.BAC9A693-7448-42AD-8B91-53745C3BF1D3</string>
<key>PayloadRemovalDisallowed</key>
<false />
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>72B898FE-EFAB-43B8-8726-1DD0A2CF951D</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
Save the above with file ending .mobileconfig
, and use AirDrop (or
whathaveyou) to send to your iOS device. Follow the on-screen
instructions.
macOS #
For macOS I went with the GUI method to configure my on-demand VPN. I just created a new, empty VPN tunnel in the WireGuard app, and selected on-demand and excluded my ’trusted’ WiFi from the list. So now my laptop connects to my VPN anytime I’m not home, and disconnects the VPN when I’m home again.