Per-App VPN side-by-side with Personal VPN

Is it possible to run a Per-App VPN side-by-side with a Personal VPN on an iOS device?


Specifically I would like to assign a Per-App VPN to a specific iOS application so that the traffic of that application flows through the Per-App VPN, and to have a Personal VPN installed that handles the traffic for all other applications.


I recall previously testing this on an iOS 11.1 device and from memory it worked. I have tested this again today using an iPhone X running iOS 12.1.2, and it seems that the ability to run each VPN is mutually exclusive. I.e. to run the Per-App VPN the Personal VPN must first be disabled, and to run the Personal VPN the Per-App VPN must be disabled.


I am using 'SurfEasy VPN' as a Personal VPN, and the Per-App VPN is a custom VPN application operating as a NEPacketTunnelProvider.


The following appears in the console when I try to connect 'SurfEasy VPN' while the Per-App VPN is running:

strings debug com.apple.CFBundle 10:22:27.482880 +1100 nesessionmanager Bundle: <private>, key: VPN_DISCONNECT_ERROR_INTERNAL_ERROR, value: VPN_DISCONNECT_ERROR_INTERNAL_ERROR, table: Localizable, localizationName: (null), result: The VPN session failed because an internal error occurred.


Is this behaviour as expected, or should both VPNs be able to operate side-by-side? Is there something that could be set in my custom Per-App VPN or the SurfEasy VPN that could cause conflict?


Kind regards,


Jordan

Replies

I haven’t researched this for a long time, but my understanding is that Personal VPN and managed VPN (and per-app VPN is always managed) are compatible.

Is your per-app VPN an app proxy provider? Or a packet tunnel provider in per-app VPN mode?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Quinn.


I can confirm that it is a packet tunnel provider.


On further testing, it seems that the issue is caused by both my custom VPN and the SurfEasy VPN trying to bind to port 500 and 4500.


To test this further and isolate any "bad behaviour" of my custom VPN, I have performed the following tests against a strongSwan endpoint, using the iOS built-in IKEv2 client:

  1. Personal VPN side-by-side with Per-App VPN
  2. Per-App VPN side-by-side with a different Per-App VPN


Neither of the above combinations performed side-by-side. It seems that the iOS built-in IKEv2 client will only bind to port 500 and 4500, and hence it isn't possible to have more than one instance connected at a time.


Is this the expected behavour?

I’ve never looked into this but it’s hardly surprising that you might run into conflicts in that situation. Given that you control one of the VPN clients, can you move it to a different port?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

You are right. I wasn't sure whether the built-in IKEv2 client would be designed to seek alternative ports if the default ones were already in use, but I would seem that the answer is: no, they don't.


Thanks for your help!


Kind regards,


Jordan