拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RustDesk自建中继服务器:从零搭建稳定远程控制方案

RustDesk自建中继服务器:从零搭建稳定远程控制方案

这两年我陆续给身边的同事朋友搭了不少远程控制方案,从商业软件到开源工具都折腾过一圈。最后自己日常在用的,反而是一套看起来最不起眼的组合:RustDesk 加上一台便宜的公网云服务器,自建中继节点,稳定远程控制家里的内网机器。这篇文章就把完整过程写清楚,从为什么不用官方公共服务器,到服务端 hbbs/hbbr 怎么部署,再到客户端怎么填 ID、中继地址和 Key,最后是怎么验证公网远控链路、排查高频故障。如果你也想让家里或办公室的内网机器变成随时随地可访问的资源,这篇可以直接照着执行。

1. 为什么官方公共服务器不能直接满足远控需求

1.1 官方公共服务器到底慢在哪

RustDesk 默认连接官方公共服务器,开箱即用,什么都不用配。但实际用一段时间就会发现,白天高峰期连接质量飘忽不定,画面延迟忽高忽低,设备在线状态偶尔还会刷不出来。原因并不神秘:你的数据需要先绕到公共节点,再从那里转回受控端,中间每一跳都会放大延迟。远程桌面是实时交互流量,哪怕只多出 100ms 延迟,拖动窗口时的体感都会差很多。

把这些问题按影响程度排个序,大概是:中继路径过长导致延迟高,公共节点高峰拥塞导致画面卡顿,ID 注册信息过于依赖第三方节点导致不可控。我不想完全否定官方公共服务器,作为初次体验它完全合格;但当你需要天天用、时时用,并且希望每次连接的路径都由自己把控时,官方节点就远远不够了。

1.2 自建中继后,控制端、中继端、受控端三者怎么配合

自建之后的完整链路是:控制端设备(手机、笔记本)发起连接请求,通过你设置的 ID 服务器找到受控端 ID 对应的当前网络信息,然后尝试 P2P 直连;如果直连失败或者双方 NAT 类型不允许,就自动走自己的中继服务器转发。

这里最核心的一句话是:受控端主动外连中继服务器,所以家里内网机器不需要公网 IP,也不需要路由器端口映射。很多朋友一开始纠结“我家没有公网 IP 是不是搞不了”,答案是能搞。因为主动发起外连的是受控端自己,不是公网来连它。正因为这个特性,自建 RustDesk 中继解决的不只是“能连”,而是“稳定、可控地连”:受控端只要能在断电重启后重新连上服务器,你在世界上任何有网络的地方打开客户端就能找到它。这比 frp、ngrok 暴露具体端口的方式更贴合普通人的远程桌面需求——我不是要暴露某个服务,我是要那台电脑的完整画面。

1.3 这套方案适合什么样的使用者

从我的实际接触来看,这套组合最匹配三类人。第一类:家里有一台 Windows 台式机常年开机,想在办公室、地铁上随时访问它,拷贝文件或操作软件。第二类:手上散落着几台 Linux 主机或树莓派,想用一个客户端统一管理远程桌面和文件传输。第三类:对商业远程软件收费规则不满意的个人用户,想要免费、跨平台、数据自持的方案。

当然它也有不适合的场景。如果你需要支撑二十路以上的高画质并发远程会话,单机部署的中继带宽和 CPU 会吃不消,那是商业架构该考虑的事。但个人和家庭团队场景,一台 2核4G、带宽 5Mbps 的服务器已经非常宽裕。后面的配置都按这个体量来讲,不会上来就让你搞高可用集群。

2. hbbs与hbbr服务端组件拆解:谁负责登录,谁负责中转

2.1 两个进程你看重谁,决定了排错方向

RustDesk 服务端不是单个二进制,而是 hbbs 和 hbbr 两个程序协同工作。我见过不少人在服务端只启动了 hbbs,结果怎么都连不上,就是漏了 hbbr。这两个进程的差别用一句话说清楚:hbbs 负责“找到对方”,hbbr 负责“把数据送过去”。

hbbs 是 ID/会合服务器。每台设备启动客户端后,会主动向 hbbs 注册自己的 ID、IP、端口和 NAT 类型。控制端发起连接时,也是向 hbbs 询问“目标 ID 现在在哪”。它更像电话簿加接线员的合体,消息量不大,但对实时性敏感。hbbr 是中继服务器,当两台设备无法建立 P2P 直连时,所有远程桌面的画面、键盘鼠标事件、剪贴板内容都从它这里转发。它承载的是全部业务流量,是真正的带宽消耗大户。

