ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

内网远程协助自建RustDesk服务端:hbbs/hbbr部署与排障指南

内网远程协助自建RustDesk服务端:hbbs/hbbr部署与排障指南

内网里的远程协助这件事,说大不大,说小也真能让人抓狂。财务的报表打不开、产线上位机的采集程序卡死、财务室那台老电脑打印机驱动天天掉,人不在现场,电话里说三遍对方还是点错地方。商业远程工具不是不能用,但一牵扯到内网隔离、数据不出网、设备数量上百、还要长期稳定,账就算不过来了。RustDesk 这类开源远程桌面工具之所以在这两年被大量内网场景选中,核心就一点:它的服务端可以自己搭,ID 注册、信令协商、流量中继全在你自己的机器上跑,被控端和主控端之间不需要经过任何第三方节点。这篇内容就是把这套东西在内网里真正跑起来的过程完整拆一遍——从 hbbs 和 hbbr 各自干什么、端口怎么规划、Docker 怎么拉起来、Key 怎么取和怎么下发、客户端怎么批量配置,到连不上时该按什么顺序排查。适合手里管着几十上百台内网机器、需要一套可控远程通道的运维和 IT 支持人员,也适合只是想让家里那台机器和公司内网机器互通的动手派,基础差一点也能照着做,因为每一步我都写清楚了为什么这么干。

1. 先想清楚:自建服务端到底解决了什么问题

1.1 内网远程协助真正卡住的三个点

很多人一上来就问“用哪个远程软件好”,这个问法本身就偏了。内网场景的麻烦从来不是软件功能多少,而是三个很具体的约束叠在一起。第一个约束是网络可达性,两台机器可能在不同 VLAN、不同网段,中间还隔着防火墙和 ACL,公网那套“双方都连到云上再转发”的模型在这儿直接失效,因为被控端压根没有出网权限。第二个约束是数据流向,屏幕画面、剪贴板、传输的文件都属于敏感内容,走第三方服务器在合规上过不去,很多时候不是技术问题而是流程上就不允许。第三个约束是规模和维护成本,商业方案按设备数或者按坐席收费,几十台还能忍,几百台就是一笔持续支出,而且版本升级、策略变更都得跟着厂商节奏走。

RustDesk 的架构恰好把这三点都绕开了。它把服务端拆成两个独立进程,一个负责“你们互相认识”,一个负责“认识之后话说不通我帮你转达”。这两个进程可以部署在内网任意一台常开的机器上,哪怕是一台低配的旧台式机,只要网络位置合适就行。客户端连的是你填的那个地址,不是官方节点。这意味着被控端只要能访问到这台内网服务器,哪怕它完全出不了网,远程协助照样能用。

我见过不少团队一开始图省事直接用默认配置,结果发现设备列表里一堆陌生 ID,或者连接时好时坏,最后才发现自己连的是公共节点,而公共节点的中继带宽是共享的,晚高峰卡成 PPT 一点都不奇怪。自建的意义不只是“数据不出网”,更是把中继带宽这个变量握在自己手里。

1.2 hbbs 和 hbbr 的分工,决定了你要开哪些端口

这套服务端只有两个二进制,名字起得很直白,但搞不清它们各自职责的人特别多,配置错一半都是从这里开始的。

hbbs是 ID 服务器兼信令服务器。你可以把它理解成“通讯录加撮合人”:每台客户端启动后会向它注册自己的 ID 和网络位置,主控端要连某台机器时,先问它“这个 ID 现在在哪、走什么方式能通”。它还负责 NAT 类型检测,帮着判断两端能不能直连。hbbr是中继服务器,只在直连失败的时候出场——两端握手谈不拢,就把流量都发给 hbbr,由它转一手。

