news 2026/10/1 22:40:31

RustDesk编译内嵌自建服务器与key:打造免配置远程桌面客户端

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RustDesk编译内嵌自建服务器与key:打造免配置远程桌面客户端

自己编译RustDesk,把自建ID服务器和key写进客户端,是我折腾过最值回票价的一件事。远程桌面这玩意儿,日常用TeamViewer、向日葵倒是方便,可一旦动了“这台机器归我管,数据不想经过第三方”的念头,自建就成了唯一解法。RustDesk本身就是开源项目,服务器端和客户端全在自己手里,但默认编译出来的客户端,连接的是官方公共服务器,你得手动填ID服务器、填key,才能连上自己的服务。对于自己用,这倒无所谓;可如果你是给公司内部十几号人分发,或者想让家里人装完就能用,这一步手动配置就是灾难——总有人会填错地址,总有人干脆不填,然后跑过来问你为什么连不上。

所以这篇文章要解决的,就是一件事:从源码编译一个RustDesk客户端,把自建ID服务器地址和key提前“焊”进去。编译出来的安装包,用户装上就能直连你的服务器,不需要任何额外配置。适合三类人看:给企业内部批量部署的运维、想在NAS或VPS上搭一套私有远程方案的玩家、以及想改个客户端名头甚至Logo做点定制分发的人。

1. 方案设计:为什么一定要编译写入,而不是让用户手动填

先聊清楚一个核心问题:RustDesk自建服务器之后,客户端连接需要什么?答案就两个东西——服务器地址和一个叫key的值。服务器地址好理解,就是跑着ID服务器(hbbs)和中继服务器(hbbr)那台机器的IP或域名。key则是服务器的公钥标识。RustDesk的架构和远程软件不太一样,它的客户端在建立连接前,会先校验服务器的身份,防止有人假冒服务器截取流量。这个校验靠的就是key,相当于你们之间的一套“接头暗号”。

1.1 自建ID服务器和key到底解决了什么问题

RustDesk的完整链路分三段:客户端A、客户端B、中间的服务器。服务器里又分两个角色,一个叫hbbs,管ID注册和信令,就是“你帮我找一下对方在哪”;另一个叫hbbr,管数据中继,当两个客户端之间没法直接打洞传输时,流量就走它转发。所以搭建一套自建服务,最少要跑这两个进程。key是在服务器第一次启动时自动生成的,存在服务器的硬盘上,是一个叫id_ed25519.pub的文件。客户端连接时填的这个key,就是要和服务端的公钥对上,相当于指纹校验,防止中间人劫持。

1.2 两种下发方式:手动填写与编译内嵌

方式一:客户端装好之后,在设置里填ID服务器和中继服务器,再把key也填进去。优点是灵活,换个服务器改个配置就行;缺点是每位用户都得操作一遍,而且大部分人分不清“ID服务器”和“中继服务器”的端口区别,填错一个就连不上。

方式二:编译时就把这些信息写进代码里,客户端启动就是“已配置”状态。用户装完打开,主界面直接出来一个ID,让别人用这个ID连你,或者你在另一台机器输他的ID就能连过去,全程不用碰设置。缺点也明显——一旦服务器地址要变,得重新编译分发。但对于固定服务器、长期使用的场景,这个缺点完全不是问题。

我的选择一直是第二种。原因很朴素:远程桌面这东西,出问题的概率本来就高,你要是再把“填服务器地址”这种配置负担甩给用户,出了问题你根本不知道是网络不行,还是他key填错了。直接编译内嵌,变量全在自己手里,排查起来省太多事。

1.3 编译写入前要搞懂的三件事

第一,你要有一个能编译的环境,RustDesk客户端是Rust核心加Flutter界面,编译链比较重,尤其是Windows客户端,环境配置最麻烦。第二,服务器端要先跑起来,并取出key,不然你编译时不知道该写什么值。第三,要明白改代码不是搜个关键字替换那么简单,新版RustDesk的公共服务器地址和key在源码里出现的位置不止一处,必须都改到位,否则编译出来的客户端部分模块仍然会走官方服务器。