理解了这点,排错方向就清晰了:客户端连不上、设备不在线,优先查 hbbs;能连上但画面黑屏、一直转圈,优先查 hbbr 和中继端口 21117。看日志也是这样,hbbs 的日志主要记录注册心跳,hbbr 的日志记录的是实际转发会话。后面故障排查章节我会再展开。

2.2 一张表看懂端口和协议

服务端需要放行的端口有一个固定清单,我直接列出来,并附上漏配端口时最常见的表现:

端口协议作用漏配的后果
21115TCPNAT 类型探测连接建立变慢,部分网络环境无法完成打洞
21116TCP心跳与注册的备用通道设备偶尔失联
21116UDP心跳与注册的主要通道设备状态无法上报,列表里找不到机器
21117TCP中继服务器数据转发能看到设备在线,但画面一直建立不起来
21118TCPWeb 客户端连接浏览器远程桌面用不了
21119TCPWeb 客户端中继浏览器远程桌面中继时用不了

第一次搭的人最容易踩的坑是只放 TCP 不放 UDP。21116 的 UDP 是客户端向 hbbs 报心跳的主要通道,UDP 没通,设备注册信息就送不过去,表现为客户端一直看不到设备在线。另一个坑是只放 ID 端口却忘了中继端口:设备列表能看到受控端在线,但点击连接之后画面一直出不来,因为 21117 被挡了。

2.3 为什么要把“登记”和“转发”拆成两个独立服务

这不是 RustDesk 为了凑进程数才拆的,而是基于负载特性做的合理设计。hbbs 虽然每秒要处理大量注册心跳请求,但每个包很小,占用不了多少带宽;hbbr 则完全不同,它要搬运一帧一帧的画面数据,带宽消耗比 hbbs 高一个数量级。拆开之后,你可以把 hbbs 留在低配机器上,把 hbbr 单独部署到带宽充足、地理位置更合适的节点,扩容时不用整体搬迁。

对个人用户来说,在一台云服务器上同时跑两个进程是默认做法,因为流量不大、逻辑也简单。但理解这个拆分逻辑能帮你避免一个误区:中继慢的时候跑去加 CPU,其实该加的是带宽;中继延迟高的时候换机房,其实要先评估受控端到机房这段链路的距离。问题定位错了,钱就白花了。

3. 服务器端一步步部署:从二进制到systemd守护

3.1 选一台什么样的服务器

先给配置建议。如果只服务个人设备和少量朋友,2核4G 的规格绰绰有余,1核1G 也能跑,但处理高分辨率画面时 CPU 会飙高。带宽反而更重要,强烈建议至少 5Mbps 起步。远程桌面在 1080P 画质下,中继码率通常在 2-8Mbps 之间波动,5Mbps 能保证日常操作流畅,但播放视频类画面会比较吃力;10Mbps 基本能覆盖绝大多数个人场景。云厂商的带宽是按月付费的,可以先买小,真正不够时再临时升。

系统方面推荐 Ubuntu 22.04 LTS 或 Debian 12,包管理干净,systemd 现成,新机器默认就是这些系统,省去折腾。CentOS 7 虽然还在服役但已停止维护,新部署不建议再上。如果选了 ARM 架构服务器,下载对应的 aarch64 版本即可,后面命令完全一样。

3.2 二进制部署的完整命令

登录服务器,先安装解压工具和下载工具:

apt update && apt install -y unzip wget

下载 rustdesk-server 的最新 Linux release。版本号以你实际下载到的为准:

cd /opt wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.11-2/rustdesk-server-linux-amd64.zip unzip rustdesk-server-linux-amd64.zip

解压后进入目录,先手动启动一次 hbbs:

cd /opt/rustdesk-server-linux-amd64 chmod +x hbbs hbbr ./hbbs -r 你的服务器公网IP:21117

第一次启动会在当前目录生成 data 文件夹,里面是id_ed25519(私钥)和id_ed25519.pub(公钥)。公钥内容就是后续客户端要填的 Key,私钥一定要保管好。看到类似 “Waiting for connection” 的日志输出,说明 hbbs 起来了。按 Ctrl+C 停掉,再执行:

./hbbr -p 21117

确认 hbbr 也能正常启动。这一步只是验证进程能跑,真正长期运行要交给 systemd。

如果你更喜欢容器化方式,可以直接用官方镜像。用 Docker Compose 编排,注意 hbbs 和 hbbr 要共享同一个 data 目录:

