I’m working on bringing the WireGuard VPN tunnel to iOS and macOS using the Network Extension framework.

I initially tried to implement the WireGuard protocol in Swift, but abandoned that after learning that the WireGuard team had plans to make the Go implementation of WireGuard (used in their Android app) available for use in iOS.

When I took a look at WireGuard after a few months, a C API based on WireGuard-Go was available that could be used from iOS, and an effort to make an iOS app was underway.

I proposed a rewrite of the app to:

  • Use the VPN tunnel for data persistance instead of Core Data
  • Redo the UI to support both the iPhone and iPad
  • Redo the UI in code (no Interface Builder)
  • Minimize dependancies on third-party code
  • Enable a macOS version to be developed with the same code base

My pitch was accepted. My work on this project was sponsored by the NLnet Foundation.

These features are common to both the iOS and macOS versions:

  • Bringing up / bringing down a WireGuard tunnel
  • Creating, viewing and modifying tunnel configurations
  • Importing from a .conf or .zip file
  • Exporting all tunnels to a .zip file
  • On-Demand VPN (interface-type-based and SSID-based)
  • Viewing and exporting the log
  • Showing bytes transferred for active tunnels

The iOS version includes these additional features:

  • Importing through QR code (adapted from the code before my rewrite)
  • State Restoration
  • Support for Dynamic Type

The macOS version includes these additional features:

  • Bringing up / down a Wireguard tunnel from the status bar
  • The app automatically starts when the user logs in, if it was running when the user logged off
  • The app appears in the dock only when a window is shown – if the app is just in the status bar, the app isn’t shown in the dock

Source code: https://git.zx2c4.com/wireguard-ios/