2018-08-23 10:16:36 +00:00
# TunnelKit
2018-08-23 08:19:25 +00:00
2018-10-19 00:47:06 +00:00
![iOS 11+ ](https://img.shields.io/badge/ios-11+-green.svg )
2019-11-01 23:20:59 +00:00
[![OpenSSL 1.1.1d ](https://img.shields.io/badge/openssl-1.1.1d-d69c68.svg )](https://www.openssl.org/news/openssl-1.1.1-notes.html)
2018-10-19 00:47:06 +00:00
[![License GPLv3 ](https://img.shields.io/badge/license-GPLv3-lightgray.svg )](LICENSE)
2019-05-27 20:16:36 +00:00
[![Travis-CI ](https://api.travis-ci.org/passepartoutvpn/tunnelkit.svg?branch=master )](https://travis-ci.org/passepartoutvpn/tunnelkit)
2018-10-19 00:47:06 +00:00
2019-11-01 23:20:59 +00:00
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.1][dep-openssl], which in turn enables support for a certain range of encryption and digest algorithms.
2018-08-23 08:19:25 +00:00
2018-10-19 00:47:06 +00:00
< a href = "https://www.patreon.com/keeshux" > < img src = "https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width = "160" > < / a >
2018-08-23 08:19:25 +00:00
## Getting started
2018-11-10 09:24:05 +00:00
The client is known to work with [OpenVPN®][openvpn] 2.3+ servers.
2018-08-23 08:19:25 +00:00
- [x] Handshake and tunneling over UDP or TCP
2018-08-24 09:07:12 +00:00
- [x] Ciphers
2018-09-13 11:42:08 +00:00
- AES-CBC (128/192/256 bit)
- AES-GCM (128/192/256 bit, 2.4)
2018-08-24 09:07:12 +00:00
- [x] HMAC digests
2018-08-23 08:19:25 +00:00
- SHA-1
2018-09-13 11:42:08 +00:00
- SHA-2 (224/256/384/512 bit)
2018-09-02 00:16:34 +00:00
- [x] NCP (Negotiable Crypto Parameters, 2.4)
- Server-side
2018-08-24 09:07:12 +00:00
- [x] TLS handshake
2018-10-23 21:49:57 +00:00
- Server validation (CA, EKU)
2018-08-24 09:07:12 +00:00
- Client certificate
2018-09-11 15:45:22 +00:00
- [x] TLS wrapping
- Authentication (`--tls-auth`)
2018-09-20 22:11:01 +00:00
- Encryption (`--tls-crypt`)
2018-08-30 09:11:37 +00:00
- [x] Compression framing
2019-03-20 15:39:02 +00:00
- Via `--comp-lzo` (deprecated in 2.4)
- Via `--compress`
2019-03-19 14:20:47 +00:00
- [x] Compression algorithms
2019-03-20 15:39:02 +00:00
- LZO (via `--comp-lzo` or `--compress lzo` )
2018-11-10 09:24:05 +00:00
- [x] Key renegotiation
2018-08-24 09:07:12 +00:00
- [x] Replay protection (hardcoded window)
2018-08-23 08:19:25 +00:00
2019-03-19 14:20:47 +00:00
The library therefore supports compression framing, just not newer compression. Remember to match server-side compression and framing, otherwise the client will shut down with an error. E.g. if server has `comp-lzo no` , client must use `compressionFraming = .compLZO` .
2018-08-23 14:55:35 +00:00
2018-11-10 09:24:05 +00:00
### Support for .ovpn configuration
TunnelKit can parse .ovpn configuration files. Below are a few limitations worth mentioning.
Unsupported:
- UDP fragmentation, i.e. `--fragment`
2019-03-20 15:39:02 +00:00
- Compression via `--compress` other than empty or `lzo`
2019-05-02 08:49:30 +00:00
- Connecting via proxy
2018-11-10 09:24:05 +00:00
- External file references (inline `<block>` only)
2019-05-09 08:18:31 +00:00
- Static key encryption (non-TLS)
2019-03-03 08:41:17 +00:00
- `<connection>` blocks
2019-11-11 18:26:21 +00:00
- `vpn_gateway` and `net_gateway` literals in routes
2018-11-10 09:24:05 +00:00
Ignored:
- MTU overrides
- `--*-mtu` and variants
- `--mssfix`
- Multiple `--remote` with different `host` values (first wins)
2019-11-11 18:28:13 +00:00
- Static client-side routes
2018-11-10 09:24:05 +00:00
Many other flags are ignored too but it's normally not an issue.
2018-08-23 08:19:25 +00:00
## Installation
### Requirements
2018-09-26 10:37:15 +00:00
- iOS 11.0+ / macOS 10.11+
2019-03-30 22:21:11 +00:00
- Xcode 10+ (Swift 5)
2018-08-23 08:19:25 +00:00
- Git (preinstalled with Xcode Command Line Tools)
- Ruby (preinstalled with macOS)
2019-02-25 21:53:26 +00:00
- [CocoaPods 1.6.0][dep-cocoapods]
2018-08-23 08:19:25 +00:00
- [jazzy][dep-jazzy] (optional, for documentation)
2018-12-14 13:31:53 +00:00
- [Disable Bitcode][issue-51]
2018-08-23 08:19:25 +00:00
It's highly recommended to use the Git and Ruby packages provided by [Homebrew][dep-brew].
### CocoaPods
To use with CocoaPods just add this to your Podfile:
```ruby
2018-08-23 10:16:36 +00:00
pod 'TunnelKit'
2018-08-23 08:19:25 +00:00
```
### Testing
Download the library codebase locally:
2019-05-14 08:58:47 +00:00
$ git clone https://github.com/passepartoutvpn/tunnelkit.git
2018-08-23 08:19:25 +00:00
Assuming you have a [working CocoaPods environment][dep-cocoapods], setting up the library workspace only requires installing the pod dependencies:
$ pod install
2019-05-27 18:51:11 +00:00
After that, open `TunnelKit.xcworkspace` in Xcode and run the unit tests found in the `TunnelKitTests` folder. A simple CMD+U while on `TunnelKit-iOS` should do that as well.
2018-08-23 08:19:25 +00:00
#### 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.
2018-10-06 14:50:04 +00:00
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.
2018-08-23 08:19:25 +00:00
Example:
2018-10-06 14:50:04 +00:00
private let ca = CryptoContainer(pem: """
-----BEGIN CERTIFICATE-----
MIIFJDCC...
-----END CERTIFICATE-----
""")
2018-08-23 08:19:25 +00:00
2019-04-13 09:04:46 +00:00
Make sure to also update the following constants in the same files, according to your developer account and your target bundle identifiers:
public static let appGroup
public static let tunnelIdentifier
Remember that the App Group on macOS requires a team ID prefix.
2018-08-23 08:19:25 +00:00
## Documentation
2019-05-27 18:51:11 +00:00
The library is split into several modules, in order to decouple the low-level protocol implementation from the platform-specific bridging, namely the [NetworkExtension][ne-home] VPN framework.
2018-08-23 08:19:25 +00:00
Full documentation of the public interface is available and can be generated with [jazzy][dep-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
2019-05-27 18:51:11 +00:00
Contains the building blocks of a VPN protocol. Eventually, a consumer would implement the `Session` interface, expected to start and control the VPN session. A session is expected to work with generic network interfaces:
2018-08-23 08:19:25 +00:00
2019-05-27 18:51:11 +00:00
- `LinkInterface` (e.g. a socket)
- `TunnelInterface` (e.g. an `utun` interface)
There are no physical network implementations (e.g. UDP or TCP) in this module.
2018-08-23 08:19:25 +00:00
### AppExtension
2019-05-27 18:51:11 +00:00
Provides a layer on top of the NetworkExtension framework. Most importantly, bridges native [NWUDPSession][ne-udp] and [NWTCPConnection][ne-tcp] to an abstract `GenericSocket` interface, thus making a multi-protocol VPN dramatically easier to manage.
### Protocols/OpenVPN
Here you will find the low-level entities on top of which an OpenVPN connection is established. Code is mixed Swift and Obj-C, most of it is not exposed to consumers. The module depends on OpenSSL.
The entry point is the `OpenVPNSession` class. The networking layer is fully abstract and delegated externally with the use of opaque `IOInterface` (`LinkInterface` and `TunnelInterface` ) and `OpenVPNSessionDelegate` protocols.
Another goal of this module is packaging up a black box implementation of a [NEPacketTunnelProvider][ne-ptp], which is the essential part of a Packet Tunnel Provider app extension. You will find the main implementation in the `OpenVPNTunnelProvider` class.
2018-08-23 08:19:25 +00:00
2019-05-27 18:51:11 +00:00
A debug log snapshot is optionally maintained and shared by the tunnel provider to host apps via the App Group container.
2018-08-23 08:19:25 +00:00
2019-05-27 18:51:11 +00:00
### Extra/LZO
2019-03-19 13:34:49 +00:00
Due to the restrictive license (GPLv2), LZO support is provided as an optional subspec.
2018-08-23 08:19:25 +00:00
## License
2018-09-29 08:19:15 +00:00
### Part I
2018-10-08 12:25:07 +00:00
This project is licensed under the [GPLv3][license-content].
2018-09-29 08:19:15 +00:00
### Part II
As seen in [libsignal-protocol-c][license-signal]:
> 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/).
2018-08-23 08:19:25 +00:00
2019-03-19 14:20:47 +00:00
### Part III
Part I and II do not apply to the LZO library, which remains licensed under the terms of the GPLv2+.
2018-10-08 12:25:07 +00:00
### Contributing
By contributing to this project you are agreeing to the terms stated in the [Contributor License Agreement (CLA)][contrib-cla].
For more details please see [CONTRIBUTING][contrib-readme].
## Credits
2018-08-23 08:19:25 +00:00
2019-05-17 09:10:48 +00:00
- [lzo][dep-lzo-website] - © 1996 - 2017 Markus F.X.J. Oberhumer
- [PIATunnel][dep-piatunnel-repo] - © 2018-Present Private Internet Access
2019-07-26 18:35:38 +00:00
- [SURFnet][surfnet]
2019-12-02 09:43:04 +00:00
- [SwiftyBeaver][dep-swiftybeaver-repo] - © 2015 Sebastian Kreutzberger
2018-08-23 08:19:25 +00:00
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. ([https://www.openssl.org/][dep-openssl])
© 2002-2018 OpenVPN Inc. - OpenVPN is a registered trademark of OpenVPN Inc.
2018-10-08 12:25:07 +00:00
## Contacts
Twitter: [@keeshux][about-twitter]
2019-05-14 09:06:50 +00:00
Website: [passepartoutvpn.app][about-website]
2018-10-08 12:25:07 +00:00
2018-08-23 08:19:25 +00:00
[openvpn]: https://openvpn.net/index.php/open-source/overview.html
2018-10-08 12:25:07 +00:00
2018-08-23 08:19:25 +00:00
[dep-cocoapods]: https://guides.cocoapods.org/using/getting-started.html
[dep-jazzy]: https://github.com/realm/jazzy
[dep-brew]: https://brew.sh/
[dep-openssl]: https://www.openssl.org/
2019-05-14 08:58:47 +00:00
[issue-51]: https://github.com/passepartoutvpn/tunnelkit/issues/51
2018-08-23 08:19:25 +00:00
[ne-home]: https://developer.apple.com/documentation/networkextension
[ne-ptp]: https://developer.apple.com/documentation/networkextension/nepackettunnelprovider
[ne-udp]: https://developer.apple.com/documentation/networkextension/nwudpsession
[ne-tcp]: https://developer.apple.com/documentation/networkextension/nwtcpconnection
2018-08-23 10:16:36 +00:00
2018-10-08 12:25:07 +00:00
[license-content]: LICENSE
2018-09-29 08:19:15 +00:00
[license-signal]: https://github.com/signalapp/libsignal-protocol-c#license
2018-08-23 10:16:36 +00:00
[license-mit]: https://choosealicense.com/licenses/mit/
2018-10-08 12:25:07 +00:00
[contrib-cla]: CLA.rst
[contrib-readme]: CONTRIBUTING.md
2018-08-27 17:54:29 +00:00
2018-08-23 10:16:36 +00:00
[dep-piatunnel-repo]: https://github.com/pia-foss/tunnel-apple
[dep-swiftybeaver-repo]: https://github.com/SwiftyBeaver/SwiftyBeaver
2019-03-19 14:20:47 +00:00
[dep-lzo-website]: http://www.oberhumer.com/opensource/lzo/
2019-07-26 18:35:38 +00:00
[surfnet]: https://www.surf.nl/en/about-surf/subsidiaries/surfnet
2018-10-08 12:25:07 +00:00
[about-twitter]: https://twitter.com/keeshux
2019-05-14 09:06:50 +00:00
[about-website]: https://passepartoutvpn.app
2018-10-13 12:56:58 +00:00
[about-patreon]: https://www.patreon.com/keeshux