rapiz1 / rathole Goto Github PK
View Code? Open in Web Editor NEWA lightweight and high-performance reverse proxy for NAT traversal, written in Rust. An alternative to frp and ngrok.
License: Apache License 2.0
A lightweight and high-performance reverse proxy for NAT traversal, written in Rust. An alternative to frp and ngrok.
License: Apache License 2.0
noise support brings about an increase of 0.4 MiB in the binary size. Separate it as a crate feature to mitigate that.
TCP_NODELAY
for all control channelsSeems to reduce the latency in a primitive test, but also impact the bandwidth.
Current CI doesn't publish to crates.io and it's easy to be out of date. CI should publish the crate on crates.io
keepalive is missed for noise transport. It needs to be added
rathole
uses about as 1/5 memory as frp uses. A more formed benchmark should be created to show that.
Lines 40 to 46 in e6dd0c8
UdpSocket::bind("0.0.0.0:0").await?
binds to a IPv4 UDP socket and cannot be used to connect to an IPv6 address. A match
on addr
can solve this issue.
The current implementation transmits all UDP packets on one TCP connection. It just works, but can be improved for more handling more visitors
A full-powered rathole can be obtained from the release page. Or build from source for other platforms and minimizing the binary. A Docker image is also available.
Why not cargo install rathole
?
I tried but it fails
error: failed to run custom build command for `rathole v0.3.1`
Caused by:
process didn't exit successfully: `/tmp/cargo-installeiw1LE/release/build/rathole-4166e51a1e9957bd/build-script-build` (exit status: 1)
--- stderr
Error: could not find repository from '/home/hackerzol/.cargo/registry/src/github.com-1ecc6299db9ec823/rathole-0.3.1'; class=Repository (6); code=NotFound (-3)
warning: build failed, waiting for other jobs to finish...
error: failed to compile `rathole v0.3.1`, intermediate artifacts can be found at `/tmp/cargo-installeiw1LE`
Caused by:
build failed
Lots of features and optimization have been introduced since v0.1.0. Documentations are needed to indicate that, including:
cargo strip
has been stabilized. We should enable it after the release is out.
Currently if a data channel is broken, it's still remaining in the connection pool for the latter use. It's not an issue for most applications but disturbs users.
This is unlikely to occur. But if a hot-reload for a service and a TCP connection arrives at the same time, the TCP connection will be dropped.
Lines 140 to 143 in 1240dd8
A primitive thought is to turn Transport::accept
into Transport::handshake
and make it accept a raw TCP connection. And use TCPListener::accept in select because it is cancel safe. However it breaks some abstraction and assumes the underlying protocol is TCP, which causes trouble for UDP-based transport, like QUIC. So maybe the trait can be redesigned in another way. Thoughts will be welcome.
Or keep the trait unchanged and write a future to make Transport::accept
cancel safe. I don't know if that's feasible. For TCP, it's impossible to put an accepted connection back to the system backlog. And generally handshake consists of multiple packets. I doubt it can made cancel safe without altering the trait. Redesigning the trait seems the way to go.
Use crate features to conditional compile:
And default with all features on
Since only SHA256 in ring
is used and ring
doesn't support some platforms well, it can be replaced with some pure rust library.
If I change the service name, the client does not know to unregister the previous service, and re-register a new service under the same name. Getting the following error:
Jan 05 07:06:15.562 ERROR new{service=foo1}: rathole::client: Failed to run the control channel
Caused by:
0: Authentication failed: foo1
1: Service not exist
Retry in 1s...
server side log:
5|rathole | Jan 16 12:33:10.150 INFO handle_connection{addr=58.246.229.238:22945}:new{service=ssu}:run{service=ssu}: rathole::server: Control channel shutdown
5|rathole | Jan 16 12:33:11.283 INFO handle_connection{addr=58.246.229.238:23425}: rathole::server: Try to handshake a control channel
5|rathole | Jan 16 12:33:11.293 WARN handle_connection{addr=58.246.229.238:23425}: rathole::server: Dropping previous control channel for service ssu
5|rathole | Jan 16 12:33:11.293 INFO handle_connection{addr=58.246.229.238:23425}: rathole::server: Control channel established service=ssu
5|rathole | Jan 16 12:33:11.293 INFO handle_connection{addr=58.246.229.238:23425}:new{service=ssu}:run_udp_connection_pool: rathole::server: Listening at 0.0.0.0:18088
5|rathole | Jan 16 12:33:11.321 DEBUG handle_connection{addr=58.246.229.238:23457}: rathole::server: Try to handshake a data channel
5|rathole | Jan 16 12:33:11.322 DEBUG handle_connection{addr=58.246.191.50:9281}: rathole::server: Try to handshake a data channel
5|rathole | Jan 16 12:33:28.487 ERROR handle_connection{addr=58.246.229.238:23425}:new{service=ssu}: rathole::server: Failed to run TCP connection pool
5|rathole | Caused by:
5|rathole | Connection reset by peer (os error 104)
5|rathole | Jan 16 12:33:28.487 INFO handle_connection{addr=58.246.229.238:23425}:new{service=ssu}:run{service=ssu}: rathole::server: Control channel shutdown
5|rathole | Jan 16 12:33:29.658 INFO handle_connection{addr=58.246.229.238:24225}: rathole::server: Try to handshake a control channel
5|rathole | Jan 16 12:33:29.667 WARN handle_connection{addr=58.246.229.238:24225}: rathole::server: Dropping previous control channel for service ssu
5|rathole | Jan 16 12:33:29.667 INFO handle_connection{addr=58.246.229.238:24225}: rathole::server: Control channel established service=ssu
5|rathole | Jan 16 12:33:29.668 INFO handle_connection{addr=58.246.229.238:24225}:new{service=ssu}:run_udp_connection_pool: rathole::server: Listening at 0.0.0.0:18088
5|rathole | Jan 16 12:33:29.703 DEBUG handle_connection{addr=58.246.229.238:24258}: rathole::server: Try to handshake a data channel
5|rathole | Jan 16 12:33:29.705 DEBUG handle_connection{addr=58.246.191.50:10274}: rathole::server: Try to handshake a data channel
5|rathole | Jan 16 12:33:57.304 ERROR handle_connection{addr=58.246.229.238:24225}:new{service=ssu}: rathole::server: Failed to run TCP connection pool
5|rathole | Caused by:
5|rathole | unexpected end of file
client side log:
4|rathole | Jan 16 12:33:28.384 ERROR new{service=ssu}: rathole::client: Failed to run the control channel
4|rathole | Caused by:
4|rathole | 0: Failed to read control cmd
4|rathole | 1: early eof
4|rathole | Retry in 1s...
4|rathole | Jan 16 12:33:29.565 INFO new{service=ssu}:run: rathole::client: Control channel established
4|rathole | Jan 16 12:33:57.190 ERROR new{service=ssu}:run: rathole::client: Failed to run the data channel
4|rathole | Caused by:
4|rathole | 0: Failed to deserialize udp header
4|rathole | 1: invalid value: integer `3070230528`, expected `V4` or `V6`
4|rathole | Jan 16 12:33:57.199 ERROR new{service=ssu}:run: rathole::client: Failed to run the data channel
4|rathole | Caused by:
4|rathole | 0: Failed to read data cmd
4|rathole | 1: early eof
Caused by:
0: Failed to read control cmd
1: early eof
Retry in 1s...
Jan 14 12:37:44.956 ERROR new{service=my_nas_ssh}:run: rathole::client: Failed to run the data channel
Current handshake functions don't call flush
after sending each packets. It may be an issue affecting reliability.
# freebsd-version
12.2-RELEASE-p11
cargo build --release
Error message:
error[E0609]: no field `uid` on type `&Process`
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/vergen-6.0.0/src/feature/si.rs:265:28
|
265 | *user.uid() == process.uid
| ^^^ unknown field
For more information about this error, try `rustc --explain E0609`.
Would you please help?
Current CI only compiles against only a few targets, which causes inconvenience for end users.
x86_64_unknown-linux-gnu
links a glibc of ubuntu-latest, which may be too new for some distributions. -musl
should be added to facilitate older distributions.
Current logs are always colorful. It will better to automatically disable the color if the output is a pipe
Maybe use tc
?
Someone requests it and it should be easy to create one, though it doesn't seem quite useful to me. These days people are get used to just typing docker run
.
A Dockerfile
can be created under the root of the project.
thread 'main' panicked at 'called Result::unwrap()
on an Err
value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }', /cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.15.0/src/runtime/blocking/pool.rs:247:14
note: run with RUST_BACKTRACE=1
environment variable to display a backtrace
Aborted
sometime the clinet cannot connect server direct,client need to connect server by an proxy (Usually HTTP proxy)
RUST_LOG
I tried to use cargo install rathole
to install rathole, but got a result like this.
WARN rustc_codegen_ssa::back::link Linker does not support -no-pie command line option. Retrying without.
error: failed to compile `rathole v0.3.8`, intermediate artifacts can be found at `/tmp/cargo-installAxF1R0`
Caused by:
could not compile `rathole`
Caused by:
process didn't exit successfully: `rustc --crate-name rathole --edition=2021 /root/.cargo/registry/src/mirrors.ustc.edu.cn-61ef6e0cd06fb9b8/rathole-0.3.8/src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto --cfg 'feature="base64"' --cfg 'feature="client"' --cfg 'feature="default"' --cfg 'feature="hot-reload"' --cfg 'feature="noise"' --cfg 'feature="notify"' --cfg 'feature="server"' --cfg 'feature="snowstorm"' --cfg 'feature="tls"' --cfg 'feature="tokio-native-tls"' -C metadata=e437c7ced0e7eeb5 -C extra-filename=-e437c7ced0e7eeb5 --out-dir /tmp/cargo-installAxF1R0/release/deps -L dependency=/tmp/cargo-installAxF1R0/release/deps --extern anyhow=/tmp/cargo-installAxF1R0/release/deps/libanyhow-730a28b8f79ceb5d.rlib --extern async_trait=/tmp/cargo-installAxF1R0/release/deps/libasync_trait-a4dc42297c0ceffd.so --extern atty=/tmp/cargo-installAxF1R0/release/deps/libatty-f50d19c10292bf76.rlib --extern backoff=/tmp/cargo-installAxF1R0/release/deps/libbackoff-13a4b179c6b6ecbb.rlib --extern base64=/tmp/cargo-installAxF1R0/release/deps/libbase64-12a9411d5668daac.rlib --extern bincode=/tmp/cargo-installAxF1R0/release/deps/libbincode-0d0f9498b364a491.rlib --extern bytes=/tmp/cargo-installAxF1R0/release/deps/libbytes-e48e07cf49912739.rlib --extern clap=/tmp/cargo-installAxF1R0/release/deps/libclap-90189fe0dddb30d0.rlib --extern const_format=/tmp/cargo-installAxF1R0/release/deps/libconst_format-c0e3e1842b42edc8.rlib --extern fdlimit=/tmp/cargo-installAxF1R0/release/deps/libfdlimit-afa4c3a19c6961bd.rlib --extern hex=/tmp/cargo-installAxF1R0/release/deps/libhex-c24168e20527c0e0.rlib --extern lazy_static=/tmp/cargo-installAxF1R0/release/deps/liblazy_static-4cfee8f8757b12d4.rlib --extern notify=/tmp/cargo-installAxF1R0/release/deps/libnotify-3217dbbdb1e5c269.rlib --extern rand=/tmp/cargo-installAxF1R0/release/deps/librand-3066103e7a256266.rlib --extern rathole=/tmp/cargo-installAxF1R0/release/deps/librathole-d00699d9f968f2b1.rlib --extern serde=/tmp/cargo-installAxF1R0/release/deps/libserde-cac8618c1490a5ea.rlib --extern sha2=/tmp/cargo-installAxF1R0/release/deps/libsha2-b9c52311cf212fd3.rlib --extern snowstorm=/tmp/cargo-installAxF1R0/release/deps/libsnowstorm-810f2b49afb5a323.rlib --extern socket2=/tmp/cargo-installAxF1R0/release/deps/libsocket2-6037ebe9b9eec2d3.rlib --extern tokio=/tmp/cargo-installAxF1R0/release/deps/libtokio-6b32e572b38416e2.rlib --extern tokio_native_tls=/tmp/cargo-installAxF1R0/release/deps/libtokio_native_tls-3105911603e52e49.rlib --extern toml=/tmp/cargo-installAxF1R0/release/deps/libtoml-5bafa3b48212c2ea.rlib --extern tracing=/tmp/cargo-installAxF1R0/release/deps/libtracing-62c2bfdcceec5fea.rlib --extern tracing_subscriber=/tmp/cargo-installAxF1R0/release/deps/libtracing_subscriber-7972557a3e5b499c.rlib --cap-lints allow` (signal: 9, SIGKILL: kill)
UDP test packets should vary in length. Maybe more concurrency and duration.
如题
Add CI including:
cargo clippy
cargo test
Lines 224 to 234 in 6eb0a13
Current integration tests are flawed because it ignores spawned task panic. If fixed then it shows that noise transport actually fails the test.
Further investigation shows that snowstorm::stream::NoiseStream
consumes all CPU when using with tokio::io::copy_bidirectional
.
Client side experience constant control channel and data plane flapping while tunnelling UDP traffic. In the meanwhile, TCP tunnel is working without an issue.
Both server and client are deployed with official docker image.
The UDP service being tunnelling is wireguard, MTU has been adjusted to accommodate tunnelling and avoid fragmentation.
Error message on client side:
Jan 07 02:02:52.122 INFO new{service=some_service}:run: rathole::client: Control channel established
Jan 07 02:02:52.817 ERROR new{service=some_service}: rathole::client: Failed to run the control channel
Caused by:
0: Failed to read control cmd
1: early eof
Retry in 1s...
Jan 07 02:02:52.818 ERROR new{service=some_service}:run: rathole::client: Failed to run the data channel
Caused by:
unexpected end of file
Jan 07 02:02:52.819 ERROR new{service=some_service}:run: rathole::client: Failed to run the data channel
Caused by:
0: Failed to read data cmd
1: early eof
Jan 07 02:02:54.162 INFO new{service=some_service}:run: rathole::client: Control channel established
Jan 07 02:02:54.879 ERROR new{service=some_service}: rathole::client: Failed to run the control channel
Server side configuration snap:
[server]
bind_addr = "someaddr:8080"
default_token = "sometoken"
[server.transport]
type = "noise"
[server.transport.noise]
local_private_key = "somekey"
[server.services.some_service]
type = "udp"
bind_addr = "0.0.0.0:51820"
Client side configuration snap:
[client]
remote_addr = "someaddr:8080"
default_token = "sometoken"
[client.transport]
type = "noise"
[client.transport.noise]
remote_public_key = "somekey"
[client.services.some_service]
type = "udp"
local_addr = "someip:51820"
I tried to exec rathole binaries on mipsel device and config it from examples, but it print nothing and usage 25% CPU(100% single thread), looks like be in infinite loop.
CPU is MT7621AT, dual-core with quad-thread.
System is Padavan 3.4.3.9-099_21-10-3, build by hiboyhiboyhiboy.
With the introduce of the config watcher, if the main task encounters unrecoverable errors, the task will exit silently and leave the program freeze until next configuration change.
The expected behavior is to abort the program.
Here is the documentation link
See also how bytes
get it done using cargo-hack
In some setups, rathole
can't watch the configuration change if it's modified by vim.
https://vi.stackexchange.com/questions/25030/vim-not-firing-inotify-events-when-writing-file
It looks like vim
only does this under certain environments. Hot-reload works on my Arch, though.
This can be worked around and should not bother most users.
`Jan 13 12:18:01.913 ERROR new{service=my_ssh}: rathole::client: Failed to run the control channel
Caused by:
0: Failed to read control cmd
1: early eof
Retry in 1s...
Jan 13 12:18:01.939 ERROR new{service=my_ssh}:run: rathole::client: Failed to run the data channel
Caused by:
0: Failed to read data cmd
1: early eof`
This was happening all the time since the client started,I don't know why it happened,but it didn't affect the connection actually,I could still ssh to the computer behind NAT.
Like:
[client.transport]
type = "tcp"
[client.transport.tcp]
proxy = "socks5://localhost:1080" # connect to the server via a socks5 proxy
or
[client.transport]
type = "tcp"
[client.transport.tcp]
proxy = "http://localhost:1080" # connect to the server via a http proxy
Currently we only release binaries with full features. In the future, we can also release binaries with different feature combinations.
Maybe useful combinations:
minimal
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.