Javier de Martín

VPNs with Packet Tunnel Network Extensions in Swift

The Network Extension framework is one of the most customizable frameworks that Apple provides. Allowing you to customize and extend the core networking features of iOS and macOS.

While this article by Alexander Grebenyuk covers this topic in depth I would like to add some things I have learnt.

I have recently worked on a project implementing a VPN using the OpenVPN protocol. This is not supported natively by the networking framework and requires a third party library, like OpenVPNAdapter.

The WWDC sessions from 2015, 2017 Part 1 and Part 2. Are specially useful to grasp essential points and know how this framework is used.

Using the Packet Tunnel Extension to Implement a VPN

Imagine you want to tunnel all your outgoing traffic using the VPN connection. All your traffic will be sent to your VPN server, that is also your DNS server. This solution can be used to block certain websites, like gambling or adult content and to access an internal company website.

This can be done in iOS using a Packet Tunnel and for this to be published to the App Store it couldn’t be done with frameworks that require managed devices.

For unmanaged devices there are some things at our hand. Like playing around with the on demand rules. This allows the system to automatically start a VPN connection based on different rules. In this case forcing the system to establish a tunnel whenever it acquires internet connectivity, Cellular or WiFi.

OpenVPN has implemented their own solution for an always on VPN tunnel, called seamless tunnel. The implementation is not public but it seems to work for them.

Implementing a Packet Tunnel Network Extension will divide the app into two targets. Your main app where your app will reside and the target that subclasses NEPacketTunnelProvider. Subclassing this class will grant us access to a virtual network interface. Creating a packet tunnel provider requires to configure the Info.plist file.

The main app will only be in charge of doing tasks like configuring de VPN profile into the device Settings app. And the target will be doing all the networking operations: starting, stopping and managing all the states the tunnel could be in.

As there is not a lot of documentation or projects here are some of the things that explain how this framework works and how you can manage to build an always on VPN tunnel on iOS devices.