内网穿透工具:rathole
rathole
项目简介
项目特点
- 高性能 具有更高的吞吐量,高并发下更稳定。见Benchmark
- 低资源消耗 内存占用远低于同类工具。见Benchmark。二进制文件最小可以到 ~500KiB,可以部署在嵌入式设备如路由器上。
- 安全性 每个服务单独强制鉴权。Server 和 Client 负责各自的配置。使用 Noise Protocol 可以简单地配置传输加密,而不需要自签证书。同时也支持 TLS。
- 热重载 支持配置文件热重载,动态修改端口转发服务。HTTP API 正在开发中。
使用指南
下载地址:https://github.com/rapiz1/rathole/releases
源码获取:https://github.com/rapiz1/rathole/blob/main/docs/build-guide.md
使用条件:
- rathole 必须要设置 token
- 使用 rathole 需要一个有公网 IP 的服务器作为服务端
- 客户端设计为一个在 NAT 或防火墙后的设备,其中有些服务需要暴露在互联网上
Linux常规方式部署
服务端部署
在有一个公网 IP 的服务器上创建配置文件 server.toml
# server.toml
[server]
bind_addr = "0.0.0.0:2333" # `2333` 配置了服务端监听客户端连接的端口
[server.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know" # 用于验证的 token
bind_addr = "0.0.0.0:5202" # `5202` 配置了将 `my_nas_ssh` 暴露给互联网的端口
运行服务:
./rathole server.toml
客户端部署
在 NAT 后面的主机(你的 NAS)上创建配置文件 client.toml
# client.toml
[client]
remote_addr = "myserver.com:2333" # 服务器的地址。端口必须与 `server.bind_addr` 中的端口相同。
[client.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know" # 必须与服务器相同以通过验证
local_addr = "127.0.0.1:22" # 需要被转发的服务的地址
运行服务:
./rathole client.toml
Systemd examples 中提供了一些让 rathole
在 Linux 上作为后台服务运行的配置示例。
现在 rathole
客户端会连接运行在 myserver.com:2333
的 rathole
服务器,任何到 myserver.com:5202
的流量将被转发到客户端所在主机的 22
端口。
所以你可以 ssh myserver.com:5202
来 ssh 到你的 NAS。
Docker部署
仓库1:rapiz1/rathole
- linux/x86_64
docker pull rapiz1/rathole
docker run -it --rm -v "./config.toml:/app/config.toml" rathole --server /app/config.toml
仓库2:archef2000/rathole
- x86_64 & ARM:
docker pull archef2000/rathole:latest
服务端docker-compose.yaml
rathole-server:
image: archef2000/rathole:latest
environment:
- "RUST_LOG=info"
- "ADDRESS=0.0.0.0:2333"
- "SERVICE_TOKEN_1=***token***"
- "SERVICE_NAME_1=service1"
- "SERVICE_ADDRESS_1=0.0.0.0:5202"
ports:
- 2333:2333
- 5202:5202
restart: unless-stopped
客户端docker-compose.yaml
rathole-client:
image: archef2000/rathole:latest
command: client
environment:
- "RUST_LOG=info"
- "ADDRESS=server-ip:2333"
- "SERVICE_TOKEN_1=***token***"
- "SERVICE_NAME_1=service1"
- "SERVICE_ADDRESS_1=10.10.10.10:5202"
restart: unless-stopped
现在 rathole
客户端会连接运行在 myserver.com:2333
的 rathole
服务器,任何到 myserver.com:5202
的流量将被转发到客户端所在主机的 22
端口。
所以你可以 ssh myserver.com:5202
来 ssh 到你的 NAS。
Configuration
-
推荐首先查看 examples 中的配置示例来快速理解配置格式
-
关于如何配置 Noise Protocol 和 TLS 来进行加密传输,参见 Transport。
-
单配置块场景:
- 若配置文件仅含 [server] 块 → 自动以服务器模式运行
- 若配置文件仅含 [client] 块 → 自动以客户端模式运行
-
多配置块场景(当配置文件同时存在 [server] 和 [client] 块时):
- 服务器端需指定参数启动:rathole --server config.toml
- 客户端需指定参数启动:rathole --client config.toml
完整的配置格式
[client]
remote_addr = "example.com:2333" # 必需项。服务器的地址
default_token = "default_token_if_not_specify" # 可选。服务的默认令牌,若服务未自行定义
heartbeat_timeout = 40 # 可选。设置为 0 可禁用应用层心跳测试。该值必须大于 `server.heartbeat_interval`。默认值:40 秒
retry_interval = 1 # 可选。重试连接服务器的间隔时间。默认值:1 秒
[client.transport] # 整个块为可选。指定要使用的传输方式
type = "tcp" # 可选。可能的值:["tcp", "tls", "noise"]。默认值:"tcp"
[client.transport.tcp] # 可选。也会影响 `noise` 和 `tls`
proxy = "socks5://user:passwd@127.0.0.1:1080" # 可选。用于连接服务器的代理。支持 `http` 和 `socks5`。
nodelay = true # 可选。为每个服务覆盖 `client.transport.nodelay`
keepalive_secs = 20 # 可选。若适用,指定 `tcp(7)` 中的 `tcp_keepalive_time`。默认值:20 秒
keepalive_interval = 8 # 可选。若适用,指定 `tcp(7)` 中的 `tcp_keepalive_intvl`。默认值:8 秒
[client.transport.tls] # 若 `type` 为 "tls" 则必需
trusted_root = "ca.pem" # 必需。签署服务器证书的 CA 证书
hostname = "example.com" # 可选。客户端用于验证证书的主机名。若未设置,则回退到 `client.remote_addr`
[client.transport.noise] # Noise 协议。详见 `docs/transport.md` 以获取更多解释
pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s" # 可选。默认值如所示
local_private_key = "key_encoded_in_base64" # 可选
remote_public_key = "key_encoded_in_base64" # 可选
[client.transport.websocket] # 若 `type` 为 "websocket" 则必需
tls = true # 若为 `true`,则会使用 `client.transport.tls` 中的设置
[client.services.service1] # 需要进行转发的服务。名称 `service1` 可任意更改,只要与服务器配置中的名称一致即可
type = "tcp" # 可选。需要转发的协议。可能的值:["tcp", "udp"]。默认值:"tcp"
token = "whatever" # 若未设置 `client.default_token` 则必需
local_addr = "127.0.0.1:1081" # 必需。需要转发的服务的地址
nodelay = true # 可选。确定是否在适用时为数据传输启用 TCP_NODELAY,以降低延迟但减少带宽。默认值:true
retry_interval = 1 # 可选。重试连接服务器的间隔时间。默认值:继承全局配置
[client.services.service2] # 可以定义多个服务
local_addr = "127.0.0.1:1082"
[server]
bind_addr = "0.0.0.0:2333" # 必需。服务器监听客户端的地址。通常只需更改端口。
default_token = "default_token_if_not_specify" # 可选
heartbeat_interval = 30 # 可选。两次应用层心跳之间的间隔时间。设置为 0 可禁用发送心跳。默认值:30 秒
[server.transport] # 与 `[client.transport]` 相同
type = "tcp"
[server.transport.tcp] # 与客户端相同
nodelay = true
keepalive_secs = 20
keepalive_interval = 8
[server.transport.tls] # 若 `type` 为 "tls" 则必需
pkcs12 = "identify.pfx" # 必需。服务器证书和私钥的 pkcs12 文件
pkcs12_password = "password" # 必需。pkcs12 文件的密码
[server.transport.noise] # 与 `[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] # 若 `type` 为 "websocket" 则必需
tls = true # 若为 `true`,则会使用 `server.transport.tls` 中的设置
[server.services.service1] # 服务名称必须与客户端一致
type = "tcp" # 可选。与客户端的 `[client.services.X.type]` 相同
token = "whatever" # 若未设置 `server.default_token` 则必需
bind_addr = "0.0.0.0:8081" # 必需。服务暴露的地址。通常只需更改端口。
nodelay = true # 可选。与客户端相同
[server.services.service2]
bind_addr = "0.0.0.1:8082"
Logging
rathole
,像许多其他 Rust 程序一样,使用环境变量来控制日志级别。
支持的 Logging Level 有 info
, warn
, error
, debug
, trace
比如将日志级别设置为 error
:
RUST_LOG=error ./rathole config.toml
如果 RUST_LOG
不存在,默认的日志级别是 info
。
Tuning
从 v0.4.7 开始, rathole 默认启用 TCP_NODELAY。这能够减少延迟并使交互式应用受益,比如 RDP,Minecraft 服务器。但它会减少一些带宽。
如果带宽更重要,比如网盘类应用,TCP_NODELAY 仍然可以通过配置 nodelay = false
关闭。