ARTICLE DETAIL

资讯详情

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

RustDesk自建远程方案:编译客户端并固化服务器地址与Key

RustDesk自建远程方案:编译客户端并固化服务器地址与Key 最近又把 RustDesk 的自建链路完整走了一遍服务器端自己编译 hbbs/hbbr客户端也自己编译并且把自建 ID 服务器地址和 key 直接写进了客户端里。折腾完之后最大的感受是一旦服务器和 key 不用手动填整个分发体验完全不一样——给别人发一个安装包对方装上打开就能连你自己的服务器不用解释什么叫 ID 服务器、什么叫 key更不用在多个输入框之间来回切。这篇文章我就把整个过程中我认为最关键的几个环节包括服务端部署、客户端编译、以及三种把服务器信息固化进客户端的方法原原本本记录下来给打算自己搞一套 RustDesk 远程方案的朋友做个参考。1. 为什么非要把服务器和 key 编进客户端不可1.1 公共服务器与自建服务器的差距RustDesk 官方公共服务器对个人偶尔用一下来说是够的但一旦你把它当日常工具问题马上会浮现高峰期连接不稳、跨地域延迟忽高忽低、中继带宽有限。更重要的是数据链路完全不受你控制这对企业用户或者对隐私比较敏感的人来讲始终是个心结。自建之后整套链路都在自己手里客户端向你的 ID 服务器注册身份、两个设备互相发现、中继服务器转发流量全走你自己的机器和带宽。这在企业内网、跨地域小团队、或者单纯喜欢数据可控的个人场景里价值非常明显。1.2 真正的痛点不是部署而是客户端配置服务端部署好之后你自己用很简单填一下地址和 key 就行。但如果你要把客户端分发给同事、客户或者家里好几台设备重装系统问题就来了——非技术用户面对ID 服务器中继服务器Key这几个输入框很容易卡住。key 尤其容易错。它是服务器生成的 ed25519 公钥一长串 base64 字符串复制粘贴时前面多一个空格、或者换行被带进去都会导致连接失败界面上弹出一个很费解的提示。我见到的key 值未知错误多半就是这么来的。1.3 三种写入方式的利弊对比把服务器地址和 key 固化进客户端常见有三条路编译期改默认值、预置配置文件、安装后脚本注入。我分别试过先给个对比。方案侵入性分发体验适用场景编译期改默认值每次升级要重新改最好开箱即用固定服务器的团队长期使用预置配置文件/数据库无拷贝文件即可好但要在首次启动前放好批量机器、临时分发界面手动填写无差依赖使用者操作个人自用、个位数设备实际项目中我倾向于组合使用编译期改默认值解决开箱即用的问题配置文件预置应对那些老版本客户端或者不想重新编译的机器。2. 服务端先行hbbs/hbbr 部署与 key 生成2.1 服务端源码编译RustDesk 的服务端是独立仓库rustdesk-server包含两个核心二进制hbbs是 ID 服务器和信令服务器负责设备注册与连接协商hbbr是中继服务器负责在无法直连时为两端转发流量。编译过程很简单git clone https://github.com/rustdesk/rustdesk-server.git cd rustdesk-server cargo build --release编译产物在target/release/目录下我们需要的是hbbs和hbbr这两个文件。如果你的服务器内存偏小编译时间会比较长建议放到 2G 内存以上的机器上操作或者干脆用官方 release 里的预编译二进制。标题既然讲自己编译这里就走源码编译路线。2.2 首次运行生成 key把hbbs、hbbr放到服务器的固定目录比如/opt/rustdesk-server/然后第一次启动cd /opt/rustdesk-server ./hbbs -r your-server.com:21117 ./hbbr第一次运行后目录下会生成id_ed25519和id_ed25519.pub两个文件。id_ed25519.pub里的内容就是客户端设置界面需要填的那个 key。这串公钥相当于服务器身份凭证客户端拿着它才能确认自己连的服务器确实是你搭的那台防止中间人冒充。这里有一个非常容易踩的坑id_ed25519私钥必须备份好并且不要随意删除。一旦服务端目录被清空导致重新生成密钥所有已经配置好的客户端都会弹出 key 不匹配的提示全部要重新改配置相当痛苦。2.3 端口清单与防火墙放行服务端需要放行的端口有规律整理成一张表方便对照端口协议用途21115TCPNAT 类型检测21116TCP UDP客户端注册与信令交换UDP 为主21117TCPhbbr 中继数据传输21118TCPWeb 客户端支持可选21119TCPWeb 中继支持可选如果你在云服务器上部署除了服务器本身的防火墙iptables/firewalld/ufw还要检查云控制台的安全组规则两个地方都得放行。国内用户如果喜欢用宝塔面板也要在面板防火墙里同步放行这些端口不然客户端能 ping 通机器但连接总是超时。2.4 用 systemd 守护进程nohup ... 在调试阶段没问题但生产环境我更推荐用 systemd 托管防止进程挂掉后没人管。写两个 service 文件分别守护hbbs和hbbr启动命令里带上-r参数指定中继地址并设置开机自启。# /etc/systemd/system/rustdesk-hbbs.service [Unit] DescriptionRustDesk ID Server Afternetwork.target [Service] Typesimple WorkingDirectory/opt/rustdesk-server ExecStart/opt/rustdesk-server/hbbs -r your-server.com:21117 Restartalways RestartSec3 [Install] WantedBymulti-user.targethbbr的 service 文件照葫芦画瓢ExecStart 换成/opt/rustdesk-server/hbbr即可。3. 客户端编译环境版本选型与依赖准备3.1 RustDesk 客户端的两个时代RustDesk 客户端源码变化很大网上教程用的是老版本v1.1.xSciter UI而现在已经普遍切换到 Flutter UI 的新版本v1.2、v1.3。两代产品的编译方式和源码路径都不一样如果你跟着老教程走很可能会卡在某一步找不到对应文件。我的建议是直接用当前官方 release tag比如 v1.3.x不要盲目追 master。master 分支处于持续开发状态今天能编译明天可能因为一个依赖变更就报错。锁定稳定版本遇到问题也好查。git clone https://github.com/rustdesk/rustdesk.git cd rustdesk git checkout v1.3.x3.2 Linux 编译环境在 Linux 下编译 Linux 客户端需要准备 Rust 工具链和一堆系统依赖。Rust 安装用 rustup 官方脚本即可curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh系统库方面Ubuntu/Debian 系大致需要这些sudo apt install build-essential pkg-config cmake git \ libgtk-3-dev libssl-dev libasound2-dev libavcodec-dev \ libavformat-dev libavutil-dev libswscale-dev \ libx11-dev libxext-dev libxinerama-dev libxcursor-dev \ libxdamage-dev libxfixes-dev libxi-dev libxkbcommon-dev \ libvpx-dev libopus-dev不同版本的依赖列表会变最权威的还是仓库里的 README 和build.py脚本。我的经验是把build-essential、pkg-config、libssl-dev、libgtk-3-dev这几个装好大部分编译错误就能消掉一半。3.3 Windows 编译环境Windows 下编译 Windows 客户端条件会多一点安装 Visual Studio Build Tools 2019 或 2022勾选使用 C 的桌面开发工作负载。安装 Rust 的 MSVC 工具链。安装 vcpkg并配置VCPKG_ROOT环境变量。通过 vcpkg 安装 RustDesk 依赖的 C 库比如libvpx。git clone https://github.com/microsoft/vcpkg.git cd vcpkg .\bootstrap-vcpkg.bat .\vcpkg install libvpx:x64-windows-static $env:VCPKG_ROOT C:\path\to\vcpkg在 Windows 上最稳妥的编译方式是用x64 Native Tools Command Prompt for VS打开终端再执行 cargo 命令。否则容易遇到link.exe找不到的问题。3.4 新版 Flutter UI 的额外步骤如果你拉取的是 Flutter UI 版本编译时还需要 Flutter SDK。桌面客户端通常是先编译 Rust 核心再构建 Flutter 界面层。手动步骤繁琐官方提供了build.py脚本建议直接用python build.py --flutter --release这个脚本会处理 Rust 和 Flutter 两部分的构建并且自动把它们打包成安装包。如果你想验证自己的代码修改也可以先只跑cargo build --release构建单独的 Rust 可执行文件。4. 把 ID 服务器和 key 写进客户端的三种做法4.1 做法一编译期改默认常量这是最彻底的方案也是标题里说的写入客户端的标准做法。思路很简单RustDesk 客户端源码里必然存在一组默认服务器地址和默认 key程序首次启动时会读这些默认值。我们只要把它们改成自己的服务器和公钥就行。问题是不同版本的源码位置差别很大不能直接告诉你改哪个文件。我提供的通用定位方法是用 grep 搜索# 在 RustDesk 客户端源码根目录执行 grep -rn rustdesk.com --include*.rs src libs 2/dev/null grep -rn rendezvous --include*.rs -i src libs 2/dev/null在 v1.1.x 时代常见位置是src/common/constants.rs里面会有一个类似RENDEZVOUS_SERVER的常量。在较新的版本中这些默认值可能挪到了libs/hbb_common/src/config.rs之类的地方。找到之后把默认服务器地址改成你自己的域名或 IP把默认 key 改成id_ed25519.pub的内容。下面是一个示意性的修改片段不同版本字段名和路径可能不同核心思路是一样的// 示意代码实际位置以你搜索到的源码为准 pub const RENDEZVOUS_SERVER: str your-server.com; pub const KEY: str 你的 ed25519 公钥字符串一长串 base64;改完重新编译客户端一启动就会拿这些值去连接你的服务器。这里有个非常关键的前提目标机器上不能有旧的 RustDesk 配置。如果客户端已经运行过一次本地存储的配置优先级高于编译期默认值你改半天编译配置也不会生效。测试时要把~/.config/rustdeskLinux或%APPDATA%\RustDeskWindows删掉再启动。4.2 做法二预置配置文件编译期改默认值有个问题每次升级版本都要重新改、重新编译。如果你只是想快速批量设置一批机器配置文件预置法更省事。具体流程是这样的准备一台干净的测试机安装官方或自编译的客户端。打开设置界面手动填入 ID 服务器地址、中继服务器地址和 key确认能正常连接。关闭客户端找到配置文件。Windows 在%APPDATA%\RustDesk\Linux 在~/.config/rustdesk/。把里面保存服务器信息的文件通常是RustDesk.toml或类似配置复制出来作为模板。这里必须提醒一个非常容易翻车的细节不要整个配置目录都拷走。config下还有id_ed25519和id_ed25519.pub那是客户端自己的身份密钥如果每台机器都用同一份后果就是所有设备共享同一个设备 ID互相抢注册连接会变得一团乱。另外数据库文件包含地址簿等隐私数据也不适合批量分发。正确的做法是只提取跟服务器、key 相关的配置内容或者干脆把配置好的内容做成一个批处理/Shell 脚本在客户端首次运行前写入目标机器的配置目录。Windows 下大致是这样一个思路echo off mkdir %APPDATA%\RustDesk\config 2nul echo [options] %APPDATA%\RustDesk\config\RustDesk.toml echo custom-rendezvous-serveryour-server.com %APPDATA%\RustDesk\config\RustDesk.toml echo keyyour-public-key %APPDATA%\RustDesk\config\RustDesk.toml字段名还是那句话以你实际配置生成的真实文件为准不要照抄网上任何一个模板。每个版本的存储结构都可能调整最稳的方法永远是先手动配置再复制真实内容。4.3 做法三安装后脚本注入做法三适合已经装好客户端、跑过几次但配置不对的场景。它的本质跟做法二差不多只是把写入配置的时机从首次启动前挪到安装之后。可以用批处理脚本、PowerShell 脚本或者组策略来推送配置文件。如果你管理了一批已然运行过客户端的电脑删配置目录会影响它们的设备身份所以我不建议直接删了重来而是只更新配置文件里服务器和 key 相关的条目然后重启客户端。这种方式的好处是不用重新编译坏处是命令行里写明文 key脚本本身的保管要注意权限别让无关人员看到你的服务器公钥和地址。其实公钥本身不算敏感但配合服务器地址暴露在公网上容易被别人扫描利用后面讲安全时再说。4.4 我的选择编译期为主配置兜底三种方式按实际使用场景分开自己主力机、给家人朋友分发编译期改默认值一劳永逸。给公司同事批量部署预置配置脚本推送节省重编译成本。临时帮别人调一下远程指导手动填或者脚本修一下配置。我最推荐的组合是编译期默认值 配置文件双保险。编译期保证全新安装的机器开箱即连配置文件应对那些需要差异化覆盖的单台机器。5. 完整编译流程与实测记录5.1 Linux 下编译 Linux 客户端我在一台 Ubuntu 22.04 机器上完整跑过一次记录一下流程# 1. 安装系统依赖 sudo apt update sudo apt install build-essential pkg-config cmake git \ libgtk-3-dev libssl-dev libasound2-dev libavcodec-dev \ libavformat-dev libavutil-dev libswscale-dev \ libx11-dev libxext-dev libxinerama-dev libxcursor-dev \ libxdamage-dev libxfixes-dev libxi-dev libxkbcommon-dev \ libvpx-dev libopus-dev # 2. 安装 Rust curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh source ~/.cargo/env # 3. 拉源码并切换到稳定版本 git clone https://github.com/rustdesk/rustdesk.git cd rustdesk git checkout v1.3.x # 4. 修改默认服务器地址和 key按第四章做法一 # 5. 编译 cargo build --release编译产物在target/release/rustdesk。首次编译时间比较长取决于机器性能二十分钟到一小时都正常建议耐心等不要中途 CtrlC。我看到很多新手在编译时看到一长串 warning 就以为报错了其实只要最后没有error字样就是成功。在启动自己编译的客户端之前务必先清理旧配置rm -rf ~/.config/rustdesk然后运行./target/release/rustdesk打开设置界面就能看到服务器地址已经变成了自己填的那个。5.2 Windows 下编译 Windows 客户端Windows 编译流程我在一台 Windows 11 机器上跑过。重点是要用 VS 的开发者命令行否则后面链接阶段会找不到环境变量。git clone https://github.com/rustdesk/rustdesk.git cd rustdesk git checkout v1.3.x # 设置 vcpkg 环境变量如果还没设置 $env:VCPKG_ROOT C:\vcpkg # 编译 cargo build --release编译产物在target\release\rustdesk.exe。如果是 Flutter UI 版本可以先执行python build.py --flutter --release最终产物在target\release\下。5.3 我踩过的编译错误把几个典型报错和处理方式整理出来应该能帮大家省不少时间。错误现象原因解决办法link.exe not found或找不到 MSVC 链接器没有使用 VS 开发者命令行打开 x64 Native Tools Command Prompt 再执行 cargovcpkg 安装依赖超时失败网络原因或依赖较多重试必要时配置镜像源OpenSSL 头文件找不到缺少libssl-dev/pkg-configLinux 安装libssl-devWindows 通过 vcpkg 安装 opensslFlutter 构建报错或卡住Flutter 版本不一致或依赖未拉取执行flutter upgrade flutter pub get磁盘空间不足Rust 编译缓存很大清理target目录或用外置盘做编译还有一个通用建议编译这类大型 Rust 项目把CARGO_HOME和target目录放到空间充足的磁盘上SSD 优先。机械硬盘编译 RustDesk 会让人怀疑人生。5.4 验证编译产物确实写入了默认配置编译完成后怎么确认默认值真的生效可以先用一个干净环境运行客户端然后直接看设置界面显示的是不是你自己的服务器。更快的办法是在源码里搜索替换后的字符是否还在grep -rn your-server.com target/release/ 2/dev/null不过二进制里字符串不一定明文可见最靠谱的还是实机验证。我自己的测试流程是清空配置目录、启动客户端、观察日志、开两台设备实际连一次。两台设备建立连接的那一刻整套方案才算真正跑通。6. 上线后的排查手段与安全边界6.1 key 值未知的完整排查链路这个报错可能是 RustDesk 自建玩家最常见的求助热点。所谓key 值未知本质是客户端本地保存的 key 和服务器实际公钥对不上。排查链路按顺序走一遍登录到服务器进入 hbbs 部署目录用cat id_ed25519.pub查看当前公钥。在客户端设置界面把 key 更新为刚才看到的完整字符串。复制时注意开头结尾有没有多出空格、是不是被换行截断了。如果更新后仍然报错关闭客户端删除本地配置目录再重新启动输入。如果服务器有多台实例、或者曾经把旧目录拷贝过确保客户端连的确实是生成这份公钥的那台机器。我遇到最多的情况是服务端透过宝塔或者其他面板重启过目录被重建密钥重新生成了客户端还拿着旧 key 在连接。备份的重要性在这里体现得很充分。6.2 连不上 ID 服务器时的排查链路客户端如果一直显示无法连接服务器不要急着怀疑源码。按这个顺序查检查端口是否可达nc -z -v your-server.com 21115 nc -z -v your-server.com 21116 nc -z -v your-server.com 21117检查服务器防火墙ufw status或firewall-cmd --list-all确认 21115-21119 已放行。检查云安全组很多云厂商的安全组默认全关单独放行端口才有效。查看 hbbs 日志启动 hbbs 时不要加--quiet日志里会打印客户端注册、注册失败的详细信息。有个容易被忽略的坑21116 端口同时需要 TCP 和 UDP 放行。很多网络环境只放行 TCP客户端能完成一部分握手但后续的 UDP 通信直接被丢现象就是反复超时。6.3 中继服务器不转发的几个原因两台设备无法直连时流量会走 hbbr。中继不工作现象是对方设备一直显示连接中然后失败。常见原因21117 端口没放行客户端与 hbbr 建立不了连接。客户端填的中继服务器地址不对。新版客户端可以单独设置中继服务器务必和 hbbs 的-r参数保持一致。hbbr 进程没起来或死循环了。ps aux | grep hbbr看一眼配合 systemd 的Restartalways解决。如果确认端口和进程都正常用两台不同网络环境比如一个在移动网络、一个在宽带的设备再测一次很多时候是测试环境里两台机器其实可以直连流量根本没走中继导致你以为中继坏了。6.4 安全边界与隐私保护RustDesk 的 key 机制需要澄清一个概念key 是服务器身份公钥不是访问密码。拿到服务器地址和公钥的人可以尝试向你的 ID 服务器注册自己的设备所以服务器暴露在公网上时必须有额外的保护意识。几个我自己长期在用的安全习惯id_ed25519私钥视为最高机密绝不公开、不随客户端分发。如果条件允许在服务器防火墙层面限制来源 IP。只给自己固定出口 IP 放行 21115-21119能挡掉大量扫描。每台被控设备设置强访问密码。这是连接设备时真正起拦截作用的凭证。定期备份 hbbs 部署目录。密钥丢了或变了所有客户端都要重新配置代价太大。域名和服务器 IP 尽量不要频繁变更。客户端里写死的地址一旦变更同样需要重新配置。6.5 顺手还能改的客户端名称与图标既然已经走到编译客户端这一步很多人会顺手把软件名称、图标一起改掉让整个工具看起来更像自家产品。这个需求一般涉及资源文件和界面文案Windows 图标和版本信息在.rc资源文件里Flutter UI 的文字在flutter/lib/下的源码里。改起来不难但每次升级版本都要维护一份 patch个人自用的话自己权衡一下值不值。最后的几点体会把服务器地址和 key 编进客户端这个事真正做起来比想象中简单难点反而在版本差异的适配和旧配置的清理上。我个人现在已经养成了习惯拿到新版本源码先 grep 默认服务器常量的位置改完再编译同时保留一份配置文件模板用于那些没法重编译的环境。整套方案跑顺之后RustDesk 的使用体验基本可以做到发给别人就用不用任何解释。最后再提醒一句最关键的话服务器端id_ed25519私钥千万保管好丢一次所有客户端的 key 都要跟着重配那种批量改配置的酸爽体验过一次就再也不想体验第二次了。
返回列表