tunnelkit/README.md

287 lines
11 KiB
Markdown
Raw Normal View History

2023-04-02 07:08:25 +00:00
![iOS 15+](https://img.shields.io/badge/ios-15+-green.svg)
![macOS 12+](https://img.shields.io/badge/macos-12+-green.svg)
2024-01-05 09:30:35 +00:00
![tvOS 17+](https://img.shields.io/badge/tvos-17+-green.svg)
[![License GPLv3](https://img.shields.io/badge/license-GPLv3-lightgray.svg)](LICENSE)
[![Unit Tests](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml)
[![Release](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/release.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/release.yml)
2018-10-19 00:47:06 +00:00
2021-02-12 00:57:20 +00:00
# TunnelKit
This library provides a generic framework for VPN development on Apple platforms.
## OpenVPN
2018-08-23 08:19:25 +00:00
2023-12-14 09:38:46 +00:00
TunnelKit comes with a simplified Swift/Obj-C implementation of the [OpenVPN®][dep-openvpn] protocol, whose crypto layer is built on top of [OpenSSL 3.2.0][dep-openssl].
2018-08-23 08:19:25 +00:00
The client is known to work with 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
- 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
- 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`)
- [x] Compression framing
2019-03-20 15:39:02 +00:00
- Via `--comp-lzo` (deprecated in 2.4)
- Via `--compress`
- [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
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
2021-07-23 09:14:20 +00:00
TunnelKit can parse .ovpn configuration files. Below are a few details worth mentioning.
2018-11-10 09:24:05 +00:00
2021-07-23 09:14:20 +00:00
#### Non-standard
- XOR-patch functionality:
- Multi-byte XOR Masking
- Via `--scramble xormask <passphrase>`
- XOR all incoming and outgoing bytes by the passphrase given
- XOR Position Masking
- Via `--scramble xorptrpos`
- XOR all bytes by their position in the array
- Packet Reverse Scramble
- Via `--scramble reverse`
- Keeps the first byte and reverses the rest of the array
- XOR Scramble Obfuscate
- Via `--scramble obfuscate <passphrase>`
- Performs a combination of the three above (specifically `xormask <passphrase>` -> `xorptrpos` -> `reverse` -> `xorptrpos` for reading, and the opposite for writing)
- See [Tunnelblick website][about-tunnelblick-xor] for more details (Patch was written in accordance with Tunnelblick's patch for compatibility)
2021-07-23 09:14:20 +00:00
#### Unsupported
2018-11-10 09:24:05 +00:00
- 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)
- Static key encryption (non-TLS)
- `<connection>` blocks
- `net_gateway` literals in routes
2018-11-10 09:24:05 +00:00
2021-07-23 09:14:20 +00:00
#### Ignored
2018-11-10 09:24:05 +00:00
2021-01-03 11:41:50 +00:00
- Some MTU overrides
- `--link-mtu` and variants
2018-11-10 09:24:05 +00:00
- `--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.
## WireGuard
TunnelKit offers a user-friendly API to the modern [WireGuard®][dep-wireguard] protocol.
### Manual Xcode steps
If you add any `TunnelKitWireGuard*` Swift package to the "Link with binary libraries" section of your app or tunnel extension, you are bound to hit this error:
```
ld: library not found for -lwg-go
```
because part of the WireGuardKit package is based on `make`, which SwiftPM doesn't support yet.
Therefore, make sure to follow the steps below for proper integration:
- Copy `Scripts/build_wireguard_go_bridge.sh` somewhere in your project.
- In Xcode, click File -> New -> Target. Switch to "Other" tab and choose "External Build System".
- Type a name for your target.
- Open the "Info" tab and replace `/usr/bin/make` with `$(PROJECT_DIR)/path/to/build_wireguard_go_bridge.sh` in "Build Tool".
- Switch to "Build Settings" and find SDKROOT. Type in `macosx` if you target macOS, or type in `iphoneos` if you target iOS.
- Locate your tunnel extension target and switch to "Build Phases" tab.
- Locate "Dependencies" section and hit "+" to add the target you have just created.
- Repeat the process for each platform.
2018-08-23 08:19:25 +00:00
## Installation
### Requirements
2024-01-05 09:30:35 +00:00
- iOS 15+ / macOS 12+ / tvOS 17+
2021-11-11 20:42:14 +00:00
- SwiftPM 5.3
2018-08-23 08:19:25 +00:00
- Git (preinstalled with Xcode Command Line Tools)
- golang (for WireGuardKit)
2018-08-23 08:19:25 +00:00
2021-11-05 10:50:42 +00:00
It's highly recommended to use the Git package provided by [Homebrew][dep-brew].
2018-08-23 08:19:25 +00:00
### Caveats
Make sure to set "Enable Bitcode" (iOS) to NO, otherwise the library [would not be able to link OpenSSL][about-pr-bitcode] (OpenVPN) and the `wg-go` bridge (WireGuard).
Recent versions of Xcode (latest is 13.1) have an issue where the "Frameworks" directory is replicated inside application extensions. This is not a blocker during development, but will prevent your archive from being validated against App Store Connect due to the following error:
ERROR ITMS-90206: "Invalid Bundle. The bundle at '*.appex' contains disallowed file 'Frameworks'."
You will need to add a "Run Script" phase to your main app target where you manually remove the offending folder, i.e.:
rm -rf "${BUILT_PRODUCTS_DIR}/${PLUGINS_FOLDER_PATH}/YourTunnelTarget.appex/Frameworks"
for iOS and:
rm -rf "${BUILT_PRODUCTS_DIR}/${PLUGINS_FOLDER_PATH}/YourTunnelTarget.appex/Contents/Frameworks"
for macOS.
2021-11-05 10:50:42 +00:00
### Demo
2018-08-23 08:19:25 +00:00
Download the library codebase locally:
$ git clone https://github.com/passepartoutvpn/tunnelkit.git
2018-08-23 08:19:25 +00:00
2024-01-05 09:30:35 +00:00
There are demo targets containing a simple app for testing the tunnels. Open `Demo/TunnelKit.xcodeproject` in Xcode and run it.
2018-08-23 08:19:25 +00:00
For the VPN to work properly, the demo requires:
2018-08-23 08:19:25 +00:00
- _App Groups_ and _Keychain Sharing_ capabilities
- App IDs with _Packet Tunnel_ entitlements
both in the main app and the tunnel extension targets.
2018-08-23 08:19:25 +00:00
2021-11-05 10:50:42 +00:00
In order to test connectivity in your own environment, modify the file `Demo/Demo/Configuration.swift` to match your VPN server parameters.
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
Make sure to also update the following constants in the `*ViewController.swift` files, according to your developer account and your target bundle identifiers:
2019-04-13 09:04:46 +00:00
private let appGroup = "..."
private let tunnelIdentifier = "..."
2019-04-13 09:04:46 +00:00
Remember that the App Group on macOS requires a team ID prefix.
2018-08-23 08:19:25 +00:00
## Documentation
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
2021-11-11 20:42:14 +00:00
Full documentation of the public interface is available and can be generated by opening the package in Xcode and running "Build Documentation" (Xcode 13).
2018-08-23 08:19:25 +00:00
### TunnelKit
2020-06-13 13:44:33 +00:00
This component includes convenient classes to control the VPN tunnel from your app without the NetworkExtension headaches. Have a look at `VPN` implementations:
2020-06-13 13:44:33 +00:00
- `MockVPN` (default, useful to test on simulator)
- `NetworkExtensionVPN` (anything based on NetworkExtension)
2020-06-13 13:44:33 +00:00
### TunnelKitOpenVPN
2021-11-11 20:42:14 +00:00
Provides the entities to interact with the OpenVPN tunnel.
### TunnelKitOpenVPNAppExtension
Contains the `NEPacketTunnelProvider` implementation of a OpenVPN tunnel.
2021-11-11 20:42:14 +00:00
### TunnelKitWireGuard
2018-08-23 08:19:25 +00:00
Provides the entities to interact with the WireGuard tunnel.
2018-08-23 08:19:25 +00:00
### TunnelKitWireGuardAppExtension
2021-11-11 20:42:14 +00:00
Contains the `NEPacketTunnelProvider` implementation of a WireGuard tunnel.
2019-03-19 13:34:49 +00:00
2018-08-23 08:19:25 +00:00
## License
2024-01-14 13:33:14 +00:00
Copyright (c) 2024 Davide De Rosa. All rights reserved.
2020-05-11 07:52:54 +00:00
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
### 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].
### Other licenses
A custom TunnelKit license, e.g. for use in proprietary software, may be negotiated [on request][license-contact].
2018-10-08 12:25:07 +00:00
## Credits
2018-08-23 08:19:25 +00:00
2020-05-11 07:52:54 +00:00
- [lzo][dep-lzo-website] - Copyright (c) 1996-2017 Markus F.X.J. Oberhumer
- [PIATunnel][dep-piatunnel-repo] - Copyright (c) 2018-Present Private Internet Access
- [SURFnet][ppl-surfnet]
2020-05-11 07:52:54 +00:00
- [SwiftyBeaver][dep-swiftybeaver-repo] - Copyright (c) 2015 Sebastian Kreutzberger
- [XMB5][ppl-xmb5] for the [XOR patch][ppl-xmb5-xor] - Copyright (c) 2020 Sam Foxman
- [tmthecoder][ppl-tmthecoder] for the complete [XOR patch][ppl-tmthecoder-xor] - Copyright (c) 2022 Tejas Mehta
- [eduVPN][ppl-eduvpn] for the convenient WireGuardKitGo script
2018-08-23 08:19:25 +00:00
### OpenVPN
2018-08-23 08:19:25 +00:00
2022-04-12 16:02:52 +00:00
© Copyright 2022 OpenVPN | OpenVPN is a registered trademark of OpenVPN, Inc.
2018-08-23 08:19:25 +00:00
### WireGuard
2022-04-12 16:02:52 +00:00
© Copyright 2015-2022 Jason A. Donenfeld. All Rights Reserved. "WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.
### OpenSSL
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. ([https://www.openssl.org/][dep-openssl])
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
[dep-brew]: https://brew.sh/
[dep-openvpn]: https://openvpn.net/index.php/open-source/overview.html
[dep-wireguard]: https://www.wireguard.com/
2021-11-16 10:56:25 +00:00
[dep-openssl]: https://www.openssl.org/
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/
[license-contact]: mailto:license@passepartoutvpn.app
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
[dep-lzo-website]: http://www.oberhumer.com/opensource/lzo/
[ppl-surfnet]: https://www.surf.nl/en/about-surf/subsidiaries/surfnet
[ppl-xmb5]: https://github.com/XMB5
[ppl-xmb5-xor]: https://github.com/passepartoutvpn/tunnelkit/pull/170
[ppl-tmthecoder]: https://github.com/tmthecoder
[ppl-tmthecoder-xor]: https://github.com/passepartoutvpn/tunnelkit/pull/255
[ppl-eduvpn]: https://github.com/eduvpn/apple
2021-07-23 09:14:20 +00:00
[about-tunnelblick-xor]: https://tunnelblick.net/cOpenvpn_xorpatch.html
[about-pr-bitcode]: https://github.com/passepartoutvpn/tunnelkit/issues/51
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