rathole/README.md

155 lines
7.4 KiB
Markdown
Raw Normal View History

2021-12-11 13:30:42 +01:00
# rathole
2021-12-18 11:34:26 +01:00
![rathole-logo](./docs/img/rathole-logo.png)
2021-12-11 13:30:42 +01:00
[English](README.md) | [简体中文](README-zh.md)
A secure, stable and high-performance reverse proxy for NAT traversal, written in Rust
2021-12-11 13:30:42 +01:00
2021-12-27 08:46:38 +01:00
rathole, like [frp](https://github.com/fatedier/frp) and [ngrok](https://github.com/inconshreveable/ngrok), can help to expose the service on the device behind the NAT to the Internet, via a server with a public IP.
## Features
2021-12-11 13:30:42 +01:00
- **High Performance** Much higher throughput can be achieved than frp, and more stable when handling a large volume of connections. See [Benchmark](#Benchmark)
- **Low Resource Consumption** Consumes much fewer memory than similar tools. See [Benchmark](#Benchmark). [The binary can be](docs/build-guide.md) **as small as ~500KiB** to fit the constraints of devices, like embedded devices as routers.
- **Security** Tokens of services are mandatory and service-wise. The server and clients are responsible for their own configs. With the optional Noise Protocol, encryption can be configured at ease. No need to create a self-signed certificate! TLS is also supported.
- **Hot Reload** Services can be added or removed dynamically by hot-reloading the configuration file. HTTP API is WIP.
2021-12-24 15:42:04 +01:00
2021-12-11 13:30:42 +01:00
## Quickstart
2022-01-02 09:38:31 +01:00
A full-powered `rathole` can be obtained from the [release](https://github.com/rapiz1/rathole/releases) page. Or [build from source](docs/build-guide.md) for other platforms and customizing the binary.
The usage of `rathole` is ver similar to frp. If you have experience with the latter, then the configuration is very easy for you. The only difference is that configuration of a service is splited into the client side and the server side, and a token is mandatory.
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.
2021-12-11 13:30:42 +01:00
Assuming you have a NAS at home behind the NAT, and want to expose its ssh service to the Internet:
1. On the server which has a public IP
Create `server.toml` with the following content and accommodate it to your needs.
```toml
# 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
```
Then run:
```bash
./rathole server.toml
```
2. On the host which is behind the NAT (your NAS)
Create `client.toml` with the following content and accommodate it to your needs.
```toml
# client.toml
2021-12-11 13:30:42 +01:00
[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
```
Then run:
```bash
./rathole client.toml
```
3. Now the client will try to connect to the server `myserver.com` on port `2333`, and any traffic to `myserver.com:5202` will be forwarded to the client's port `22`.
So you can `ssh myserver.com:5202` to ssh to your NAS.
## Configuration
`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 `[server]` and `[client]` block is present, like the example in [Quickstart](#Quickstart).
But the `[client]` and `[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.
Before heading to the full configuration specification, it's recommaned to skim [the configuration examples](./examples) to get a feeling of the configuration format.
2021-12-18 11:35:46 +01:00
See [Security](./docs/security.md) for more details about encryption and the `transport` block.
2021-12-24 14:57:37 +01:00
2021-12-11 13:30:42 +01:00
Here is the full configuration specification:
```toml
[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
2021-12-25 07:56:23 +01:00
[client.transport] # The whole block is optional. Specify which transport to use
type = "tcp" # Optional. Possible values: ["tcp", "tls", "noise"]. Default: "tcp"
2021-12-24 14:57:37 +01:00
2021-12-15 08:12:36 +01:00
[client.transport.tls] # Necessary if `type` is "tls"
trusted_root = "ca.pem" # Necessary. The certificate of CA that signed the server's certificate
hostname = "example.com" # Optional. The hostname that the client uses to validate the certificate. If not set, fallback to `client.remote_addr`
2021-12-24 14:57:37 +01:00
[client.transport.noise] # Noise protocol. See `docs/security.md` for further explanation
pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s" # Optional. Default value as shown
local_private_key = "key_encoded_in_base64" # Optional
remote_public_key = "key_encoded_in_base64" # Optional
2021-12-11 13:30:42 +01:00
[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
type = "tcp" # Optional. The protocol that needs forwarding. Possible values: ["tcp", "udp"]. Default: "tcp"
2021-12-11 13:30:42 +01:00
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
2021-12-25 07:56:23 +01:00
[server.transport] # Same as `[client.transport]`
type = "tcp"
2021-12-24 14:57:37 +01:00
[server.transport.tls] # Necessary if `type` is "tls"
2021-12-15 08:12:36 +01:00
pkcs12 = "identify.pfx" # Necessary. pkcs12 file of server's certificate and private key
pkcs12_password = "password" # Necessary. Password of the pkcs12 file
2021-12-24 14:57:37 +01:00
[server.transport.noise] # Same as `[client.transport.noise]`
pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s"
local_private_key = "key_encoded_in_base64"
remote_public_key = "key_encoded_in_base64"
2021-12-11 13:30:42 +01:00
[server.services.service1] # The service name must be identical to the client side
type = "tcp" # Optional. Same as the client `[client.services.X.type]
2021-12-11 13:30:42 +01:00
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"
```
2021-12-19 12:37:24 +01:00
### Logging
`rathole`, like many other Rust programs, use environment variables to control the logging level. `info`, `warn`, `error`, `debug`, `trace` are avialable.
```
RUST_LOG=error ./rathole config.toml
```
will run `rathole` with only error level logging.
If `RUST_LOG` is not present, the default logging level is `info`.
## Benchmark
2021-12-11 13:30:42 +01:00
rathole has similiar latency to [frp](https://github.com/fatedier/frp), but can handle a more connections, provide larger bandwidth, with less memory usage.
2021-12-11 13:30:42 +01:00
2021-12-18 11:34:26 +01:00
See also [Benchmark](./docs/benchmark.md).
2021-12-11 13:30:42 +01:00
![http_throughput](./docs/img/http_throughput.svg)
2021-12-18 11:34:26 +01:00
![tcp_bitrate](./docs/img/tcp_bitrate.svg)
![udp_bitrate](./docs/img/udp_bitrate.svg)
![mem](./docs/img/mem-graph.png)
2021-12-11 13:30:42 +01:00
## Development Status
2021-12-11 13:30:42 +01:00
2021-12-27 08:46:38 +01:00
`rathole` is under active development. A load of features is on the way:
- [x] TLS support
- [x] UDP support
2021-12-27 08:46:38 +01:00
- [x] Hot reloading
2021-12-11 13:30:42 +01:00
- [ ] HTTP APIs for configuration