这三件事没搞懂就动手,大概率会在编译中途卡住,或者编译出来连不上自己的服务器。下面按顺序走。

2. 动手前的准备:编译环境与依赖

编译RustDesk客户端,最典型的目标平台是Windows和Linux。我以最常见的Windows客户端编译为例,这套流程跑通后,Linux只是换一套依赖而已。

2.1 一条主线和两条分支

编译这件事,主线永远是:准备好Rust工具链、准备好Flutter SDK、拉源码、改配置、编译、打包。两条分支是:如果你只想要命令行编译好的exe,可以走纯Rust路线;但RustDesk的界面是Flutter画的,要出完整的带GUI的Windows客户端,Flutter那一步绕不开。我的建议是别省,直接按完整流程走。因为平常用的客户端,不只是连接界面,还有文件传输、白板、聊天这些功能,纯命令行模式做不出来完整体验。

2.2 Rust与Flutter环境搭建

环境搭建是第一个坑,我见过太多人倒在这里。

Rust工具链安装,去官网跑rustup安装脚本就行。这里有个关键点:Windows下编译RustDesk推荐用GNU工具链,而不是MSVC。原因不是MSVC不行,而是RustDesk依赖的某些原生库在GNU链下更省心。装完记得把cargo的bin目录加到PATH里。

Flutter SDK,去Flutter官网下Stable版本,注意版本要和RustDesk源码要求的对齐。RustDesk的README.md里一般写了推荐的Flutter版本,别直接上最新版,否则Dart版本不一致,编译时满屏报错。装完Flutter,还要跑一下flutter doctor,把Windows的Desktop支持勾上,Visual Studio 2022那一堆C++桌面开发组件也得装——这个部分是给Flutter底层用的,缺了会编不过。

依赖镜像这一步,强烈建议配一下。国内直接拉crates.io和pub.dev会很慢,经常超时。cargo的镜像配置写在$HOME/.cargo/config.toml里,Flutter的镜像通过环境变量PUB_HOSTED_URL和FLUTTER_STORAGE_BASE_URL指定。这个不敏感,纯粹是加速。

2.3 源码拉取与依赖镜像配置

RustDesk源码直接用Git拉:

git clone https://github.com/rustdesk/rustdesk.git cd rustdesk

拉完之后,先别急着编译,把子模块也同步了。RustDesk有几个依赖是以submodule形式引入的,不更新的话编到一半会提示缺文件:

git submodule update --init --recursive

这里要注意,子模块体积不小,网络不好时容易中断,建议开代理或多次重试。我自己遇到过一次只拉了一半就断了,后续编译各种奇怪报错,最后删了重新拉才解决。

环境都就绪后,可以先跑一次不带修改的编译,验证环境没问题。这个第一次编译会非常久,十几分钟到半小时都很正常,因为几百个crate都要从源码构建。确认能出包后,再去做服务器配置改动,这样后面排查问题时,你能区分是环境问题还是代码问题。

3. 服务器端部署与key生成

客户端的修改是后面的事,服务器必须先跑起来,因为你编译时需要用到服务器生成的key。部署方式有Docker和直接跑二进制两种,我两个都试过,这里分别讲。

3.1 hbbs和hbbr的角色划分

服务器端是RustDesk官方提供的另一个仓库rustdesk-server,编译好后会得到两个二进制文件:hbbs和hbbr。hbbs监听21115到21116端口,负责ID注册和信令转发,说白了就是“登记每台设备,帮它们找到彼此”;hbbr监听21117端口,负责两台设备之间没法直连时的流量转发。两个都得跑,缺一个客户端就玩不转。

如果把整套服务比作一个公司前台:hbbs是前台服务员,负责登记来访者、转达消息;hbbr是内部快递员,A部门要给B部门送文件,自己走不过去,就由快递员跑一趟。

3.2 CentOS 7上从零部署一套服务

很多NAS和VPS还是CentOS 7的环境,这里给一套我实际验证过的部署流程。先装基础依赖:

yum install -y wget tar

然后去GitHub的RustDesk Server Releases页面下载对应Linux版本的压缩包。下载后解压,把hbbs和hbbr放到/usr/local/rustdesk-server/目录下。给执行权限后,先手动跑一次生成密钥:

cd /usr/local/rustdesk-server ./hbbs -r /data/rustdesk ./hbbr

-r参数指定数据存放目录。第一次启动后,这个目录下会生成id_ed25519和id_ed25519.pub两个文件。前者是私钥,绝对不要泄露;后者就是客户端要用的key。

手动启动没问题后,用systemd把它俩托管起来,开机自启才省心。hbbs的systemd配置大致如下:

[Unit] Description=RustDesk ID Server After=network.target [Service] Type=simple ExecStart=/usr/local/rustdesk-server/hbbs -r /data/rustdesk Restart=always [Install] WantedBy=multi-user.target

hbbr同理。配置好后systemctl enable --now hbbs hbbr,再firewall-cmd把21115到21117这几个TCP/UDP端口放行。如果服务器在云上,安全组规则也得同步放通。

3.3 取出key并理解它的作用

key就在id_ed25519.pub文件里,用cat查看:

cat /data/rustdesk/id_ed25519.pub

输出是一长串字母数字,这就是后面要写进客户端的key。有些人会问,这个key和账号密码有什么区别?区别很大:key是服务器身份的指纹,客户端用它在连接前校验“对面确实是你的服务器”,防止有人伪造一个同名服务器来截获连接。它不决定谁能连,只决定客户端敢不敢连。这就像你见网友前先核验对方身份证照片,而不是进门后再随便聊。

所以这个key在客户端里是绝对必要的,不填或者填错,客户端会直接报错“key值未知”,拒绝建立连接。理解了这一点,你就明白为什么客户端必须内置key——它和安全直接相关。

4. 编译客户端并写入ID服务器和key

服务器端就绪,key也拿到了,接下来是重头戏:改客户端源码,把服务器地址和key写进去,然后编译出开箱即用的安装包。

4.1 定位源码里的服务器配置

RustDesk源码分两部分:flutter目录是界面层,core或libs目录是Rust核心层。公共服务器信息在两个地方都可能出现,我的做法是直接在源码根目录全局搜索关键字,比如rustdesk.com或ny.rustdesk.com,把出现的位置全找出来。

不同版本的源码结构有差异,但思路一致:找到默认的RustDesk官方公共服务器地址、默认的key常量,然后把它们替换成你自己的服务器地址和服务器key。特别注意别只搜Rust目录,Flutter的Dart代码里也可能有硬编码的旧配置。搜索时用大小写不敏感模式,因为源码里可能出现RustDesk.com这种写法。

4.2 写入服务器地址和key

找到配置文件后,改动逻辑并不复杂。核心是把类似下面这样的默认值:

server_host: "rustdesk.com" key: "xxxxxxxxxxxxxxxxxxxx"

替换成自己的:

server_host: "your-server-ip-or-domain" key: "你的id_ed25519.pub文件内容"

服务器地址可以填IP,也可以填域名。如果填域名,建议解析到服务器公网IP上,并且做好端口转发。这里的重点坑在于:某些版本里还有“中继服务器地址”的独立配置项。很多人只改了ID服务器地址,忘了改中继地址,结果客户端能注册上线,但远程时显示“无法连接中继服务器”。所以改完后,要在源码里搜一遍relay server或者hbbr相关配置,确保中继地址也指向你的服务器。

另外一个容易被忽略的点:如果你的服务器有多个网卡或用了Docker映射端口,hbbs对外公布的地址可能和内部地址不一致。RustDesk的hbbs启动时可以加-r参数指定对外域名或IP,建议服务器端启动时就把对外域名写死,这样客户端编译时填同一个域名,两边不会打架。

4.3 编译命令与产物

改完代码,进入flutter目录(或者按源码说明进入对应目录),开始编译Windows客户端:

flutter build windows --release

这一步会先编译Rust核心库,再编译Flutter界面,最后打包成Windows可执行文件。产物在flutter\build\windows\x64\runner\Release目录下。想做成安装包,可以再用Inno Setup之类的工具,把整个Release目录打包成一个exe安装程序。

如果仅仅是测试,直接运行这个目录下的exe即可。打开后主界面会直接显示本机的ID,说明服务器配置已经生效——因为客户端在无配置状态下,第一屏会提示“未配置服务器”,而我们现在编译出来的版本直接进入了正常界面。

编译过程中最常见的报错是缺依赖:比如cannot find -lpublic这类Qt相关的链接错误、或者某个crate下载不下来。前者通常是环境缺少Qt开发库,后者多半是网络问题,重试或换成镜像源能解决。遇到报错别慌,看最下面几行错误信息,网上基本都有现成答案。

4.4 验证连接是否成功

编译出包后,验证流程分两步。第一步,在编译机上启动客户端,确认主界面ID正常显示;第二步,用另一台机器装官方原版客户端,手动填你的服务器地址和key,尝试连接编译机。如果能连通,说明服务器端和key都对。再用编译版客户端去连另一台机器,验证编译时写入的配置确实生效。

这里有个容易踩的坑:验证时如果用的是局域网IP,两台设备在同一内网下,RustDesk会走内网直连,发现不了服务器的问题。所以第一轮验证建议让一台设备走公网(或用公网服务器做中继),强制流量走hbbr,这样才能确认整套链路完整。我见过不少人内网测得好好的,一搬到外网就拉胯,就是因为没验证中继链路。

5. 常见问题与排查技巧实录

自建RustDesk这套流程,我前前后后帮人排查过不少问题,踩过的坑总结起来其实就几大类。

5.1 key值未知、地址为空、连接超时三类常见故障

“key值未知”是出现频率最高的一个。原因基本都是客户端填的key和服务端的id_ed25519.pub内容对不上。有些人复制key时多复制了空格或换行符,有些人服务器重新部署时换了密钥对但客户端没更新。排查思路很简单:去服务器上重新cat一次key文件,和客户端配置逐字符比对。如果是新建服务器,第一次启动hbbs时生成的密钥需要妥善备份,丢了或换了,所有已经下发的客户端都得重新编译配置。

“地址为空”意味着客户端配置里没写入有效服务器地址。这种情况在编译版里如果出现,八成是源码中对应的配置项没改对位置,或者在编译时被其他配置覆盖了。再检查一遍全局搜索的结果,确认所有硬编码的官方服务器地址都被替换了。

“连接超时”最复杂。先别怀疑客户端,用telnet或nc测一下服务器的21115到21117端口是否通。很多情况下是云服务商安全组没放行UDP端口,或者本地防火墙没配置。还有一个隐蔽问题:某些宽带运营商环境下,UDP流量会被限速或丢弃,导致信令不畅。这时候可以看看是不是能走TCP——RustDesk新版本部分支持TCP模式,但默认还是UDP为主,UDP端口不通会非常难排查,因为TCP端口检查全通,实际就是连不上。

5.2 编译依赖失败的几种情况

编译失败这块,我列个速查表:

报错特征常见原因处理办法
cannot find -lpublicQt开发库缺失或路径不对确认安装Qt对应版本,并设置好环境变量
crate下载超时网络原因配置rustup镜像源,重试
版本校验错误RustDesk要求特定版本的工具链按README指定的Rust版本重新设置toolchain
Flutter编译失败定位到Dart异常Flutter版本不匹配重装源码指定的Flutter版本,或者用fvm切换
磁盘空间不足RustDesk编译产物很大,release目录加中间产物可能占用几十GB留足50GB以上空间再开始

关于编译时间,第一次编译大概率跑15到30分钟,别中途掐断,尤其是最后链接阶段,看似卡住其实是在处理Windows符号。我试过用低配云主机编译,CPU一直在跑但内存不够导致OOM,后来加了swap才过。

5.3 升级与后续维护的几个建议

自建这套东西不是搭完就一劳永逸,后续升级、备份、监控都得跟上。我自己的经验是三个点:

一是把服务器密钥对视为最重要的资产。id_ed25519这个私钥文件,建议额外备份到安全的地方。服务器磁盘坏了不怕,重装系统拉个新hbbs起来,只要把原来的私钥放回去,所有旧客户端依然能连;如果私钥丢了,所有已分发的客户端全部失效,只能重新下发。

二是以后升级RustDesk客户端时,不要只拉代码就编译。先看新版本的源码结构有没有变化,尤其是配置文件的位置和格式。RustDesk版本迭代速度很快,有时新版会引入新的配置方式,旧版修改源码的做法可能不再适用。我的做法是升级前先看GitHub上的release notes,确认没有破坏性变更再动手。

三是考虑用构建脚本把这套流程固化下来。编译一次容易,反复编译就烦了。我把替换服务器地址和key的步骤写成脚本,每次拉完新源码,先跑脚本改配置再编译,输出固定名称的安装包。这样以后每次升级就是“拉代码、跑脚本、编译、打包”四步,省心很多。

最后分享一个小技巧:编译产物在发给别人之前,自己先装一遍,走一遍完整的连接流程再交付。远程桌面软件这东西,自己环境里再正常,换台机器可能就是另一番光景。我印象最深的一次,是编译完觉得万事大吉,结果别人装上后一直提示连接失败,排查了半天才发现是新版客户端默认用了UDP中继,而那家公司的网络策略把UDP全封了。从那以后我再也不偷懒,凡是发出去的包,一定用一条不受控的公网链路完整验证一遍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 22:39:03

基于4300张猫狗数据集的YOLOv8目标检测实战:从标注解析到部署

1. 拿到4300张猫狗图片之后,先想清楚你要用它做什么很多人看到"猫狗检测数据集"这几个字,第一反应就是下载、解压、丢进YOLO里跑一遍,然后看着mAP数字出来就完事了。但我在实际项目里踩过太多次坑之后发现,数据集的价值…

作者头像 李华
网站建设 2026/10/1 22:37:31

Unity与UE5真实对比:选型、迁移与高频踩坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 22:36:39

phpstudy MySQL启动失败排查指南:从日志、端口到数据目录

phpstudy面板上那个MySQL的启动按钮,你点下去,小圆圈转半圈,然后变回红色,或者干脆弹出一个“服务启动失败”的Windows窗体。这个画面我太熟了,不管是帮别人远程看环境,还是自己在不同电脑上配开发环境&…

作者头像 李华
网站建设 2026/10/1 22:35:55

MySQL符号链接安全:默认开启的隐患及彻底禁用指南

去年做安全审计时接手了一台被入侵的 MySQL 服务器。入侵者其实只拿到了一个低权限 Web 应用数据库账号,却差点把服务器上的敏感文件读走。追查之后发现,数据目录里多了一条指向 /etc/passwd 的符号链接,而实例的 symbolic_links 变量还保持着…

作者头像 李华
网站建设 2026/10/1 22:34:44

第9课:Nacos集群高可用部署 生产级故障容灾方案

文章目录一、开篇:单机版Nacos的生产“死穴”二、集群架构设计2.1 官方推荐架构2.2 端口规划三、MySQL数据源配置与初始化3.1 初始化数据库3.2 配置application.properties3.3 集群配置文件cluster.conf3.4 鉴权配置(3.x必配)3.5 JVM参数优化…

作者头像 李华
网站建设 2026/10/1 22:33:38

推理框架与AI编译栈:从PyTorch到高效部署的优化全链路

1. 从“模型能跑”到“模型跑得快”:推理框架到底在解决什么问题先抛一个很常见但容易被忽略的问题:同一个 PyTorch 模型,在开发机上用 GPU 推理可能只要 20 毫秒,换到另一台配置差不多的机器上,却可能要 80 毫秒甚至更…

作者头像 李华