rathole, like [frp](https://github.com/fatedier/frp), can help to expose the service on the device behind the NAT to the Internet, via a server with a public IP.
- **High Performance** Much higher throughput can be achieved than frp. See [Benchmark](#Benchmark)
- **Low Resource Consumption** Much less memory is consumed and well managed by Rust.
- **Secure Model** Tokens of services are mandatory and service-wise. The server and clients are responsible for their own configs.
- **Encryption** With the help of the Noise Protocol, encryption can be configured at ease. No need to create a self-signed certificate!
- **Flexibility** While the default profile produces a small binary, it can be customized to be even smaller to fit the constraints of devices, like embedded devices as routers.
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:
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]
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.
[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
`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`.
rathole has similiar latency to [frp](https://github.com/fatedier/frp), but can handle more connections. Also it can provide much better bandwidth than frp.