services: hbbs: image: rustdesk/rustdesk-server:latest command: hbbs -r 你的服务器公网IP:21117 volumes: - ./data:/data ports: - 21115:21115 - 21116:21116 - 21116:21116/udp restart: always hbbr: image: rustdesk/rustdesk-server:latest command: hbbr -p 21117 volumes: - ./data:/data ports: - 21117:21117 restart: always

容器方式下 data 目录必须让两个容器共享,不然 hbbs 生成的密钥 hbbr 看不到,中继会不正常。个人使用我还是更推荐直接跑二进制,少一层容器,排查问题更直观。

如果你在服务器上直接下载 GitHub release 不稳定,不用死磕,在本地电脑下载好压缩包,再用 scp 传上去:

scp rustdesk-server-linux-amd64.zip root@你的服务器IP:/opt/

只是多一步,下载这件事会可控很多。

3.3 用 systemd 把这俩服务固定住

用 nohup 或直接在当前终端跑进程,SSH 会话一断进程就没了。所以必须注册成系统服务。创建两个 unit 文件,路径和用户名按自己实际环境调整。

/etc/systemd/system/rustdesk-hbbs.service:

[Unit] Description=RustDesk ID Server (hbbs) After=network.target [Service] Type=simple WorkingDirectory=/opt/rustdesk-server-linux-amd64 ExecStart=/opt/rustdesk-server-linux-amd64/hbbs -r 你的服务器公网IP:21117 Restart=always RestartSec=3 [Install] WantedBy=multi-user.target

/etc/systemd/system/rustdesk-hbbr.service:

[Unit] Description=RustDesk Relay Server (hbbr) After=network.target [Service] Type=simple WorkingDirectory=/opt/rustdesk-server-linux-amd64 ExecStart=/opt/rustdesk-server-linux-amd64/hbbr -p 21117 Restart=always RestartSec=3 [Install] WantedBy=multi-user.target

然后一次性启用并启动:

systemctl daemon-reload systemctl enable --now rustdesk-hbbs rustdesk-hbbr systemctl status rustdesk-hbbs rustdesk-hbbr

如果提示找不到服务,检查文件是否放到了/etc/systemd/system/下,文件名后缀是不是.service。Restart=always保证进程崩溃后 3 秒自动拉起,这对远程服务几乎是必备配置。查看运行日志用:

journalctl -u rustdesk-hbbs -f journalctl -u rustdesk-hbbr -f

日志里能看到客户端心跳和连接请求,后面排查问题全靠它们。

3.4 防火墙放行和监听验证

云服务器默认 ufw 多数是关闭的,但保险起见还是显式放行。Ubuntu 上执行:

ufw allow 21115/tcp ufw allow 21116/tcp ufw allow 21116/udp ufw allow 21117/tcp ufw allow 21118/tcp ufw allow 21119/tcp ufw reload

CentOS 上对应:

firewall-cmd --permanent --add-port=21115/tcp firewall-cmd --permanent --add-port=21116/tcp firewall-cmd --permanent --add-port=21116/udp firewall-cmd --permanent --add-port=21117/tcp firewall-cmd --permanent --add-port=21118/tcp firewall-cmd --permanent --add-port=21119/tcp firewall-cmd --reload

但真正卡住大多数人的不是系统防火墙,而是云厂商控制台的安全组。安全组和系统防火墙是两套独立体系,很多云服务器的安全组默认只放行了 22、3389 等少数端口,必须手动加规则。建议的规则如下:

方向协议端口源
入方向TCP21115-211190.0.0.0/0
入方向UDP211160.0.0.0/0

不要为了省事把安全组全部端口放行,端口范围越小越安全。配置完之后用ss验证:

ss -lntup | grep -E '2111[5-9]'

能看到 21115、21116(TCP/UDP)、21117 的监听状态,服务端部署就算完成了。

3.5 顺手备份密钥文件

部署完先别急着配客户端,我建议你立刻把 data 目录备份好。这个目录里的id_ed25519是服务器的“身份证”,丢失或重装机器后,以前填过旧 Key 的所有客户端都要重新配置。

cp -a /opt/rustdesk-server-linux-amd64/data /opt/rustdesk-server-backup-data

我更倾向于把备份文件下载到本地再存一份,因为服务器磁盘故障时,备份在同一台机器上等于没备份。这个习惯后面帮我省了很多麻烦。

4. 客户端接入内网机器的关键配置与Key校验

