Checking VPN connection on iOS (Swift)

Alessandro Francucci
2 min readApr 15, 2020

--

[Solution working for: iOS 13, Swift 5.2]

Due a business requirement, I had to find out how to check whether the user was using a VPN connection or not.

The answers I could found, although quite concise, weren't too much satisfying though, especially for the lack of explanations behind the snippets I was finding.

Therefore, before explaining the relatively short solution to this problem I found and came up with, I wanted to first dive a little bit in and explain it with some theory.

First of all, what's in short a VPN?

VPN stands "Virtual Private Network" and, as most of us already know, can serve to achieve many different goals, such as:

  • access between remote private networks;
  • data encryption;
  • anonymity when browsing the Internet.

To ensure security, the private network connection is established using an encrypted layered tunneling protocol.

Now, in this post, I'm not gonna go deeper on what a VPN is, but I'm gonna focus instead on the possible adopted tunneling protocols. Some of them are for example:

  1. IPsec: Ipsec uses encryption, encapsulating an IP packet inside an IPsec packet. De-encapsulation happens at the end of the tunnel, where the original IP packet is decrypted and forwarded to its intended destination
  2. Tun (or Utun)/Tap: Serve similar tunneling purposes, but they operate on different layers of the network stack. More info Here
  3. PPP: Stands for “Point-to-Point Protocol.” PPP is a protocol that enables communication and data transfer between two points or “nodes”. Since it encapsulates other protocols, it can be used for data tunneling (Full definition Here)

Now that we know a bit more about them, we have a chance to understand if the app is potentially using a VPN or not. Doing so, is in fact possible by relying on the CFNetworkCopySystemProxySettings, that gives us a list of the adopted protocols.

With that said, if we find in this dictionary one of the mentioned protocols, we can assume that a VPN is likely to be used. Hereby the code snippet:

Final considerations

Does this solution work?

As far as I could test (real device and simulator), the solution was perfectly working. (In my case, a `ipsec` key was appearing for instance in case of an active vpn)

Is this solution bullet proof?

Not really. We don’t know whether there would be other protocols that the user is using and I didn’t include, if new ones will be introduced or simply if apple will change his api in the future. (Although, in this specific case, I guess it’ll simply be a matter of syntax)

Therefore, if you think you can contribute or you want to keep this blog-post up to date, feel free!

Thanks for your attention.

--

--