这个分工直接决定了端口规划。hbbs 要占 21115(TCP,NAT 类型测试)、21116(TCP 和 UDP 都要,TCP 做握手、UDP 做心跳和 ID 注册)、21118(TCP,给 Web 客户端用的 WebSocket)。hbbr 占 21117(TCP,中继数据)和 21119(TCP,WebSocket 中继)。其中21116 的 UDP 是最容易被漏掉的一个,很多人防火墙只放 TCP,结果就是设备能看到、能连上,但状态一会儿在线一会儿离线,或者连上几秒就断,排查半天以为是软件 bug。心跳走不通,服务器就认为设备掉线了。

提示:端口不是“能用就行”,UDP 21116 必须双向放通。跨网段场景下,除了主机防火墙,中间的硬件防火墙和交换机 ACL 也要一起看,只改一边等于没改。

1.3 这套方案的能力边界,提前说清楚

自建不等于万能。有几个边界最好在动手前就想明白,省得后面返工。

中继带宽是硬瓶颈。两端直连成功时,画面数据是点对点走的,服务器几乎不承担流量;但跨网段、跨 NAT、或者策略上禁止直连时,所有画面都会压到 hbbr 上。一路 1080P 的普通办公画面,按经验大概在 1~3 Mbps 波动,如果同时有五六个人在协助,一台百兆网卡的机器就会明显吃紧。所以中继服务器的网卡和上行带宽要按“并发路数 × 单路码率”来估,别拿一台只剩残血的虚拟机凑合。

它不解决“机器没开机”的问题。远程协助的前提是被控端在线且服务在跑。真要处理关机、蓝屏、进不了系统这类情况,需要的是带外管理,跟这套工具是两回事。

纯隔离网络里要考虑软件来源。如果内网完全不出网,客户端安装包、服务端镜像都得提前准备好离线文件带进去。这一点在实施排期里经常被忘掉,到了现场才发现下不了安装包,白跑一趟。

2. 部署前的资源核算与端口规划

2.1 服务器放在哪、要什么配置

位置比配置重要得多。理想的位置是所有被控端和主控端都能访问到的中间网段,通常是办公网的核心区或者一个独立的运维管理网段。如果公司有多个厂区、多个子网,最好让服务器处在一个被所有子网路由可达的位置,而不是塞在某个车间的接入交换机下面。

配置方面,我给个实测可用的参考:2 核 4G 起步,跑 hbbs 和 hbbr 两个进程绰绰有余,CPU 在空闲时基本是个位数占用。真正需要关注的是网络:千兆网卡是底线,如果中继并发预期超过十路,建议上万兆或者至少做网卡绑定。磁盘几乎不占,日志量也很小,20G 系统盘足够,但一定要留出日志轮转的空间,长期运行的机器被日志写满磁盘这种事太常见了。

系统选择上,Linux 是最省心的,Debian 系和 RHEL 系都行,内核版本别太老,主要是为了 Docker 和网络栈的稳定性。Windows Server 也能跑,但服务化配置会麻烦一些,除非团队完全没有人熟悉 Linux,否则不建议。

还有一个容易忽略的点:时间同步。服务器和被控端的时间偏差过大,会导致连接握手阶段的校验出问题,表现为“偶尔能连、偶尔连不上”这种最烦人的间歇性故障。部署前确认 NTP 是通的,或者至少保证服务器时间是准的。

2.2 端口清单与防火墙策略落地

把端口整理成一张表,实施的时候直接对着核对,比记在心里靠谱。

端口协议所属进程用途是否必须
21115TCPhbbsNAT 类型测试必须
21116TCPhbbsID 注册与握手必须
21116UDPhbbs心跳保活必须,最易漏
21117TCPhbbr中继数据转发必须
21118TCPhbbsWeb 客户端 WebSocket可选
21119TCPhbbrWeb 客户端中继 WebSocket可选

放通策略上,我的习惯是源地址做收敛,不要图省事写成任意来源。比如 21116/21117 只允许办公网段和运维网段访问,21115 可以稍微宽一点但也没必要全网开放。安全组或者 iptables 里按“进程 + 端口 + 源网段”三条一起写,事后排查有据可查。

如果服务器用的是云主机或者虚拟化平台,除了系统防火墙,还要注意平台侧的安全组是另一层,两层都要配。这个坑我踩过不止一次:系统里ss -lntup看着端口都在监听,外面死活连不上,最后发现是平台安全组没放行。

2.3 部署方式的三条路线怎么选

实际可选的就是三种,各有适用场景。

Docker 部署是最推荐的,尤其是第一次上手。好处是依赖隔离、升级简单、卸载干净,官方镜像已经把两个进程打包好了,一条命令就能拉起来。缺点是要求宿主机有可用的容器运行时,在完全不联网的内网里需要先把镜像save成 tar 再load进去。

二进制 + systemd适合对容器有顾虑的环境,比如某些生产网段不允许跑容器。这种方式最“素”,出问题好定位,但升级要手动替换文件、重载服务,机器多了就烦。

源码编译基本没必要,除非你要改代码或者跑在特殊架构上。日常运维不建议走这条路。

我给的建议很直接:能上容器就上容器,把精力留给后面的客户端配置和排障,别在编译环境上耗时间。

3. 服务端落地:从拉起容器到拿到 Key

3.1 用 Docker 拉起 hbbs 和 hbbr 的完整过程

先建数据目录。两个进程要共用同一个数据目录,因为 Key 是 hbbs 生成、hbbr 读取的,分开放会直接导致中继校验失败。

mkdir -p /opt/rustdesk/data cd /opt/rustdesk

然后拉起 hbbs。这里有个关键参数:-r后面要填 hbbr 的地址,端口 21117。如果两个容器在同一台机器上,填本机的内网 IP 就行,不要填 127.0.0.1,因为客户端拿到的这个地址是要用来发起连接的,填回环地址客户端永远连不上。

docker run --name hbbs \ -v /opt/rustdesk/data:/root \ --net=host \ -d \ rustdesk/rustdesk-server hbbs -r 192.168.10.5:21117

再拉起 hbbr:

docker run --name hbbr \ -v /opt/rustdesk/data:/root \ --net=host \ -d \ rustdesk/rustdesk-server hbbr

注意:用了--net=host就不要再写-p端口映射,两者混写虽然不报错,但会让人误以为流量走的是映射规则,后面排查问题时容易判断错方向。要么全用 host 网络,要么全用端口映射,别混。

--net=host的好处是客户端看到的源地址就是真实 IP,NAT 判断更准确,中继和直连的切换也更稳。如果宿主机上还有别的服务抢端口,那就只能改用-p映射,这时候-r里填的地址要确保客户端能路由到。

启动完先看日志,确认没有报错:

docker logs hbbs docker logs hbbr

正常的日志里会打印出监听端口和 Key 的指纹信息。如果看到“Permission denied”或者端口占用相关的报错,先解决端口冲突再往下走。

3.2 Key 的读取、备份与更换

Key 是这套体系里最容易被忽视、也最容易配错的东西。它是一对密钥,hbbs 首次启动时自动生成,存在数据目录里,公钥文件叫id_ed25519.pub。客户端配置里要填的就是这个公钥的内容。

cat /opt/rustdesk/data/id_ed25519.pub

输出的是一串 Base64 字符,复制的时候千万不要带换行和空格。我见过太多“Key 填了但就是连不上”的案例,最后发现是复制时多带了一个回车,或者编辑器自动折行插了空格。

Key 的几个实操要点:

  • 必须备份。数据目录丢了,Key 就没了,所有客户端都得重新配一遍。建议把id_ed25519和id_ed25519.pub一起打包存到安全位置。
  • 不要随意更换。换 Key 等于所有客户端的配置全部失效,如果设备量大,这个工作量非常可观。真要换,提前规划好批量下发的手段。
  • Key 不是密码,但也要当敏感信息对待。拿到 Key 的人可以往你的服务器上注册设备,所以别往公开文档里贴。

还有一个细节:hbbr 读取的也是数据目录里的同一份 Key,所以两个容器的挂载路径必须一致。如果 hbbr 启动日志里出现 Key 相关的警告,八成是挂载路径写错了或者没挂。

3.3 怎么确认服务是真的活着

容器Up不代表服务能用。我习惯做三层验证,一层层往上。

第一层,端口在听。在服务器上跑:

ss -lntup | grep -E '21115|21116|21117'

应该能看到 hbbs 监听 21115、21116(TCP),hbbr 监听 21117。UDP 21116 用ss -lnup单独确认。

第二层,本机能连。用telnet 192.168.10.5 21116或者nc -zv 192.168.10.5 21117,通不通一目了然。

第三层,换一台机器从别的网段连。这一步是关键,因为本机通不代表跨网段通。找一个和目标被控端同网段的机器,测 21116 的 TCP 和 UDP。UDP 没有 telnet 可用,可以用nc -zu试探,或者直接跳到客户端配置环节,用实际连接结果来验证——连上之后观察是否频繁掉线,就能反推 UDP 是否通。

4. 客户端配置:从一台到两百台

4.1 单机手工配置,每个字段都要搞明白

先在一台机器上手工配通,把每个字段的含义弄清楚,后面批量才有依据。打开客户端设置,找到网络相关的那一栏,有三个字段要改:

ID 服务器填 hbbs 的地址,比如192.168.10.5。如果端口不是默认的,写成192.168.10.5:21116这种形式。

中继服务器填 hbbr 的地址,比如192.168.10.5。两个进程在同一台机器上时,这两个字段填的是同一个 IP,很多人会疑惑“为什么一样”,因为它们只是地址相同,端口不同,客户端自己会区分。

Key填刚才cat出来的公钥内容。

填完保存,客户端会重启网络连接。此时看主界面的 ID,如果显示的是纯数字(通常是 9 位或 10 位),并且状态正常,说明注册成功了。如果 ID 一直转圈或者显示“未就绪”,那就是连不上 hbbs,回到上一节查端口和防火墙。

提示:改了配置之后一定要完全退出客户端再重开,不要只关窗口。托盘图标还在就说明进程没退,配置可能没重新加载。

4.2 配置文件与批量下发

手工配一台还行,两百台会出人命。好在客户端的所有设置都存在一个 TOML 文件里,直接改文件或者用脚本覆盖就行。

文件位置随安装方式不同,常见的有这几处:便携版通常在程序目录或者%APPDATA%\RustDesk\config\RustDesk2.toml;以服务方式安装的 Windows 客户端,配置在系统服务账户的目录下,路径类似C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk2.toml;Linux 下在~/.config/rustdesk/RustDesk2.toml。

内容结构大致是这样:

[options] custom-rendezvous-server = '192.168.10.5' relay-server = '192.168.10.5' key = '这里填你的公钥内容'

批量下发的思路有这么几种,按实施成本从低到高排:

域环境组策略推文件。把写好的 TOML 放在共享路径,用启动脚本或者登录脚本复制到目标位置。适合有统一域管理的环境,一次配好长期有效。

脚本批量执行。用手里的批量运维工具,或者写个简单的 PowerShell、Bash 循环,遍历设备列表逐个推送。关键是推完要校验,不能推完就算完事。

$src = "\\fileserver\deploy\RustDesk2.toml" $dst = "C:\Windows\ServiceProfiles\LocalService\AppData\Roaming\RustDesk\config\RustDesk2.toml" Copy-Item -Path $src -Destination $dst -Force Get-Content $dst | Select-String "custom-rendezvous-server"

打包进安装镜像。如果有标准化的系统镜像,直接把配置文件做进镜像里,新装机器开箱即用。这是最省事的长期方案,但要记得镜像里的配置文件版本要和当前服务端一致,服务端换 Key 之后镜像要跟着更新,否则新装的机器全是连不上的。

4.3 无人值守访问怎么设才安全

远程协助分两种:有人值守和无人值守。前者需要被控端的人点确认,后者是主控端直接凭密码连进去。内网运维里大量场景是后者——晚上十点服务器要重启,没人守在机房。

设置固定密码的位置在安全设置里,勾选使用固定密码并设置一个强口令。密码策略上我的建议是:长度优先于复杂度,十六位以上的随机字符串比八个字符里塞满符号更抗暴力破解,而且不需要定期更换带来的管理负担。

固定密码的风险在于,只要 ID 和密码都泄露,任何人都能连进来。所以配套要做两件事:一是限制客户端的可连接范围,二是在网络层做访问控制,让非运维网段压根连不到 21116。这两层做完,即使密码泄露,攻击面也被压到很小。

另外,如果某些机器只是被主控端临时看一次,用完就该把固定密码关掉,改回临时密码模式。这个动作最好写进操作规范里,靠人记是记不住的。

5. 安全加固:Key 之外还得做点什么

5.1 把注册入口管起来

自建服务器最大的隐性风险是谁都能往你的服务器上注册设备。只要有人拿到你的服务器地址和 Key,就能把一台机器注册进来,出现在你的设备列表里。内网环境相对封闭,但这个口子还是要收。

收紧的手段有几个方向。一是服务器侧限制来源,在防火墙层面只允许特定网段访问 21116,这个最直接也最有效。二是利用服务端自身的参数,新版本的 hbbs 提供了强制 Key 校验的开关,具体参数名和用法以你拉到的那个版本执行--help的输出为准,不同版本之间有差异,别照抄网上的旧教程。三是定期清理设备列表,把长期不用的、来源不明的 ID 清掉,虽然麻烦但能发现异常。

5.2 中继策略与加密选项

有两个与服务端行为相关的设置值得专门调一下,通过环境变量控制。

强制走中继:适用于策略上不允许点对点直连的环境,比如跨安全域的场景。设置之后所有流量都经 hbbr 转发,好处是路径固定、便于审计和限速,坏处是服务器带宽压力直线上升。开之前先算清楚并发量。

只接受加密连接:拒绝未加密的会话,这个建议默认打开,代价极小。

docker run --name hbbr \ -v /opt/rustdesk/data:/root \ --net=host \ -e "ALWAYS_USE_RELAY=Y" \ -e "ENCRYPTED_ONLY=1" \ -d \ rustdesk/rustdesk-server hbbr

注意:环境变量是在容器启动时读取的,改完必须重建容器,重启不生效。这一点和改配置文件不一样,别搞混。

5.3 日志留痕与日常巡检

内网自建的另一个好处是日志都在自己手里。hbbs 和 hbbr 的日志默认输出到标准输出,容器化部署时用docker logs看,但长期留存要配置日志驱动或者定期导出。

巡检我一般看三样东西:连接数是否异常增长、中继流量是否长期打满、磁盘是否被日志吃掉。前两个指标反映的是使用情况和容量水位,第三个是稳定性问题。这三项做成每周一次的例行检查,成本很低,但能提前发现不少隐患。

6. 排障实录:症状对照与排查顺序

6.1 排查的基本顺序

遇到连不上,别一上来就怀疑软件,按这个顺序走能省大量时间:

  1. 客户端能不能拿到 ID。拿不到,问题在客户端到 hbbs 这一段。
  2. 两台机器互相看不看得见。都拿到 ID 但列表里搜不到对方,多半是 Key 不一致或者不在同一个服务器。
  3. 连上之后稳不稳。能连但频繁断,重点查 UDP 21116 和网络质量。
  4. 画面卡不卡。能连但很慢,先判断是直连还是中继,再看带宽。

这个顺序的本质是从近到远、从确定到不确定,每一步都有明确的成功判据,不会陷进“感觉好像是网络问题”的猜测里。

6.2 常见症状速查表

症状最可能的原因处理方式
ID 一直转圈,显示未就绪客户端连不到 hbbs 的 21116,或 Key 填错先测 TCP 21116,再核对 Key 有无空格换行
两台都拿到 ID,但搜不到对方两端连的不是同一个服务器,或 Key 不一致对比两端配置文件里的服务器地址和 Key
能连上,几秒后断开UDP 21116 心跳不通放通 UDP,检查中间防火墙和 ACL
连接成功但画面全黑被控端显卡驱动或采集权限问题换采集模式,或用服务模式重试登录界面
画面卡顿、延迟高走了中继且带宽不足,或直连质量差看服务端流量判断是否中继,限制画质或扩容
中继服务器 CPU 打满并发中继路数过多分流到多台中继,或降低画质码率
定时断连,间隔很规律时间不同步或会话超时策略校准 NTP,检查空闲断开设置
重启后配置丢失改的是用户配置,实际生效的是服务配置找到服务账户下的配置文件位置重新下发

6.3 几个踩过的坑,写下来省得别人再踩

坑一:容器重启后 Key 变了。原因是数据目录没挂载或者挂载路径写错,每次启动都重新生成密钥。表现是所有客户端突然全部连不上。解决方法就是把-v参数写对,并且启动后立刻cat一次公钥做比对。

坑二:-r参数填了回环地址。服务端自己看着一切正常,客户端就是连不上中继。原因是下发给客户端的地址是127.0.0.1,客户端在自己机器上找中继当然找不到。改成真实内网 IP 即可。

坑三:只放了 TCP 忘了 UDP。这个前面提过,但值得再强调一次,因为它是最典型的“能用但不好用”类故障,症状不明确,排查起来很折磨人。

坑四:多网卡机器上服务监听到了错误的网卡。服务器如果有两块网卡,一个办公网一个管理网,客户端从办公网访问却连不上,可能是服务绑定在了另一块网卡上。用ss -lntup看监听地址是0.0.0.0还是具体 IP,能快速定位。

坑五:以为改了配置文件就生效。客户端在运行中会缓存配置,文件改了但进程不重读的场景很常见。批量下发的时候一定要先停进程、再写文件、再启动,顺序错了就是白忙一场。

6.4 画质与延迟的调优方向

同一套网络条件下,画质设置对体验的影响非常大。默认设置偏保守,普通办公场景够用,但如果要看清小字或者做精细操作,就得调。

调优的优先级是这样:先降帧率再降分辨率,因为帧率对带宽的影响更直接,而分辨率降太多会让文字变糊,反而影响使用。码率上限可以手动压到一个固定值,避免画面剧烈变化时瞬时打满带宽。

如果确认走的是中继,而且服务器带宽吃紧,可以给中继单独限速,保证多路并发时每路都有基本可用带宽,而不是先来的占满后来的卡死。这个策略在多人同时协助的场景里很有用。

7. 我个人在实际部署中的几点体会

这套东西我从早期版本用到现在,最大的感受是:部署本身半小时就能搞定,真正花时间的是网络规划和客户端分发。服务器拉起来太容易了,容易到让人产生“已经完事了”的错觉,然后卡在某个网段的 UDP 不通上耗掉一整天。所以我的习惯是,动手之前先把端口表和网段图摊开,把“哪台机器在哪个网段、能不能到服务器、UDP 通不通”这三个问题回答完,再开始装。

第二个体会是配置一定要有版本管理。客户端的 TOML 文件、服务端的启动参数、防火墙规则,全都丢进一个目录里用版本工具管起来,改了什么、什么时候改的、为什么改,一笔一笔有记录。设备量上去之后,靠脑子记和靠翻聊天记录找,是两个完全不同量级的效率。

最后一个实用技巧:先拿两台机器做小范围验证,跑满一周再铺开。一周时间足够暴露间歇性掉线、时间同步、防火墙会话老化这类问题。铺开之后再回头改,成本是前者的十倍不止。这套流程跑顺之后,内网里的远程支持基本可以做到“电话打过去的同时画面已经在屏幕上”,那种顺畅感,比什么功能清单都实在。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进