说实话,很多人一开始对“自建中继”这件事是持怀疑态度的:RustDesk 官方不是免费提供公共服务器吗,何必自己买台云主机折腾?但等你真正把家里、办公室那几台没有公网 IP 的内网机器纳入远控范围,并且频繁遇到官方节点连接抖动、高峰期排队、加密密钥不受自己控制这些问题之后,就会明白“RustDesk 搭建公网中继服务器”的价值所在。这篇文章不会只给你贴一段 docker run 命令,而是把 hbbs、hbbr 各自做什么、端口为什么要开这么多、客户端三个配置项到底在配什么、以及部署后如何检查链路是否真的走通,完整地讲清楚。内容偏实操,适合已经用过一阵子 RustDesk、想彻底摆脱官方节点限制的人。
1. 为什么绕不开自建中继:公共服务器和自建节点的真实差异
先别急着敲命令,我们得先对齐一个认知:RustDesk 远控内网机器,本质上是在两台没有公网 IP 的设备之间建立一条“间接通路”。这条通路的核心角色,就是公网上的服务器。官方服务器虽然方便,但用久了你会明显感觉到几个问题。
1.1 官方中继节点的体验瓶颈
RustDesk 官方在全球部署了一批 ID 服务器和中继服务器,国内访问时延迟和稳定性并不总是理想。某些运营商网络环境下,连接可能会频繁超时,尤其是跨网、跨地区的时候。你可能遇到过这种情况:远控窗口好不容易弹出来,画面操作起来却像幻灯片,键盘输入延迟能到两秒以上——这通常是流量走了延迟很高的官方中继节点,而不是你的设备之间点对点直连。
还有一些场景下,团队或公司内部对数据流向比较敏感,不想让远控会话的认证信息、剪贴板内容、文件传输数据经过第三方服务器。自建中继后,信令和转发链路完全由自己掌控,至少从链路层面上不再依赖外部公共资源。
1.2 自建中继解决了哪几类问题
我把实际使用中的收益整理成了一张对比表,方便你对号入座:
| 对比维度 | 官方公共服务器 | 自建公网中继服务器 |
|---|---|---|
| 初始成本 | 免费 | 需要一台轻量云主机,约几十元/月 |
| 访问延迟 | 受官方节点分布影响,高峰期不稳定 | 可选择与客户端就近的机房,延迟可控 |
| 数据链路 | 信令和部分中继流量经过官方节点 | 全部经过自己的服务器 |
| 密钥体系 | 使用 RustDesk 官方配置 | 使用自生成 ed25519 密钥对,可控性更强 |
| 端口开放 | 无需设置 | 需要在云安全组放行 21115-21119 |
| 适用规模 | 个人临时使用 | 个人主力远控、团队办公、企业内部支持 |
那是不是所有场景都值得自建?如果你的设备全在一个局域网里,或者只是临时远程一两次,直接用官方服务器和随机密码就够了。但如果你需要长期、高频地访问分布在不同网络内的机器,并且想固定设备 ID、统一管理密钥、让每次远控的链路质量都可预期,那花一两个小时搭一台中继服务器非常值得。毕竟 RustDesk 服务端本身对硬件的要求极低,1 核 1G 内存的小鸡就能稳稳跑起来。
1.3 一个影响体验的关键认知:P2P 打洞和中继不是二选一
很多教程会把中继服务器称为“兜底方案”,这容易让人误以为只要自建了服务器,所有流量就都会经过它。实际不是这样。RustDesk 的链接策略是:先通过 hbbs 交换双方的网络地址信息,尝试在控制端和被控端之间建立点对点(P2P)连接。如果双方的 NAT 类型允许、UDP 通道能打通,那么画面和操作数据直接互传,完全不占用中继服务器的带宽。只有当打洞失败,例如有一方处在严格的对称型 NAT 后面,才会自动降级走 hbbr 中继转发。
这个机制意味着,自建中继服务器的带宽规格并不需要太大。哪怕你的设备都在不同内网,大多数情况下打洞都能成功,中继服务器只是“保底”。但前提是 hbbs 这个“介绍人”必须在公网上稳定在线,否则双方连互相发现都做不到。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 拆开看服务端:hbbs 与 hbbr 的分工及端口背后的逻辑
接触 RustDesk 服务端时,你会看到两个高频名词:hbbs 和 hbbr。它们不是两个独立软件,而是同一个 rustdesk-server 包里的两个进程。我第一次部署时也搞混过,这里用最直白的话拆开讲。
2.1 hbbs 是“登记处”,hbbr 是“中转仓库”
hbbs 全称是 RustDesk ID/Relay Server 中的 ID Server 部分,负责维护哪些设备在线、设备 ID 与其当前网络地址的对应关系。客户端启动后会定时向 hbbs 上报自己的 ID 和地址,就像去酒店前台登记入住信息。控制端发起远控时,会先问 hbbs:“这个 ID 对应的设备现在在哪?”hbbs 查到后把地址信息返回给控制端,双方尝试直接连线。
hbbr 则是真正的中继转发进程。当两台设备无法直接互通时,控制端和被控端都会主动连到 hbbr,由 hbbr 把一边收到的画面数据、控制指令转发给另一边。你可以把 hbbr 想象成一个快递中转站,货不直接送到收件人手里,先集中到中转站再分发。
明白了这一层,你就知道单台服务器部署时为什么建议同时跑这两个进程:hbbs 解决“找到对方”的问题,hbbr 解决“找不到对方时怎么传数据”的问题。缺了 hbbs,客户端无法完成 ID 注册;缺了 hbbr,所有打洞失败的场景都会直接断连。
2.2 端口清单:21115 到 21119 各管一段
RustDesk 服务端默认使用的端口是连续的 21115-21119,很多部署失败案例都是因为只放行了 21116 和 21117,忽略了其余的。我把每个端口的作用列出来:
| 端口 | 所属进程 | 协议 | 用途 | 是否必须公网开放 |
|---|---|---|---|---|
| 21115 | hbbs | TCP | NAT 类型测试 | 建议开放 |
| 21116 | hbbs | TCP + UDP | ID 注册、心跳、UDP 打洞协调 | 必须开放,TCP 和 UDP 都不能漏 |
| 21117 | hbbr | TCP | 数据中继转发通道 | 必须开放 |
| 21118 | hbbs | TCP | 网页版客户端信令 | 不需要网页远控可不开放 |
| 21119 | hbbr | TCP | 网页版中继转发 | 不需要网页远控可不开放 |
很多人会把 21116 的 UDP 漏掉。RustDesk 的打洞协调依赖 UDP 21116,如果你只在云控制台里开了 TCP 规则,客户端会显示“就绪”,但两台内网设备的 P2P 通道始终建不起来,最终远控要么失败,要么频繁卡顿。这是我踩过最实在的坑,所以后面配置安全组时会专门强调。
2.3 一台服务器,两个进程,需要什么样的资源和系统环境
服务端进程是用 Rust 写的,资源占用非常克制。实测一台 1 核 CPU、1G 内存的 Linux VPS,同时跑 hbbs 和 hbbr,常驻内存占用通常在 200M 以内。真正需要关注的是带宽和系统版本:服务器操作系统建议选 Ubuntu 22.04 LTS 或 Debian 12,内核较新,对 Docker 和 UDP 转发支持都更省心。
如果只是个人使用,地域上优先选择离你常用网络环境较近的机房,可以减少信令交互的 RTT;如果你还要给公司同事用,中继带宽建议选 3Mbps 以上的峰值带宽,否则一旦多人同时降级到中继,画面会明显发糊。
3. 部署前要确定的四件事:IP、域名、防火墙和存储位置
我见过不少部署到一半卡住的人,问题往往不在安装命令本身,而是前期的网络规划没做好。这里把服务端部署前必须敲定的选项一一列出来。
3.1 用 IP 还是域名
客户端配置时,ID 服务器一栏既可以填 IP,也可以填域名。域名带来的好处是:以后服务器迁移、换 IP 时,不用重新配置每一台客户端,只要把域名解析指向新地址即可。但域名需要提前做好 A 记录解析,并且确认 DNS 没有被防火墙干扰。
如果你只是自己用,不打算频繁迁移,直接填公网 IP 最省事。需要注意,国内机房默认可能不开放 80/443 之外的端口,购买 VPS 后务必在服务商的安全组控制台确认 21115-21119 已加入白名单。
3.2 hbbs 和 hbbr 放在同一台还是分开部署
默认情况下,hbbs 和 hbbr 放在同一台机器上就够了,这也是后面 Docker Compose 方案的基础。只有到了中继带宽成为瓶颈、需要单独扩容的时候,才考虑把 hbbr 拆到另一台更高带宽的服务器上。拆分时,hbbs 启动参数里要通过 -r 指定 hbbr 的公网地址,让客户端能拿到正确的中继服务器地址;否则客户端仍然会尝试连 hbbs 所在机器的 21117 端口。
3.3 数据存储目录和密钥文件的保留
服务端运行时会生成两把钥匙:id_ed25519 私钥和 id_ed25519.pub 公钥。公钥就是客户端配置页面里要填的 Key。部署前先想好数据目录放在哪里,比如 /opt/rustdesk/data,并把整个目录纳入备份。如果哪一天服务器重装,但你没有保存这份密钥,所有客户端都需要重新配置才能连上。
3.4 云安全组与 Linux 系统防火墙的关系
国内主流云厂商的安全组默认是“白名单+黑名单”模式,你需要在安全组入方向放行 TCP 21115、TCP/UDP 21116、TCP 21117。如果你又额外开了 ufw 或 firewalld,记得系统防火墙里也要同步放行,否则安全组开了也白搭。
个人最稳妥的操作顺序是:先在云控制台把安全组规则加好,再在服务器上执行 ufw allow 21115/tcp && ufw allow 21116/tcp && ufw allow 21116/udp && ufw allow 21117/tcp,然后用 ufw status 确认规则生效。
4. 服务端部署实操:从 Docker 到离线导入的完整落地方案
现在进入正题。我会提供三种可行的部署方式,推荐优先使用 Docker Compose,因为后续升级、回滚都方便;再额外介绍如何把 Docker 镜像离线打包,方便你在一台没有外网的内网服务器上部署。
4.1 在线快速部署:Docker Compose 方式
先确认服务器已经安装 Docker 和 Docker Compose 插件:
bash复制sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo systemctl enable --now docker
然后建立一个独立的部署目录:
bash复制sudo mkdir -p /opt/rustdesk
cd /opt/rustdesk
sudo mkdir -p data
创建 docker-compose.yml 文件,我这里以公网 IP 假设为 你的公网IP,注意替换:
yaml复制services:
hbbs:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbs
restart: unless-stopped
command: hbbs -r 你的公网IP:21117
volumes:
- /opt/rustdesk/data:/data
ports:
- "21115:21115"
- "21116:21116"
- "21116:21116/udp"
- "21118:21118"
hbbr:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbr
restart: unless-stopped
command: hbbr
volumes:
- /opt/rustdesk/data:/data
ports:
- "21117:21117"
- "21119:21119"
这里解释两个我在实际部署中觉得容易忽略的细节:
- hbbs 的启动命令里必须带
-r 你的公网IP:21117。它的作用是告诉 hbbs:“当你把中继服务器地址分发给客户端时,要宣告这个地址”。如果不带这个参数,客户端虽然能连上 hbbs 完成 ID 注册,但打洞失败后不知道去哪里找 hbbr。如果你用的是域名,就把你的公网IP换成域名,例如-r relay.example.com:21117。 - 两个容器共享同一个
/opt/rustdesk/data数据卷,因为 hbbs 生成的密钥文件要能被两个进程访问,后续客户端配置用的公钥也在该目录下。
启动服务并查看状态:
bash复制sudo docker compose up -d
sudo docker compose ps
看到 rustdesk-hbbs 和 rustdesk-hbbr 都处于 healthy 状态后,查看生成的公钥:
bash复制sudo cat /opt/rustdesk/data/id_ed25519.pub
输出一串类似 xxxxxx... 的字符串,复制并保存好,它就是客户端要填写的 Key。
4.2 用进程管理方式部署:适合不想用 Docker 的服务器
有些服务器环境比较特殊,比如不允许运行 Docker,那么可以直接下载 rustdesk-server 的二进制文件,用 systemd 管理进程。
从 GitHub 的 rustdesk-server releases 页面下载对应的 Linux x86_64 压缩包,解压后把 hbbs 和 hbbr 放到 /opt/rustdesk/ 目录下:
bash复制cd /tmp
wget https://github.com/rustdesk/rustdesk-server/releases/download/1.1.12/rustdesk-server-linux-amd64.zip
unzip rustdesk-server-linux-amd64.zip
sudo cp rustdesk-server-linux-amd64/hbbs /opt/rustdesk/
sudo cp rustdesk-server-linux-amd64/hbbr /opt/rustdesk/
sudo chmod +x /opt/rustdesk/hbbs /opt/rustdesk/hbbr
创建两个 systemd service 文件。hbbs 的配置:
ini复制[Unit]
Description=RustDesk ID Server (hbbs)
After=network.target
[Service]
Type=simple
ExecStart=/opt/rustdesk/hbbs -r 你的公网IP:21117
WorkingDirectory=/opt/rustdesk
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
hbbr 的配置:
ini复制[Unit]
Description=RustDesk Relay Server (hbbr)
After=network.target
[Service]
Type=simple
ExecStart=/opt/rustdesk/hbbr
WorkingDirectory=/opt/rustdesk
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
然后启用并启动:
bash复制sudo systemctl daemon-reload
sudo systemctl enable --now rustdesk-hbbs rustdesk-hbbr
sudo systemctl status rustdesk-hbbs rustdesk-hbbr
进程方式的优点是少一层 Docker 抽象,排障时可以直接看 systemd 日志;缺点是升级时需要手动替换二进制文件,没有 Docker 镜像 tag 切换来得干净。个人还是更推荐 Docker 方式。
4.3 离线部署:内网断网服务器如何处理
很多朋友的服务器虽然部署在内网,但可以被远控端访问,或者需要在内网环境里单独搭建一套 RustDesk 服务供内部使用。内网服务器通常没有外网访问权限,这时候需要在一台能联网的机器上先把镜像打包好,再传输过去导入。
在可以联网的外网机器上执行:
bash复制docker pull rustdesk/rustdesk-server:latest
docker save -o rustdesk-server.tar rustdesk/rustdesk-server:latest
把 rustdesk-server.tar 拷贝到内网服务器上,比如用 scp 或 U 盘:
bash复制scp rustdesk-server.tar user@内网服务器IP:/opt/rustdesk/
在内网服务器上导入镜像:
bash复制docker load -i /opt/rustdesk/rustdesk-server.tar
确认镜像已加载:
bash复制docker images | grep rustdesk-server
之后再正常使用 docker compose 启动即可。这里特别提醒一句:打包时一定要用 docker save,而不是 docker export。docker export 导出的是容器文件系统,会丢失镜像的启动命令、环境变量等元数据,导入后容器可能根本起不来;docker save 保存的是完整镜像层,导入后能原样还原。
如果你希望离线导入的版本完全可复现,建议不要使用 latest 标签,而是固定一个明确版本,例如 rustdesk/rustdesk-server:1.1.12,这样后续排查问题时更容易定位。
4.4 端口和状态自检
服务端部署完成后,先不要急着配置客户端,先在服务器本机做一轮端口自检:
bash复制sudo ss -lntup | grep -E '2111(5|6|7|8|9)'
正常会看到 hbbs 监听 21115/21116/21118,hbbr 监听 21117/21119,而且 21116 同时包含 tcp 和 udp 监听。如果只有 tcp 没有 udp,多半是启动参数或者安全组规则的问题。
5. 客户端配置:三行参数和它们背后的握手流程
RustDesk 客户端的配置界面里,核心就是“ID/中继服务器”那一栏和“Key”那一栏。很多教程让你直接填服务器 IP,但没解释为什么有时候只填一行也能用,有时候必须填满三行。我把新版客户端界面里可以配置的内容整理一下。
5.1 桌面端配置步骤
以 Windows 客户端为例,打开主界面后点击右上角菜单按钮,进入“设置 - 网络”,你会看到类似下面的配置入口:
- ID 服务器:填
你的公网IP - 中继服务器:填
你的公网IP:21117或留空 - Key:填服务端
id_ed25519.pub的内容
如果服务端的 hbbs 和 hbbr 在同一台机器上并且端口没改过,中继服务器一栏其实可以留空,因为客户端完成 ID 注册时,hbbs 会把中继服务器地址主动下发。但我仍然建议手写填上 你的公网IP:21117,这样即使以后 hbbs 地址变化,排查问题时也能少一个变量。
保存并应用配置后,主界面右下角的状态会从“未连接”变为“就绪”。这里要注意,RustDesk 新版本的配置保存有时需要点击“应用”按钮,甚至重启客户端才能完全生效。
5.2 Key 到底是什么作用
Key 对应的是服务端生成的 ed25519 公钥。当客户端连接服务器时,会用它来验证服务器的身份,并参与会话密钥协商。简单理解:没有正确填写 Key 的客户端,仍然可以连接服务器完成 ID 注册,但在建立远控会话时会被服务器拒绝,或者无法建立加密链路。
所以如果你发现 ID 状态已经变绿,但实际远控时一直提示握手失败,优先检查 Key 是否填写正确、有没有多余的空格。
5.3 怎么确认流量究竟走没走中继
这是个很实际的问题。远控窗口已经打开了,但到底走的是 P2P 还是中继?最简单的办法是看 hbbr 容器的日志:
bash复制sudo docker logs -f rustdesk-hbbr
如果远控过程中日志不断刷新,说明有流量在走中继转发;如果日志几乎没有任何输出,那说明连接是 P2P 建立的,中继服务器并没有被真正用到。这个方法也能帮你评估中继服务器的带宽压力到底来自哪里。
另一条判断路径是观察远控画面质量:如果两台机器处在不同运营商网络下,画面依然清晰流畅,多半是 P2P 打洞成功了;如果画面明显卡顿、码率被压得很低,而 hbbr 日志又在持续刷新,那就要考虑升级中继带宽或优化网络链路了。
5.4 被控端保持在线的一些经验
内网机器作为被控端时,需要保证 RustDesk 进程开机自启,并关闭系统的睡眠策略。Windows 上建议在电源设置里把“睡眠”改为“从不”,同时允许 RustDesk 在锁屏界面运行。Linux 桌面端则要留意 Wayland 会话下的屏幕捕获权限,必要时改用 X11 登录。
还有一个容易被忽略的点:被控端的网络最好能保持稳定出网,不要在路由器上做过于激进的 MAC 过滤或并发连接数限制。RustDesk 的心跳包会定期发送,如果路由器把空闲 UDP 会话回收得太快,设备可能会从 hbbs 的在线列表里掉线,导致你在外网怎么也连不上。遇到这种情况,可以先在被控端本地看一眼 RustDesk 主界面的网络状态是否显示“就绪”。
6. 手机端远控的特别注意事项:安装限制和后台权限
标题里提到的“小米澎湃手机禁止安装”是真实存在且非常典型的问题。RustDesk 作为远控软件,天然需要获取屏幕共享、辅助功能等敏感权限,因此不少国产手机系统在安装时会弹出风险提醒,甚至直接拦截安装。
6.1 小米澎湃(HyperOS)安装拦截的实际处理
正常情况下,从 GitHub Releases 下载的 RustDesk APK 是官方签名的,安全无毒。但小米 HyperOS 的纯净模式、应用安全扫描和应用商店策略有时会把它判定为“风险应用”,拦下来让你去应用商店安装。而小米应用商店上架的不一定是完整版,可能不是最新版本,功能也会有所阉割。
如果你需要安装 GitHub 原版包,可以尝试以下步骤:
- 在系统设置里找到“安全与隐私 - 更多安全设置 - 外部来源应用”,允许浏览器或文件管理器安装未知应用。
- 如果系统提示“纯净模式”会拦截风险应用,先暂时关闭纯净模式,或者在选择“继续安装”时勾选“仍然安装”。
- 如果安装过程中提示“应用可能会获取您的屏幕内容”,这是远控类应用的正常权限声明,确认来源是官网后继续即可。
- 安装完成后不要急着打开,先去“设置 - 应用设置 - RustDesk - 权限管理”里,把“显示在其他应用上层”“无障碍服务”等相关权限都授予。
开启辅助功能权限的方法:进入系统设置的无障碍已下载服务,找到 RustDesk,开启“使用情况访问”和“无障碍”开关。不开启这些权限,远控时你可能只能看到画面,却无法执行点击、滑动操作。
6.2 其他安卓系统的通用对策
如果你用的是华为、荣耀、OPPO、vivo 等,虽然各家弹窗文案不同,但底层逻辑都一样:远程控制类应用需要“无障碍”和“屏幕共享”权限,系统会不厌其烦地提醒风险。处理思路也类似:优先从官方渠道下载 APK,安装时允许“未知来源”,安装后在权限管理里放开“无障碍”“后台弹窗”“省电策略”等限制。
尤其要注意“省电策略”这一项,很多手机默认会限制后台应用联网,导致 RustDesk 被控端息屏一段时间后自动掉线。我把应用的后台运行策略改成“无限制”,再把自启动权限打开,这样手机放在家里充电时才能作为一个长期在线的被控端。
6.3 iOS 端配置简述
iOS 上安装 RustDesk 相对省心,直接从 App Store 下载即可,但配置方式和桌面端略有差异。App 主界面下方的“ID 中继服务器”入口里填入同样的 ID 服务器地址和 Key,即可连接自己的服务端。iOS 端的后台保活能力比安卓更强,但也需要保持 App 在后台不被手动杀掉。
6.4 不要忽视手机端的登录密码策略
手机作为被控端时,建议设置一个独立的访问密码,而不是沿用默认的临时密码。原因是手机可能在陌生网络环境下开机,临时密码刷新不及时会导致你连不上。固定密码建议设置成长随机字符串,至少 12 位以上,并定期更换。
7. 安全加固与长期运维:不要只搭完就扔在那里
服务端一旦暴露在公网上,就会成为被扫描的重点对象。RustDesk 的 21115-21119 端口特征非常明显,如果你不做任何加固,很快就能看到大量来自陌生 IP 的探测连接。安全加固这件事,必须放在部署完成后的第一步。
7.1 最小化端口暴露原则
如果你用不到网页版远控,那 21118 和 21119 完全没有必要对公网开放。在云安全组里只放行 21115、21116 的 TCP/UDP 和 21117 的 TCP 即可。少开放一个端口,就少一分被扫描的风险。
有些场景下,控制端来源 IP 是固定的,比如公司出口有一个固定公网 IP。这时可以在安全组里把 21117 的源 IP 白名单设为只有公司出口 IP 能访问。这样做不影响被控端主动连上 hbbs 注册,因为被控端只依赖 21116 和 hbbs 通信,不需要主动连 21117;只有打洞失败、需要走中继时,21117 才会被用到。控制端如果来自公司固定 IP,中继流量也就只会接受公司 IP 的连接。
7.2 定期更新版本
RustDesk 服务端和客户端的更新节奏并不完全同步。你可以关注 rustdesk-server 的 GitHub Releases,定期拉取新镜像并重建容器:
bash复制cd /opt/rustdesk
sudo docker compose pull
sudo docker compose up -d
升级前建议先备份 /opt/rustdesk/data 目录,尤其是 db_v2.sqlite3 和密钥文件。虽然正常情况下服务升级不会破坏数据,但远程控制工具的服务端一旦异常,会直接影响你所有设备的可用性,备份是最廉价的保险。
7.3 登录密码与会话策略
RustDesk 支持为每个客户端设置“永久密码”和“临时密码”。实践中我建议把被控端统一设置为高强度随机密码,并关闭“允许保存密码到本设备”的选项。控制端这边,尽量使用账号密码 + 二次确认的方式连接,避免