4.1 配置入口:控制端和受控端都要填

打开 RustDesk 客户端,找到“设置 > 网络 > ID/中继服务器”。Windows 版的入口在左上角菜单里,Android 在侧边栏,Linux 同样在设置里。需要填三个字段:ID 服务器、中继服务器、Key。

ID 服务器填服务器公网 IP,比如123.123.123.123;中继服务器填123.123.123.123:21117,注意这里带端口;Key 填上一步生成的id_ed25519.pub文件内容。填完点确定,然后完全退出客户端再重新打开,配置才会生效。这一步我也踩过坑:填完直接发起连接,连了几次都连不上,重启客户端后才正常。所以“保存后重启客户端”不是玄学,是让新配置重新加载的必要动作。

4.2 Key 校验的工作原理

填 Key 时很多人会觉得奇怪,为什么既有 ID 服务器地址又要一个 Key。因为 RustDesk 的通信是端到端加密的,客户端第一次连接服务器时,需要确认正在通信的确实是那台服务器,而不是被中间人冒名顶替。Key 本质上是服务器公钥的文本形式,客户端拿到之后,在密钥协商阶段就能完成身份确认。

实际使用中,如果 Key 填错,时不时的不会立刻弹错误框,而是连接建立后停在等待状态,或者几次握手失败后提示“连接错误”。我的建议是配置完成后,立刻发起一次测试连接,确认能正常出画面,再把这台设备纳入日常使用。真等到下班路上需要远程时才发现连不上,那体验太折磨了。

4.3 受控端配置:固定ID、无人值守、允许远程访问

对家里那台内网机器,需要做三件事。第一,在“设置 > 安全”里设置一个无人值守密码,并勾选允许远程访问,这样你从外面连上来时,不需要有人在电脑前点“接受”。第二,确认 Windows 客户端“锁屏后连接”选项是打开状态,不然电脑锁屏后连接容易失败。第三,记录这台机器的本机 ID。

客户端每次启动生成一个随机 ID,重装客户端会换新 ID;如果地址簿存在本机,ID 变了旧记录就失效。长期使用的人,要尽量避免在受控端频繁重装客户端,同时可以把设备名称改成“家里主力机”这类好认的名字。ID 是改不了的,但名称随便改。

4.4 多台设备如何统一管理

自建的另一个好处是地址簿完全在自己手里。控制端添加设备后,下次打开客户端就能看到列表,不用每次手动输入长 ID。而且只要所有设备指向同一个 ID 服务器,它们就自动出现在同一个列表里。

我现在家里挂了四台设备:Windows 主力机、书房 Linux 小主机、老 MacBook、一台装了 Android 的旧平板。手机端登录同一套 ID 服务器后,四台机器都在列表里,点一下就连接。配置方法完全一致,没有额外学习成本。这套模式对设备多的家庭特别实用。

5. 公网远控链路验证:从手机端发起到中继转发

5.1 用移动网络做一次真实外网测试

服务端、客户端都配好后,最关键的验证环节来了。把手机关掉 Wi-Fi,只保留移动网络,打开 RustDesk,点击家里那台电脑的 ID 发起连接。这一步的意义在于:手机处于真正的移动网络环境,和受控端不在同一局域网,链路必须经过服务器协调才能建立,这是最能反映真实使用效果的测试。

连接成功后,快速拖动鼠标在桌面上转几圈,观察画面是否跟手。如果流畅、无滞感,说明链路是通的。此时打开客户端的连接详情,你会看到两种状态:直连或中继。直连说明两端完成了 P2P 打洞,数据没经过服务器;中继说明路径是手机到云服务器再到家里电脑。两种都算成功,但知道是哪一种能帮你判断后续优化方向。

5.2 中继路径下的延迟观察和带宽消耗

中继模式下,数据相当于在“控制端到服务器”和“服务器到受控端”两条链路上各走一趟。假设家里宽带上行 30Mbps,手机流量下行 100Mbps,中间服务器带宽只有 5Mbps,那么最终瓶颈就是那 5Mbps,而不是你的宽带或手机。这也是为什么我反复强调中继服务器带宽的重要性。

可以用客户端底部的实时状态确认当前码率。远程桌面静止时码率会掉到几百 kbps,快速移动窗口时会瞬间冲到几 Mbps。如果服务器带宽不够,画面会自动降低清晰度,呈现出一块块模糊的马赛克。遇到这种情况,优先去控制端手动把画质模式调低一档,而不是盲目加服务器配置。码率这个数值建议你测试时盯一下,它会告诉你真实需要多大带宽。

5.3 直连和中继的切换逻辑

RustDesk 连接建立顺序是先尝试 UDP 打洞,打洞成功就直连,失败则自动走中继。判断打洞能否成功,主要看两端 NAT 类型。家庭宽带常见的对称型 NAT 最难打通,运营商大内网环境下直连成功率也偏低。所以不用纠结“为什么我有时直连有时中继”,这是网络类型决定的,不是配置出问题。

只要中继质量和带宽足够,中继模式体验可以做到接近直连。我自己在手机上远程操作公司电脑时,大多数时候走中继,用来改文档、传文件完全没问题;只有需要播放视频或做设计类操作时,才感觉到那一点延迟。想提升中继体验,最有效的手段是把云服务器放到离受控端物理距离更近的机房,而不是一味买更高配置。

6. 高频故障排查与中继网络优化

6.1 端口不通的排查顺序

连接失败先别急着改配置,按顺序验证端口。在自己电脑上用 PowerShell 执行:

Test-NetConnection 123.123.123.123 -Port 21117

如果返回TcpTestSucceeded : False,说明 21117 到不了服务器。此时登录服务器执行:

ss -lntup | grep 21117

如果本地监听正常但外部不通,问题基本在安全组或系统防火墙。逐个检查:云控制台安全组是否放行;服务器上 ufw/firewalld 状态;如果有物理路由或额外防护设备,也要看对应策略。端口问题的概率排序大致是:云安全组漏配 > 系统防火墙未放行 > 服务进程未启动 > 运营商限制。按这个顺序查,五分钟内基本能定位。

6.2 客户端反复超时的排查链路

“设备在线,但连接一直转圈”这种症状,根因往往不在端口,而在 Key 或中继地址配置上。按这个链路排查:先确认 Key 和服务器生成的公钥完全一致,复制时不要带入换行和多余空格;再确认中继服务器地址写的是公网 IP 且带着 21117 端口,不是内网地址;然后确认客户端填写后重启过;最后看 hbbs 日志有没有收到该设备的心跳,hbbr 日志有没有建立转发会话。

我帮朋友排查时遇到过一个典型情况:他把 ID 服务器和中继服务器都填成了服务器的内网地址,局域网内测试一切正常,一到外网就连不上。这种错误很隐蔽,因为内网 IP 在局域网内可达,公网却根本不知道这个内网地址是哪台机器。遇到外网连不上、内网却正常的情况,第一反应就应该是看 IP 是不是公网 IP。

6.3 会话建立后卡顿、模糊的处理思路

远程桌面卡顿,要区分“网络瓶颈”还是“编码瓶颈”。网络瓶颈的表现是所有操作延迟都很高、画面持续模糊;编码瓶颈的表现是电脑 CPU 占用爆高、本地操作本身都变慢。前者去调整网络设置和带宽,后者去客户端设置里开启硬件编码、适当降低分辨率。

我自己常用的画质参考值:日常办公 1280x720、帧率 15、码率选平衡;远程写代码或改设计稿,1920x1080、帧率 20、高画质;外出用手机控制时,宁可降低分辨率也要保证帧率,否则鼠标光标移动都是跳的。这些设置都在客户端“显示”设置里,改完即时生效,不需要断开重连,可以边操作边微调,直到手感和画质达到平衡。

6.4 安全加固清单和我踩过的坑

自建服务必然暴露在公网,几个安全点必须做到。第一,防火墙只放行必要端口,不要学某些教程把 1-65535 全开。第二,坚持使用 Key 校验,不要在 hbbs 启动参数里加-k _禁用认证。第三,给操作系统设置强密码,SSH 使用密钥登录并关闭密码登录,远程桌面的无人值守密码也要足够复杂。第四,定期更新 RustDesk 服务端和客户端版本,它更新频率不低,很多连接兼容性问题都是靠升级解决的。

最后分享一个我真实踩过的大坑。某次云服务器数据盘故障恢复后,我重新下载解压了 rustdesk-server,但因为没备份 data 目录,hbbs 重新生成了一对新密钥,结果所有客户端原有的 Key 全部失效,家里几台机器只能在现场一台台重填配置。那次之后,我把data目录下载到本地并加了定时备份,再没犯过同样的错。如果你也准备长期跑这套方案,部署完的下一步不是急着连设备,而是先做一次密钥备份。这十几秒的操作,真的能省掉后面一整天的返工。

返回列表