Skip to content

A fast TCP/UDP tunnel, transported over HTTP WebSocket.

License

Apache-2.0, GPL-3.0 licenses found

Licenses found

Apache-2.0
LICENSE.APACHE
GPL-3.0
LICENSE.GPL
Notifications You must be signed in to change notification settings

myzhang1029/penguin-rs

Repository files navigation

Rusty Penguin

Logo

Cargo Tests Crates.io Dependency Status OpenSSF Best Practices Codecov wakatime License

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 with the prompt "a penguin standing behind a gear wheel, digital art, logo."

Basic Usage

Server

$ 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

$ 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 for details.

Cargo Features

Library features:

  • tungstenite: implement our traits on tokio_tungstenite::WebSocketStream (default)
  • nohash: (caution) use nohash_hasher as the internal flow_id hashmap. This option may be an optimization for resource-constrained devices, but will also open up a DoS attack vector if the peer cannot be trusted. If both peers use this penguin implementation or any other implementation that generates flow_ids with a random number generator, this is safe.

Executable features:

  • client: build the client (default)

  • server: build the server (default)

  • penguin-binary: shorthand for both server and client (default)

  • rustls-native-roots: use rustls with system CA (default)

  • rustls-webpki-roots: use rustls with bundled webpki CA

  • nativetls: use native-tls

  • ring: use ring as the crypto provider for rustls

  • aws-lc-rs: use aws-lc-rs as the crypto provider for rustls

  • default-is-ipv6: use ::/::1 instead of 0.0.0.0/127.0.0.1 when an IP address is omitted in the client command line

  • tokio-console: enable console-subscriber support

  • remove-logging: statically remove trace level logging and tracing code

  • deadlock-detection: spawn a background thread running parking_lot's deadlock detection

  • acme: (requires server) enable the built-in ACME client (default) Will also make the binary use rustls even if nativetls is enabled due to internal dependencies.

  • rustls_keylog: (caution) export TLS session data to the file specified in the environmental variable SSLKEYLOGFILE

Testing features:

  • tests-real-internet4: run tests that require IPv4 access to the internet
  • tests-real-internet6: run tests that require IPv4 access to the internet
  • tests-udp: run tests that expect UDP traffic to work reliably. They may be flaky depending on the network environment.
  • tests-acme-has-pebble: test the ACME client with a local ACME server at https://localhost:14000/dir

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
  1. Send a Pull Request.

License

GPL v3.0 or later or Apache License 2.0.

About

A fast TCP/UDP tunnel, transported over HTTP WebSocket.

Topics

Resources

License

Apache-2.0, GPL-3.0 licenses found

Licenses found

Apache-2.0
LICENSE.APACHE
GPL-3.0
LICENSE.GPL

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages