Skip to content
 
 

Repository files navigation

rathole

rathole-logo

GitHub stars GitHub release (latest SemVer) GitHub Workflow Status (branch) GitHub all releases Docker Pulls Join the chat at https://gitter.im/rapiz1/rathole

English | 简体中文

A secure, stable and high-performance reverse proxy for NAT traversal, written in Rust

rathole, like frp and ngrok, can help to expose the service on the device behind the NAT to the Internet, via a server with a public IP.

Features

  • High Performance Much higher throughput can be achieved than frp, and more stable when handling a large volume of connections. See Benchmark
  • Low Resource Consumption Consumes much fewer memory than similar tools. See Benchmark. The binary can be as small as ~500KiB to fit the constraints of devices, like embedded devices as routers.
  • Security Users and tokens are used for authentication. With the optional Noise Protocol, encryption can be configured at ease. No need to create a self-signed certificate!
  • Hot Reload Services can be added or removed dynamically by hot-reloading the configuration file. HTTP API is WIP.

Quickstart

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.

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:

[server]
bind_addr = "0.0.0.0:2333"

[server.users.default] # Define a user
token = "my_secret_token" # Optional password

[server.services.my_nas_ssh]
user = "default"
bind_addr = "0.0.0.0:5202"
  1. On the host which is behind the NAT (your NAS)

Create client.toml:

[client]
remote_addr = "myserver.com:2333"
user = "default"
token = "my_secret_token"

[client.services.my_nas_ssh]
local_addr = "127.0.0.1:22"

Then run rathole server.toml on the server and rathole client.toml on the client.

Visitor Mode (FRP-style)

rathole supports a "Visitor Mode" where the client can request the server to bind to a specific address/port.

Server Configuration:

  1. Run rathole --genkey to get your server's identity.
  2. Configure server.toml:
[server]
bind_addr = "0.0.0.0:2333"

[server.transport]
type = "udp"
[server.transport.noise]
local_private_key = "SERVER_PRIVATE_KEY_HERE"

[server.users.alice]
token = "alice_token"
allowed_ports = "2000-3000" # Alice can bind to these ports

Client Configuration:

[client]
remote_addr = "myserver.com:2333"
user = "alice"
token = "alice_token"

[client.transport]
type = "udp"
[client.transport.noise]
remote_public_key = "SERVER_PUBLIC_KEY_HERE"

[client.services.my_service]
local_addr = "127.0.0.1:8080"
remote_bind_addr = "0.0.0.0:2334"

Docker

  rathole:
    image: ghcr.io/nelonn/rathole-ng:nightly
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./rathole-config.toml:/rathole-config.toml

Configuration

[client]
remote_addr = "example.com:2333"
user = "default" # Default user for services
token = "test_token" # Default token for services

[client.transport]
type = "udp" # Possible values: ["tcp", "udp"]

[client.transport.noise] # Noise protocol layer
pattern = "Noise_IK_25519_ChaChaPoly_BLAKE2s"
remote_public_key = "SERVER_PUBLIC_KEY"
psk = "optional_transport_psk"

[client.services.service1]
local_addr = "127.0.0.1:1081"
# user and token can be overridden here

[server]
bind_addr = "0.0.0.0:2333"

[server.users.alice]
token = "alice_token"
allowed_ports = "2000-3000"

[server.transport]
type = "udp"

[server.transport.noise]
local_private_key = "SERVER_PRIVATE_KEY"

[server.services.service1]
user = "alice"
bind_addr = "0.0.0.0:8081"

Benchmark

http_throughput tcp_bitrate udp_bitrate mem

About

A lightweight and high-performance reverse proxy for NAT traversal, written in Rust. An alternative to frp and ngrok.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages