mirror of
https://github.com/aramperes/onetun.git
synced 2025-09-09 06:38:32 -04:00
Add architecture to README
This commit is contained in:
parent
dfa32f74d0
commit
773cd10bcb
3 changed files with 60 additions and 121 deletions
119
Cargo.lock
generated
119
Cargo.lock
generated
|
@ -242,100 +242,6 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"proc-macro-hack",
|
||||
"proc-macro-nested",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.3"
|
||||
|
@ -580,7 +486,6 @@ dependencies = [
|
|||
"anyhow",
|
||||
"boringtun",
|
||||
"clap",
|
||||
"futures",
|
||||
"lockfree",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
|
@ -625,12 +530,6 @@ version = "0.2.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_env_logger"
|
||||
version = "0.3.1"
|
||||
|
@ -642,18 +541,6 @@ dependencies = [
|
|||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
|
@ -765,12 +652,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
|
||||
|
||||
[[package]]
|
||||
name = "slog"
|
||||
version = "2.7.0"
|
||||
|
|
|
@ -14,4 +14,3 @@ anyhow = "1"
|
|||
smoltcp = { git = "https://github.com/smoltcp-rs/smoltcp", branch = "master" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
lockfree = "0.5.1"
|
||||
futures = "0.3.17"
|
||||
|
|
61
README.md
61
README.md
|
@ -2,7 +2,7 @@
|
|||
|
||||
A cross-platform, user-space WireGuard port-forwarder that requires no system network configurations.
|
||||
|
||||
## How it works
|
||||
## Usage
|
||||
|
||||
**onetun** opens a TCP port on your local system, from which traffic is forwarded to a TCP port on a peer in your
|
||||
WireGuard network. It requires no changes to your operating system's network interfaces: you don't need to have `root`
|
||||
|
@ -71,6 +71,65 @@ $ curl 127.0.0.1:8080
|
|||
Hello world!
|
||||
```
|
||||
|
||||
## Download
|
||||
|
||||
Normally I would publish `onetun` to crates.io. However, it depends on some features
|
||||
in [smoltcp](https://github.com/smoltcp-rs/smoltcp) and
|
||||
[boringtun](https://github.com/cloudflare/boringtun) that haven't been published yet, so I'm forced to use their Git
|
||||
repos as dependencies for now.
|
||||
|
||||
In the meantime, you can download the binary for Windows, macOS (Intel), and Linux (amd64) from
|
||||
the [Releases](https://github.com/aramperes/onetun/releases) page.
|
||||
|
||||
You can also build onetun locally, using Rust:
|
||||
|
||||
```shell
|
||||
$ git clone https://github.com/aramperes/onetun && cd onetun
|
||||
$ cargo build --release
|
||||
$ ./target/release/onetun
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
onetun uses [tokio](https://github.com/tokio-rs/tokio), the async runtime, to listen for new TCP connections on the
|
||||
given port.
|
||||
|
||||
When a client connects to the local TCP port, it uses [smoltcp](https://github.com/smoltcp-rs/smoltcp) to
|
||||
create a "virtual interface", with a "virtual client" and a "virtual server" for the connection. These "virtual"
|
||||
components are the crux of how onetun works. They essentially replace the host's TCP/IP stack with smoltcp's, which
|
||||
fully runs inside onetun. An ephemeral "virtual port" is also assigned to the connection, in order to route packets
|
||||
back to the right connection.
|
||||
|
||||
When the real client opens the connection, the virtual client socket opens a TCP connection to the virtual server.
|
||||
The virtual interface (implemented by smoltcp) in turn crafts the `SYN` segment and wraps it in an IP packet.
|
||||
Because of how the virtual client and server are configured, the IP packet is crafted with a source address
|
||||
being the configured `source-peer-ip` (`192.168.4.3` in the example above),
|
||||
and the destination address is the remote peer's (`192.168.4.2`).
|
||||
|
||||
By doing this, we let smoltcp handle the crafting of the IP packets, and the handling of the client's TCP states.
|
||||
Instead of actually sending those packets to the virtual server,
|
||||
we can intercept them in the virtual interface and encrypt the packets using [boringtun](https://github.com/cloudflare/boringtun),
|
||||
and send them to the WireGuard endpoint's UDP port.
|
||||
|
||||
Once the WireGuard endpoint receives an encrypted IP packet, it decrypts it using its private key and reads the IP packet.
|
||||
It reads the destination address, re-encrypts the IP packet using the matching peer's public key, and sends it off to
|
||||
the peer's UDP endpoint.
|
||||
|
||||
The remote peer receives the encrypted IP and decrypts it. It can then read the inner payload (the TCP segment),
|
||||
forward it to the server's port, which handles the TCP segment. The server responds with `SYN-ACK`, which goes back through
|
||||
the peer's local WireGuard interface, gets encrypted, forwarded to the WireGuard endpoint, and then finally back to onetun's UDP port.
|
||||
|
||||
When onetun receives an encrypted packet from the WireGuard endpoint, it decrypts it using boringtun.
|
||||
The resulting IP packet is broadcasted to all virtual interfaces running inside onetun; once the corresponding
|
||||
interface is matched, the IP packet is read and unpacked, and the virtual client's TCP state is updated.
|
||||
|
||||
Whenever data is sent by the real client, it is simply "sent" by the virtual client, which kicks off the whole IP encapsulation
|
||||
and WireGuard encryption again. When data is sent by the real server, it ends up routed in the virtual interface, which allows
|
||||
the virtual client to read it. When the virtual client reads data, it simply pushes the data back to the real client.
|
||||
|
||||
This work is all made possible by [smoltcp](https://github.com/smoltcp-rs/smoltcp) and [boringtun](https://github.com/cloudflare/boringtun),
|
||||
so special thanks to the developers of those libraries.
|
||||
|
||||
## License
|
||||
|
||||
MIT. See `LICENSE` for details.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue