LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

rathole:一款高性能内网穿透工具

admin
2025年8月27日 1:39 本文热度 6

安全、稳定、高性能的内网穿透工具,用 Rust 语言编写

rathole,类似于 frp 和 ngrok,可以让 NAT 后的设备上的服务通过具有公网 IP 的服务器暴露在公网上。

项目地址:https://github.com/rathole-org/rathole

程序下载:https://github.com/rathole-org/rathole/releases

Features

  • 高性能具有更高的吞吐量,高并发下更稳定。见Benchmark

  • 低资源消耗内存占用远低于同类工具。见Benchmark二进制文件最小可以到~500KiB,可以部署在嵌入式设备如路由器上。

  • 安全性每个服务单独强制鉴权。Server 和 Client 负责各自的配置。使用 Noise Protocol 可以简单地配置传输加密,而不需要自签证书。同时也支持 TLS。

  • 热重载支持配置文件热重载,动态修改端口转发服务。HTTP API 正在开发中。

Quickstart

一个全功能的rathole可以从release页面下载。或者从源码编译获取其他平台和最小化的二进制文件

rathole的使用和 frp 非常类似,如果你有后者的使用经验,那配置对你来说非常简单,区别只是转发服务的配置分离到了服务端和客户端,并且必须要设置 token。

使用 rathole 需要一个有公网 IP 的服务器,和一个在 NAT 或防火墙后的设备,其中有些服务需要暴露在互联网上。

假设你在家里的 NAT 后面有一个 NAS,并且想把它的 ssh 服务暴露在公网上:

  1. 在有一个公网 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
  1. 在 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
  1. 现在rathole客户端会连接运行在myserver.com:2333rathole服务器,任何到myserver.com:5202的流量将被转发到客户端所在主机的22端口。

所以你可以ssh myserver.com:5202来 ssh 到你的 NAS。

Systemd examples中提供了一些让rathole在 Linux 上作为后台服务运行的配置示例。

Configuration

如果只有一个[server][client]块存在的话,rathole可以根据配置文件的内容自动决定在服务器模式或客户端模式下运行,就像Quickstart中的例子。

[client][server]块也可以放在一个文件中。然后在服务器端,运行rathole --server config.toml。在客户端,运行rathole --client config.toml来明确告诉rathole运行模式。

推荐首先查看examples中的配置示例来快速理解配置格式,如果有不清楚的地方再查阅完整配置格式。

关于如何配置 Noise Protocol 和 TLS 来进行加密传输,参见Transport

下面是完整的配置格式。

[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:passwd@127.0.0.1:1080" # Optional. The proxy used to connect to the server. `http` and `socks5` is supported.

nodelay = true # Optional. Override the `client.transport.nodelay` per service

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. Determine whether to enable TCP_NODELAY for data transmission, if applicable, to improve the latency but decrease the bandwidth. Default: true

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"

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关闭。

Benchmark

rathole 的延迟与frp相近,在高并发情况下表现更好,能提供更大的带宽,内存占用更少。

关于测试进行的更多细节,参见单独页面Benchmark

但是,不要从这里得出结论,rathole能让内网转发出来的服务快上数倍。Benchmark 是在本地回环上进行的,其结果说明了任务受 CPU 限制时的结果。当用户的网络不是瓶颈时,用户能得到很大的提升。但是,对很多用户来说并不是这样。在这种情况下,rathole能带来的主要好处是更少的资源占用,而带宽和延迟不一定有显著的改善。

Development Status

rathole正在积极开发中

  • 支持 TLS
  • 支持 UDP
  • 热重载
  • 用于配置的 HTTP APIs

Out of Scope 列举了没有计划开发的特性并说明了原因。


阅读原文:原文链接


该文章在 2025/8/28 15:06:01 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved