.github | ||
ci | ||
Demo | ||
TunnelKit/Sources | ||
TunnelKit-iOS | ||
TunnelKit-macOS | ||
TunnelKit.xcodeproj | ||
TunnelKit.xcworkspace | ||
TunnelKitHost | ||
TunnelKitTests | ||
TunnelKitTests-iOS | ||
TunnelKitTests-macOS | ||
.gitignore | ||
.jazzy.yaml | ||
CHANGELOG.md | ||
CLA.rst | ||
CONTRIBUTING.md | ||
Gemfile | ||
Gemfile.lock | ||
LICENSE | ||
Podfile | ||
Podfile.lock | ||
README.md | ||
TunnelKit.podspec |
TunnelKit
This library provides a simplified Swift/Obj-C implementation of the OpenVPN® protocol for the Apple platforms. The crypto layer is built on top of OpenSSL 1.1.0i, which in turn enables support for a certain range of encryption and digest algorithms.
Getting started
The client is known to work with OpenVPN® 2.3+ servers.
- Handshake and tunneling over UDP or TCP
- Ciphers
- AES-CBC (128/192/256 bit)
- AES-GCM (128/192/256 bit, 2.4)
- HMAC digests
- SHA-1
- SHA-2 (224/256/384/512 bit)
- NCP (Negotiable Crypto Parameters, 2.4)
- Server-side
- TLS handshake
- Server validation (CA, EKU)
- Client certificate
- TLS wrapping
- Authentication (
--tls-auth
) - Encryption (
--tls-crypt
)
- Authentication (
- Compression framing
- Disabled
- Compress (2.4)
- LZO (deprecated in 2.4)
- Key renegotiation
- Replay protection (hardcoded window)
The library therefore supports compression framing, just not compression. Remember to disable server-side compression and match framing, otherwise the client will shut down with an error. E.g. if server has comp-lzo no
, client must use compressionFraming = .compLZO
.
Support for .ovpn configuration
TunnelKit can parse .ovpn configuration files. Below are a few limitations worth mentioning.
Unsupported:
- UDP fragmentation, i.e.
--fragment
- Compression
--comp-lzo
other thanno
--compress
other than empty
- Proxy
- External file references (inline
<block>
only) - Encrypted client certificate keys
<connection>
blocks
Ignored:
- MTU overrides
--*-mtu
and variants--mssfix
- Multiple
--remote
with differenthost
values (first wins) - Custom
--redirect-gateway
, VPN is always default gateway (no split tunnelling yet)
Many other flags are ignored too but it's normally not an issue.
Installation
Requirements
- iOS 11.0+ / macOS 10.11+
- Xcode 10+ (Swift 4.2)
- Git (preinstalled with Xcode Command Line Tools)
- Ruby (preinstalled with macOS)
- CocoaPods 1.6.0
- jazzy (optional, for documentation)
- Disable Bitcode
It's highly recommended to use the Git and Ruby packages provided by Homebrew.
CocoaPods
To use with CocoaPods just add this to your Podfile:
pod 'TunnelKit'
Testing
Download the library codebase locally:
$ git clone https://github.com/keeshux/tunnelkit.git
Assuming you have a working CocoaPods environment, setting up the library workspace only requires installing the pod dependencies:
$ pod install
After that, open TunnelKit.xcworkspace
in Xcode and run the unit tests found in the TunnelKitTests
target. A simple CMD+U while on TunnelKit-iOS
should do that as well.
Demo
There is a Demo
directory containing a simple app for testing the tunnel, called BasicTunnel
. As usual, prepare for CocoaPods:
$ pod install
then open Demo.xcworkspace
and run the BasicTunnel-iOS
target.
For the VPN to work properly, the BasicTunnel
demo requires:
- App Groups and Keychain Sharing capabilities
- App IDs with Packet Tunnel entitlements
both in the main app and the tunnel extension target.
In order to test connection to your own server, modify the file Demo/BasicTunnel-[iOS|macOS]/ViewController.swift
and make sure to set ca
to the PEM encoded certificate of your VPN server's CA.
Example:
private let ca = CryptoContainer(pem: """
-----BEGIN CERTIFICATE-----
MIIFJDCC...
-----END CERTIFICATE-----
""")
Documentation
The library is split into two modules, in order to decouple the low-level protocol implementation from the platform-specific bridging, namely the NetworkExtension VPN framework.
Full documentation of the public interface is available and can be generated with jazzy. After installing the jazzy Ruby gem with:
$ gem install jazzy
enter the root directory of the repository and run:
$ jazzy
The generated output is stored into the docs
directory in HTML format.
Core
Here you will find the low-level entities on top of which the connection is established. Code is mixed Swift and Obj-C, most of it is not exposed to consumers. The Core module depends on OpenSSL and is mostly platform-agnostic.
The entry point is the SessionProxy
class. The networking layer is fully abstract and delegated externally with the use of opaque IOInterface
(LinkInterface
and TunnelInterface
) and SessionProxyDelegate
protocols.
AppExtension
The goal of this module is packaging up a black box implementation of a NEPacketTunnelProvider, which is the essential part of a Packet Tunnel Provider app extension. You will find the main implementation in the TunnelKitProvider
class.
Currently, the extension supports VPN over both UDP and TCP sockets. A debug log snapshot is optionally maintained and shared to host apps via the App Group container.
License
Part I
This project is licensed under the GPLv3.
Part II
As seen in libsignal-protocol-c:
Additional Permissions For Submission to Apple App Store: Provided that you are otherwise in compliance with the GPLv3 for each covered work you convey (including without limitation making the Corresponding Source available in compliance with Section 6 of the GPLv3), the Author also grants you the additional permission to convey through the Apple App Store non-source executable versions of the Program as incorporated into each applicable covered work as Executable Versions only under the Mozilla Public License version 2.0 (https://www.mozilla.org/en-US/MPL/2.0/).
Contributing
By contributing to this project you are agreeing to the terms stated in the Contributor License Agreement (CLA).
For more details please see CONTRIBUTING.
Credits
- PIATunnel - Copyright (c) 2018-Present Private Internet Access
- SwiftyBeaver - Copyright (c) 2015 Sebastian Kreutzberger
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (https://www.openssl.org/)
© 2002-2018 OpenVPN Inc. - OpenVPN is a registered trademark of OpenVPN Inc.
Contacts
Twitter: @keeshux
Website: davidederosa.com