Rathole is an efficient reverse proxy tool designed for NAT traversal, developed in the Rust programming language. It falls under the category of networking software known as a proxy, which facilitates communication, between computers over the internet that are hindered by NAT on Linux systems.
What is NAT traversal? Simply put it as a networking technique used to establish communication between devices located behind a NAT (Network Address Translation) device and those outside the NAT network. When we refer to devices behind a NAT we are talking about devices that share a IP address making it challenging to specify a target IP address when communicating with them.
Let’s have a look at it’s features:
- Efficient NAT Traversal: When it comes to traversing NAT, Rathole is a much better choice because in a way, we can say that it uses smart ways to make sure your network services can be accessed without tampering with your network setup too much.
- TLS Support: Since Rathole uses TLS Encryption, you don’t have to worry about the safety of your data from hackers and internet providers. TLS encryption protects the exchange of sensitive data such as your passwords, payment information and other personal information.
- Works with WebSockets: Today’s apps need to share data instantly, and Rathole supports WebSockets right out of the box. This means your apps can chat back and forth without any hiccups.
- Load Balancing: What Rathole does it to distribute the internet traffic coming to and from your site across multiple servers. With multiple servers running, traffic will be minimal and your site can service more requests ad faster.
- Easy to Set Up: To set up Rathole, all you need is a YAML file with Rathole configurations. YAML is a human-readable language used to write configuration files. This means you can get Rathole running quickly without much effort.
- High Performance: Rathole offers more elevated efficiency compared to fpr, hence much better throughput is obtained. It is also more reliable when managing a large number of connection.
What is the need for a NAT Traversal Reverse Proxy?
NAT serves as a method to safeguard IP addresses and enhance security by concealing network details. However it can pose challenges, for connections. In such cases, a NAT traversal reverse proxy becomes essential and this is where Rathole comes into play as a solution to this issue. From a different point of view, you can say that Rathole acts as a middle man. It facilitates safe and secure communication between the internet and private networks and the other way round. With these, we can access network services run in systems behind a NAT barrier securely and with high scalability.
Installing and Using Rathole – reverse proxy for NAT traversal
To begin using Rathole you just need to follow an steps. Setting up Rathole involves downloading the package from the official repository. Because Rathole has requirements you can have it installed and running quickly. To utilize Rathole effectively you’ll require a server, with an internet connection and a device situated behind NAT. This is crucial if you intend to expose services on the internet.
You can download Rathole for free, from its page. Another option is to customize it for compatibility with systems and to reduce the programs size or you can simply use the pre made Docker image. If you’re familiar with frp using Rathole should be straightforward. Setting it up is quite simple especially if you have experience, with frp. The biggest change is how you set it up, which you have to do on both the client and server sides, and you need a token to make it work.
Step 1. Download Rathole
To get Rathole:
- Go to GitHub release page: Rathole has a GitHub page for the sole purpose of version control. From here, you can find any version of Rathole that has ever been released. All you have to do is choose the one you prefer and download it. Every version available on the GitHub page is ready for use.
- Build from source: If you prefer to build Rathole from the source code itself, the task is your for the taking. This is usually a recommended when you need it to work on a special kind of computer or you want to make the program smaller. For this task, you’ll need to have Rust set up on your computer.
- Use Docker: Another option for installing Rathole is using docker. A docker image is readily available on Docker Hub, all you have to do is pull the image and run it. You can run a command as such:
pull rathole/rathole:latest
Step 2. Quick Start
Ratholes setup involves dividing tasks between the server and client sides necessitating a token for ensuring communication. If you have a Network Attached Storage (NAS) device, at your residence located behind a NAT (Network Address Translation) which means it’s not directly reachable, from the web here’s how you can access its SSH service from online:
- Server Configuration: For the server setup, you need to configure Rathole on the machine with a public IP address. This involves creating a configuration file, typically in YAML format, where you specify the port for Rathole to listen on and the authentication token for secure access. On the server which has a public IP:
Create server.toml
with the following content and accommodate it to your needs.
# server.toml
[server]
bind_addr = "0.0.0.0:2333" # `2333` specifies 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` specifies the port that exposes `my_nas_ssh` to the Internet
Then run:
./rathole server.toml
- Client Configuration: On your side, with your computer behind a router (that’s the NAT bit), you set up Rathole to point at your server’s internet address and the port you chose. You use the same secret code to make sure the connection is safe. Here, you also decide which of your computer’s services you want Rathole to share online. On the host which is behind the NAT:
Create client.toml
with the following content and accommodate it to your needs.
# client.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 validation
local_addr = "127.0.0.1:22" # The address of the service that needs to be forwarded
Then run:
./rathole client.toml
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 go ahead and try ssh myserver.com:5202
or ssh -p 5202 localhost
to ssh to your NAS. The ssh
command should be run on the client machine from which you want to establish an SSH connection to the server. In this context, the client machine refers to the machine where the Rathole client is running.
Step 3. Configuration
However, the [client] and [server] blocks may alternatively be included in a single file. Then, to explicitly notify rathole the running mode, run rathole --server config.toml
on the server side and rathole --client config.toml
on the client side.
Here is the full configuration specifics:
[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
heartbeat_timeout = 40 # Optional. Set to 0 to disable the application-layer heartbeat test. The value must be greater than `server.heartbeat_interval`. Default: 40 seconds
retry_interval = 1 # Optional. The interval between retry to connect to the server. Default: 1 second
[client.transport] # The whole block is optional. Specify which transport to use
type = "tcp" # Optional. Possible values: ["tcp", "tls", "noise"]. Default: "tcp"
[client.transport.tcp] # Optional. Also affects `noise` and `tls`
proxy = "socks5://user:[email protected]:1080" # Optional. The proxy used to connect to the server. `http` and `socks5` is supported.
nodelay = true # Optional. Determine whether to enable TCP_NODELAY, if applicable, to improve the latency but decrease the bandwidth. Default: true
keepalive_secs = 20 # Optional. Specify `tcp_keepalive_time` in `tcp(7)`, if applicable. Default: 20 seconds
keepalive_interval = 8 # Optional. Specify `tcp_keepalive_intvl` in `tcp(7)`, if applicable. Default: 8 seconds
[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`
[client.transport.noise] # Noise protocol. See `docs/transport.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
[client.transport.websocket] # Necessary if `type` is "websocket"
tls = true # If `true` then it will use settings in `client.transport.tls`
[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"
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
nodelay = true # Optional. Override the `client.transport.nodelay` per service
retry_interval = 1 # Optional. The interval between retry to connect to the server. Default: inherits the global config
[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
heartbeat_interval = 30 # Optional. The interval between two application-layer heartbeat. Set to 0 to disable sending heartbeat. Default: 30 seconds
[server.transport] # Same as `[client.transport]`
type = "tcp"
[server.transport.tcp] # Same as the client
nodelay = true
keepalive_secs = 20
keepalive_interval = 8
[server.transport.tls] # Necessary if `type` is "tls"
pkcs12 = "identify.pfx" # Necessary. pkcs12 file of server's certificate and private key
pkcs12_password = "password" # Necessary. Password of the pkcs12 file
[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"
[server.transport.websocket] # Necessary if `type` is "websocket"
tls = true # If `true` then it will use settings in `server.transport.tls`
[server.services.service1] # The service name must be identical to the client side
type = "tcp" # Optional. Same as the client `[client.services.X.type]
token = "whatever" # Necessary 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.
nodelay = true # Optional. Same as the client
[server.services.service2]
bind_addr = "0.0.0.1:8082"
Conclusion
To wrap it up, Rathole is has prove to be an amazing tool for Linux user trying to find a way around NAT on Linux systems. What makes it so great is how it brings together good performance, safety, and simple handling in a way that sums it up to be very user-friendly and simple. With its support for TLS encryption, WebSocket integration, and load balancing, plus its easy-to-understand YAML setup, we can comfortably say that it qualifies as an all round tool for handling all kinds of projects, whether they’re just for fun or for big companies.