# Rusty Penguin

[](https://github.com/myzhang1029/penguin-rs/actions/workflows/rust.yml)
[](https://crates.io/crates/rusty-penguin)
[](https://deps.rs/repo/github/myzhang1029/penguin-rs)
[](https://www.bestpractices.dev/projects/10422)
[](https://codecov.io/gh/myzhang1029/penguin-rs)
[](https://wakatime.com/badge/github/myzhang1029/penguin-rs)

## About
A fast TCP/UDP tunnel, transported over HTTP WebSocket.
You are right. This project is inspired by `jpillora/chisel` (and subsequently
my fork `myzhang1029/penguin`), but completely rewritten in Rust without any
linkage to `chisel`. The logo is generated by [DALL-E](https://labs.openai.com)
with the prompt ["a penguin standing behind a gear wheel, digital art, logo."](
https://labs.openai.com/s/Et1VIeCBREIRHhF7MU9NoZL6
)
## Basic Usage
### Server
```bash
$ penguin server --host ::1 --port 443 --tls-cert cert.pem --tls-key key.pem --ws-psk some-secret
```
See `penguin server --help` for more options.
### Client
```bash
$ penguin client --ws-psk some-secret wss://server 1080:socks 80:example.com:80
```
See `penguin client --help` for more options.
## Comparison
Compared to the original `penguin` or `chisel`, this project stripped away
some functionalities:
- There is no internal SSH tunnels because it results in double encapsulation
when used with HTTPS/WSS.
- There is no user/password authentication because we do not have SSH. Instead,
use PSK authentication.
- There is no server keep-alive because client keep-alive is enough.
- ~~There is no support to acquire an ACME certificate on-the-fly.~~ (Implemented)
- ~~There is no reverse port forwarding because I am too lazy.~~ (Implemented)
Other than that, this project offers these functionalities compared to
`chisel`:
- Plausible deniability with WebSocket PSK and working `backend`.
- TLS certificate hot-reload with `SIGUSR1`.
- Higher performance: my crude testing on my machine reveals that `penguin` is
approximately 2x faster than `chisel` on my machine (`penguin`
commit `73a0045ff` vs `chisel` commit `ab8f06a8`).
```
$ iperf3 -c 127.0.0.1 # chisel without TLS
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.00 sec 5.41 GBytes 4.65 Gbits/sec sender
[ 5] 0.00-10.00 sec 5.40 GBytes 4.64 Gbits/sec receiver
$ iperf3 -c 127.0.0.1 # penguin without TLS
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.00 sec 16.5 GBytes 14.2 Gbits/sec sender
[ 5] 0.00-10.00 sec 16.5 GBytes 14.2 Gbits/sec receiver
$ iperf3 -c 127.0.0.1 # chisel with TLS
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.00 sec 4.79 GBytes 4.12 Gbits/sec sender
[ 5] 0.00-10.01 sec 4.79 GBytes 4.11 Gbits/sec receiver
$ iperf3 -c 127.0.0.1 # penguin with TLS
[ ID] Interval Transfer Bitrate
[ 5] 0.00-10.01 sec 11.0 GBytes 9.48 Gbits/sec sender
[ 5] 0.00-10.01 sec 11.0 GBytes 9.48 Gbits/sec receiver
```
- All the safety Rust offers.
## Protocol
Servers and clients with the same protocol version are compatible with each other. However, for the best performance, it is recommended to use the same version of `penguin` on both sides.
The current protocol version is `penguin-v7`. See [PROTOCOL.md](PROTOCOL.md) for details.
## Contribution
All contributions are welcome. Please make sure you
1. Write test cases for the bugfix/feature
2. Check that the patch passes all tests by running
```
cargo test
```
3. Send a Pull Request.
## License
GPL v3.0 or later or Apache License 2.0.