A fast and stable reverse proxy for NAT traversal, written in Rust
rathole, like frp, can help to expose the service on the device behind the NAT to the Internet, via a server with a public IP.
To use rathole, you need a server with a public IP, and a device behind the NAT, where some services that need to be exposed to the Internet.
Assuming you have a NAS at home behind the NAT, and want to expose its ssh service to the Internet:
- On the server which has a public IP
server.toml with the following content and accommodate it to your needs.
# server.toml [server] bind_addr = "0.0.0.0:2333" # `2333` specifys the port that rathole listens for clients [server.services.my_nas_ssh] token = "use_a_secret_that_only_you_know" # Token that is used to authenticate the client for the service. Change to a arbitrary value. bind_addr = "0.0.0.0:5202" # `5202` specifys the port that exposes `my_nas_ssh` to the Internet
- On the host which is behind the NAT (your NAS)
client.toml with the following content and accommodate it to your needs.
[client] remote_addr = "myserver.com:2333" # The address of the server. The port must be the same with the port in `server.bind_addr` [client.services.my_nas_ssh] token = "use_a_secret_that_only_you_know" # Must be the same with the server to pass the validataion local_addr = "127.0.0.1:22" # The address of the service that needs to be forwarded
- Now the client will try to connect to the server
2333, and any traffic to
myserver.com:5202will be forwarded to the client's port
So you can
ssh myserver.com:5202 to ssh to your NAS.
rathole can automatically determine to run in the server mode or the client mode, according to the content of the configuration file, if only one of
[client] block is present, like the example in Quickstart.
[server] block can also be put in one file. Then on the server side, run
rathole --server config.toml and on the client side, run
rathole --client config.toml to explictly tell
rathole the running mode.
Here is the full configuration specification:
[client] remote_addr = "example.com:2333" # Necessary. The address of the server default_token = "default_token_if_not_specify" # Optional. The default token of services, if they don't define their own ones [client.services.service1] # A service that needs forwarding. The name `service1` can change arbitrarily, as long as identical to the name in the server's configuration token = "whatever" # Necessary if `client.default_token` not set local_addr = "127.0.0.1:1081" # Necessary. The address of the service that needs to be forwarded [client.services.service2] # Multiple services can be defined local_addr = "127.0.0.1:1082" [server] bind_addr = "0.0.0.0:2333" # Necessary. The address that the server listens for clients. Generally only the port needs to be change. default_token = "default_token_if_not_specify" # Optional [server.services.service1] # The service name must be identical to the client side token = "whatever" # Necesary if `server.default_token` not set bind_addr = "0.0.0.0:8081" # Necessary. The address of the service is exposed at. Generally only the port needs to be change. [server.services.service2] bind_addr = "0.0.0.1:8082"
rathole has similiar latency to frp, but can handle more connections. Also it can provide much better bandwidth than frp.
See also Benchmark.
rathole is in active development. A load of features is on the way:
- UDP support
- TLS transport
- Hot reloading
- HTTP APIs for configuration