ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

RustDesk自建服务器完整指南:用Docker部署hbbs与hbbr实现私有远程控制

RustDesk自建服务器完整指南:用Docker部署hbbs与hbbr实现私有远程控制 在很多实际场景里远程控制的痛点并不是“连不上”而是“连接链路不受自己控制”。RustDesk 之所以被大量团队和个人使用核心原因是它把远程控制的几个关键环节也就是身份注册、连接协调、数据中继都拆成了可以自托管的组件。RustDesk 自建服务器后客户端访问的 ID 服务器和中继服务器都在自己的机器上网络拓扑、端口、加密密钥和带宽策略都可以自己决定这是商业远程软件账号体系里很难做到的。这篇文章会围绕一条完整的技术主线展开先理解 RustDesk 自建方案涉及的 hbbs、hbbr 和 Key 机制然后用 Docker 在一台 Linux 服务器上搭建服务器端再完成 Windows 和 Android 客户端的连接配置最后给出安全加固、常见问题排查和一份生产可用的检查清单。整个过程偏工程落地适合需要在局域网或公网环境部署远程控制服务、同时又希望数据和连接记录不经过第三方中继的开发者。1. 远程控制方案为什么要走“自建服务器”这条路1.1 远程控制的基本工作方式远程控制软件连接两台设备时真正解决的问题不只是“把画面传过去”而是先要让两台设备互相找到对方。大多数设备处于 NAT 后面没有公网 IP也没有办法直接被另一端发起连接。为了完成这个流程软件至少需要三种角色被控端和主控端安装的客户端程序一个负责注册设备 ID、协调连接建立的服务器一个在无法直接穿透时帮忙转发数据的服务器。商业远程控制软件把这三种角色都做成了封闭服务。客户端把设备 ID 和密钥交给厂商服务器连接时由厂商服务器完成匹配通信数据如果需要中继也通过厂商提供的中继节点转发。好处是用户开箱即用坏处是控制链路的数据路径完全不可见连接质量也依赖厂商节点的位置和带宽策略。1.2 RustDesk 的定位让核心链路变成开源组件RustDesk 是一个用 Rust 编写的开源远程控制项目源码主要在 rustdesk/rustdesk 仓库中维护。它不是一个只提供客户端的软件而是把服务器端也开源了。部署者可以自己运行两个服务端进程hbbs 和 hbbr。hbbs 的全称可以理解为 ID/rendezvous 服务器负责处理设备 ID 注册、心跳、P2P 连接协商以及提供中继服务器地址。hbbr 是中继服务器负责在双方无法进行点对点连接时转发加密数据。这里的思路和商业方案的区别很大商业软件把服务端当成核心商业资产而 RustDesk 允许任何人都可以把服务端跑在自己的服务器上客户端只把服务器地址和公钥配置成本地参数就能绕过官方公共服务器。1.3 自建与使用公共服务器的差异学习阶段可以直接使用 RustDesk 官方公共服务器测试只要安装客户端就能用。但在以下场景中自建服务器的价值立刻体现出来内网设备必须能注册到固定的房间服务器而不是依赖公共节点的可达性需要控制连接流量走自己的服务器或自己的带宽出口需要对服务器密钥、端口、防火墙策略做统一管理希望远程连接过程中的请求记录只落在自己手里有离线或隔离网络环境需要完全内部署。自建服务器的代价是需要一台带宽稳定的 Linux 主机并且要处理端口放行、进程守护、密钥保存和版本升级。本文后续的操作都以“自建一套自己的 RustDesk 服务器并把客户端全部切到自建地址”为目标。2. 部署前先理解 hbbs、hbbr 和 Key 机制2.1 两个服务端进程分别承担什么职责RustDesk 服务端的部署并不是要运行一个完整 Web 应用而是运行 hbbs 和 hbbr 两个原生进程。理解这两个进程后面排查连接失败时会容易很多。hbbs 的作用偏向“控制面”。设备客户端启动时会拿着自身的 ID 和密钥去连接 hbbs并持续发送心跳。当一台设备请求连接另一台设备时hbbs 负责判断被控设备是否在线把连接请求转发给被控端并帮助双方交换打洞所需的信息。hbbr 的作用偏向“数据面”。当主控端和被控端尝试 UDP 打洞失败或者网络环境不允许点对点直连时两个客户端会把数据发送到 hbbr由 hbbr 做中继转发。数据链路是否经过 hbbr只有在无法建立点对点连接时才启用。部署时要避免把 hbbs 和 hbbr 当成一个整体黑盒。如果设备能注册但画面一直卡在连接中问题常常出在 hbbr 端口或中继地址配置上。2.2 Key 文件与加密机制服务器第一次启动时会生成一组id_ed25519和id_ed25519.pub位于 hbbs 的工作目录中。这组密钥不是用于用户登录的账号密码而是用于客户端和服务端之间的通信加密身份确认。客户端配置里需要填写的 Key就是id_ed25519.pub文件里的内容。客户端连接服务器时会通过这个公钥对通信内容进行加密协商并确认自己连接到的服务器确实是部署者预期的实例而不是伪造的中间节点。这个设计容易误解的地方在于Key 只解决服务器身份和通信加密问题不解决业务层面的“谁能控制谁”。业务授权仍然靠被控端设置的连接密码或访问权限不能因为 Key 配置正确就认为任何人无法连接。2.3 端口清单和放行策略部署前需要先规划端口。RustDesk 常见使用的端口如下端口协议服务用途21115TCPhbbsNAT 类型探测21116TCPhbbs设备注册、心跳、连接协商21116UDPhbbsNAT 穿透的 UDP 打洞21117TCPhbbr中继数据转发21118TCPhbbsWeb 客户端连接21119TCPhbbrWeb 客户端中继很多部署失败不是服务端没启动而是云服务器安全组只放行了 TCP 端口忘记了 21116 的 UDP。没有 UDP 端口客户端虽然能注册但往往无法成功打洞表现为连接时长时间转圈然后超时。2.4 需要区分的学习环境和生产环境如果只是在局域网里测试可以先把所有端口放开把 hbbs 和 hbbr 直接跑在宿主机的默认端口上客户端填局域网 IP 即可。进入公网生产环境后端口策略要收敛部署方式要从“临时启动进程”调整为“容器或 systemd 托管”。密钥一定要持久化保存不能每次容器重建都生成新的密钥否则所有客户端都要重新填写 Key。3. 在一台 Linux 服务器上搭建 RustDesk 服务端3.1 环境准备和基础检查建议使用一台 Linux 主机云服务器或内网物理机都可以。最小配置建议为 1 核 1GB实际远程控制的中继负载主要受带宽影响CPU 和内存压力相对可控。操作系统建议使用 Ubuntu 22.04、Debian 12 或兼容版本。开始操作前先检查 Docker 是否已安装并启动docker --version docker compose version如果没有安装 Docker可以按当前系统的官方文档安装再确认当前用户是否能执行 docker 命令。为了避免权限问题可以把当前用户加入 docker 组sudo usermod -aG docker $USER newgrp docker然后检查公网地址或可被客户端访问的内网地址ip addr curl ifconfig.me如果服务器有防火墙要提前确认端口放行状态。Ubuntu 下使用 ufw 时的相关命令如下sudo ufw allow 21115/tcp sudo ufw allow 21116/tcp sudo ufw allow 21116/udp sudo ufw allow 21117/tcp在云服务商控制台的安全组中也要执行同样的放行操作。这一步经常被忽略尤其安全组和系统防火墙双层规则同时存在时只改其中一层并不能真正放行端口。3.2 用 Docker Compose 同时部署 hbbs 和 hbbrRustDesk 官方镜像在 Docker Hub 上可以获取推荐使用 Docker Compose 统一管理两个服务。因为 hbbs 启动时需要知道中继服务器 hbbr 的地址所以要把公网 IP 或域名传给 hbbs。下面是一份适合多数 Linux 环境的docker-compose.yml示例version: 3 services: hbbs: image: rustdesk/rustdesk-server:latest container_name: rustdesk-hbbs restart: unless-stopped command: hbbs -r your-public-ip:21117 volumes: - ./data:/root network_mode: host hbbr: image: rustdesk/rustdesk-server:latest container_name: rustdesk-hbbr restart: unless-stopped command: hbbr volumes: - ./data:/root network_mode: hostcommand中的your-public-ip要替换成客户端能访问到的地址。如果通过域名连接可以填域名例如hbbs -r relay.example.com:21117network_mode: host让容器直接使用宿主机网络适用于 Linux 上的 Docker。这样 hbbs 和 hbbr 不会互相抢占端口映射也能避免容器 IP 变化带来的地址漂移问题。使用 Docker Desktop 的 Windows 或 macOS 环境不支持 host 模式需要改成 ports 映射但生产服务器通常是 Linuxhost 模式更直接。配置文件准备好后在目录下执行docker compose up -d查看进程状态docker compose ps正常状态下hbbs 和 hbbr 都应该是Up状态。3.3 密钥文件和工作目录服务第一次启动后会在宿主机当前目录下的data目录中生成密钥文件和其他数据文件。查看文件列表ls -la ./data关键文件是id_ed25519服务器私钥必须妥善保存不要提交到代码仓库id_ed25519.pub服务器公钥客户端配置时需要使用RustDesk.toml服务器运行时写入的配置信息。在 host 网络模式下hbbs 和 hbbr 共享同一个数据目录即可。容器重建后只要数据目录还在密钥不会变化客户端不需要重新配置 Key。查看日志时使用docker logs rustdesk-hbbs docker logs rustdesk-hbbrhbbs 启动日志中通常会出现服务器公钥信息。如果日志里没有可以直接读取公钥文件cat ./data/id_ed25519.pub这一行字符串是后面客户端配置里的 Key。3.4 不使用 host 网络时的端口映射写法如果部署平台不支持 host 模式例如某些容器平台或 Windows Docker Desktop需要把端口显式映射出来。此时 hbbs 和 hbbr 分别使用不同的容器并需要保证它们之间能通过宿主机的 21117 端口通信。一份不使用 host 网络的示例version: 3 services: hbbs: image: rustdesk/rustdesk-server:latest container_name: rustdesk-hbbs restart: unless-stopped command: hbbs -r your-public-ip:21117 volumes: - ./data:/root 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: - ./data:/root ports: - 21117:21117 - 21119:21119这种配置下hbbs 启动时通过your-public-ip:21117告诉客户端去访问中继服务器。命令里的地址不一定是服务器本机地址而是客户端最终能访问到的公网地址或域名。3.5 服务端部署完成后的检查点服务端是否准备完成不能只看容器状态还需要检查端口监听情况。在宿主机上执行ss -lntup | grep -E 21115|21116|21117能看到 21115、21116、21117 端口在监听说明核心服务已经启动。如果再检查 UDP 端口ss -lunp | grep 21116确认 21116/udp 也有监听NAT 穿透的基础条件才具备。最后用客户端连接测试如果客户端能拿到设备列表并看到在线状态说明 ID 服务器通信正常。4. Windows 和 Android 客户端的连接配置与验证4.1 客户端设置面板的理解RustDesk 客户端安装完成后默认连接的是官方公共服务器。切到自建服务器时需要在客户端设置中找到网络配置区域。先看主界面。主界面左侧显示出本机的 ID 和临时密码这个 ID 是客户端根据设备信息生成的唯一标识注册到服务器后可以在列表中被其他设备看到。连接别人时只需要输入对方 ID 和密码即可发起请求。要把客户端切到自建服务器需要在设置里找到 “ID/Relay Server” 选项展开后填写三项内容ID 服务器地址Relay 服务器地址Key 值。ID 服务器地址通常填写部署服务器的公网 IP 或域名。如果不写端口客户端默认使用 21116。Relay 服务器地址填写同一台服务器的地址默认端口是 21117。Key 值填写id_ed25519.pub文件的内容。4.2 Windows 客户端的配置步骤安装好 Windows 客户端后依次打开“设置 - 网络”取消勾选自动选项手动填写ID 服务器123.45.67.89或rustdesk.example.comRelay 服务器123.45.67.89或rustdesk.example.comKey从服务器公钥文件复制出来的字符串这里有一个常见误区Relay 服务器地址可以不填客户端会通过 hbbs 拿服务器下发的中继地址。但在自建场景下如果 hbbs 启动参数里没有正确传入-r参数中继地址可能没有配置所以最稳妥的做法是 ID 和 Relay 都填同一个自建地址。保存后观察主界面是否能正常显示本机在线状态。可以查看 RustDesk 日志或网络连接状态确认客户端是否已成功连接 21116 端口。4.3 Android 客户端与系统安装限制Android 客户端通常以 APK 形式分发。在侧载安装时不同 Android 系统会有不同的安全策略部分新版本系统会对“未知来源应用”进行额外提醒这是系统主动保护机制并非 RustDesk 本身的问题。面对这类提示不建议修改系统级安全开关或禁用系统保护策略。正常的处理方法有以下几种优先从 RustDesk 官方发布渠道或对应的应用商店下载签名一致的版本如果系统允许在系统设置的“允许安装未知应用”中对文件管理器或浏览器单独授权这是 Android 的标准侧载流程如果设备管理策略明确禁止安装侧载应用应该联系设备管理员申请白名单而不是寻找绕过安装限制的方法安装后如果还提示签名校验失败说明下载来源与系统已有包签名不一致需要卸载后从正规渠道重新下载。Android 客户端配置自建服务器的方式与 Windows 一致填写相同地址和 Key 即可。需要注意的是移动网络环境下的 NAT 穿透能力更弱如果连接失败优先检查服务器 UDP 21116 和中继端口 21117 是否开放。4.4 多客户端连接验证自建服务器配置完成后最好准备两台设备做交叉验证。比如用一台 Windows 作为被控端用另一台 Windows 或 Android 手机作为主控端。验证流程被控端打开 RustDesk记录本机 ID 和临时密码在主控端输入被控端 ID点击连接输入被控端显示或预先设置的密码观察画面是否能正常显示鼠标键盘操作是否响应断开后重新连接确认密码和地址配置已保存。连接过程中如果能看到桌面画面但操作有延迟通常是因为走了中继链路。此时需要检查网络环境和 P2P 打洞是否成功。RustDesk 客户端连接成功后通常可以在会话窗口查看到连接方式如果显示为直连说明 UDP 打洞成功如果显示中继则数据在走 21117 端口转发。4.5 客户端配置常见错误错误现象可能原因处理方法客户端一直显示离线ID 服务器地址填错或 21116 被防火墙拦截检查地址和端口用 telnet 测试 TCP 21116能看到对方在线但连接一直转圈中继服务器地址缺失或 21117 不通确认 Relay 地址填写正确放行 21117连接时报“密钥不匹配”Key 没有填写或与服务器不匹配重新读取服务器公钥文件并填入客户端UDP 通道无法打洞服务器 21116/udp 未放行检查安全组和系统防火墙的 UDP 规则密码输入后反复提示错误临时密码已过期或被控端设置了固定密码使用被控端当前显示的密码或重置固定密码5. 安全加固与生产环境注意事项5.1 收缩端口暴露面很多部署样例为了省事会把 21118、21119 也都开放。实际上这两个端口主要用于 Web 客户端场景如果业务只使用 Windows、macOS、Linux 和 Android 客户端不需要 Web 连接可以不在安全组里放行。放行原则是“按业务需要最小开放”使用场景需要放行的端口桌面和移动客户端远程控制21115/tcp、21116/tcp、21116/udp、21117/tcp需要使用 Web 客户端额外放行 21118/tcp、21119/tcp只在局域网内部使用配置内网防火墙规则不对公网开放公网环境下建议不要直接把服务器上的所有端口对公网开放。可以通过云安全组把端口来源限制成公司出口 IP 或已知的办公网段。如果 RustDesk 服务只服务少量固定设备这种做法能明显降低被扫描探测的风险。5.2 密钥文件管理和备份hbbs 工作目录中的id_ed25519私钥属于核心敏感文件。丢失私钥虽然不会导致已经安装的客户端立刻断开但如果需要迁移服务器新的服务器会生成新密钥所有客户端都需要重新配置 Key工作量和风险都比较大。建议把这些文件放进单独目录并通过脚本或备份工具定期备份。备份时不要只复制公钥要把整个data目录一起备份。如果容器重启后生成了新密钥先检查是不是挂载目录配置错了数据目录没有持久化。5.3 固定密码与访问策略RustDesk 的临时密码适合短时间操作生产环境中的被控端建议设置固定密码或者在每次远程操作后主动修改密码。密码不要使用过于简单的组合远程桌面软件被爆破的风险在公网环境中真实存在。对于需要限制访问来源的场景可以结合防火墙层做来源 IP 白名单而不是只依赖 RustDesk 自身的密码。RustDesk 自身的控制逻辑以设备密码为主不提供类似企业级 AAA 的细粒度用户体系因此在多用户生产环境中需要额外规划网络层面的访问控制。5.4 定期更新和版本兼容RustDesk 迭代速度不慢服务端和客户端版本如果相差太大可能出现协议层不兼容导致注册失败或连接异常。生产环境建议固定使用一套经过验证的版本组合不要在生产服务器上频繁执行latest镜像更新除非已经先在测试环境验证过。更新流程建议按以下顺序执行备份容器数据目录在测试服务器拉取新镜像并验证客户端连接确认客户端配置无需变更再在生产服务器执行docker compose pull和docker compose up -d更新后检查密钥文件没有变化。镜像标签尽量从latest改为具体版本便于回滚。回滚时同样保留数据目录直接切回旧镜像即可。6. 常见问题排查链路6.1 从现象倒推根因RustDesk 连接失败时先不要急着重装客户端应该按现象定位。常见现象排序可以这样考虑客户端是否显示在线能看到对方但不能连接连接后画面卡顿或直接断开。每一步对应不同的链路。第 1 步失败先查 hbbs 和 21116第 2 步失败查中继和密钥第 3 步查带宽、网络稳定性和 UDP 打洞是否成功。6.2 ID 注册不上设备一直处于离线状态先确认客户端是否填了正确的 ID 服务器地址地址是否可解析。从客户端所在机器上测试到服务器的网络连通性telnet server-ip 21116如果连接超时检查服务器防火墙和云安全组。如果 TCP 能通但设备仍离线继续看 hbbs 日志docker logs rustdesk-hbbs --tail 100日志里出现大量连接拒绝或超时记录时查看是不是服务器连接数限制或输出带宽跑满。6.3 能看到对方但连接不上能显示在线说明设备已经通过 hbbs 完成注册问题通常出在连接协商或数据转发环节。检查顺序被控端是否允许被连接是否设置了密码主控端填写的被控端 ID 是否准确中继服务器地址是否填写正确21117 端口是否放行hbbr 是否正常运行。本机检查命令telnet server-ip 21117连接不上时看日志docker logs rustdesk-hbbr --tail 100日志中如果显示有客户端进入但没有后续数据多半是中继地址没有正确返回或 UDP 端口被限制。6.4 连接时报“密钥不匹配”这个错误和网络通信无关是客户端拿到的服务器公钥和服务端实际公钥不一致。常见原因有三个客户端 Key 填错客户端配置的是另一个服务器的密钥服务器数据目录在容器重建后被清空重新生成了密钥。排查方法cat data/id_ed25519.pub将输出内容和客户端设置面板中的 Key 进行逐字符对比注意不要包含多余换行或空格。如果服务器密钥被动过需要把所有客户端的 Key 统一更新否则旧客户端无法连接。6.5 局域网连接正常公网连接卡顿这种问题通常不是功能故障而是网络链路被拉长或走了中继。公网远程控制时两端之间的传输路径由 ISP 决定RustDesk 只能根据网络状态选择 P2P 或中继。常见原因是服务器本身位于某云厂商机房客户端从另一个网络接入时P2P 打洞失败所有流量全部走 hbbr 中继。此时中继服务器所在的带宽决定了体验。要提升画质需要先看本地上行带宽、服务器带宽和两端之间的实际 RTT。6.6 完整排查清单检查项命令或位置预期结果服务端进程状态docker compose pshbbs/hbbr 均为 UpTCP 21116ss -lntup端口监听中UDP 21116ss -lunp端口监听中TCP 21117从客户端机器执行telnet可以建立连接密钥文件cat data/id_ed25519.pub与客户端填写的 Key 一致hbbs 日志docker logs rustdesk-hbbs无明显连接拒绝hbbr 日志docker logs rustdesk-hbbr有中继连接记录安全组规则云平台控制台21115/21116/21117 已放行系统防火墙sudo ufw status端口规则已放行7. 生产运行最佳实践7.1 发布部署前的检查清单在把 RustDesk 服务端真正用于生产前建议按以下清单逐项核查服务器公网地址是否固定域名解析是否稳定hbbs 启动参数是否已经写入中继地址数据目录是否持久化密钥是否已经备份安全组和系统防火墙是否只放行了必要端口Docker 服务是否设置了开机自启容器是否配置了restart: unless-stopped客户端是否使用固定密码或已有密码管理方案是否记录了部署当前使用的镜像版本号是否准备了回滚方案包括旧镜像标签和数据备份位置是否配置了资源监控防止带宽或连接数异常增长。这份清单适用于第一次部署和后续版本升级。每次变更后重新跑一遍能减少很多低级故障。7.2 镜像和服务进程的运维建议RustDesk 服务端进程对资源占用不算高但如果需要长期运行建议单独建立一个部署目录并把 docker-compose.yml、备份脚本和密钥副本分类归档避免和业务项目混在一起。可以考虑把常用运维命令整理成脚本docker compose logs -f hbbs docker compose logs -f hbbr docker compose pull docker compose up -d docker compose down脚本化之后查看日志、升级、回滚都会更可控。生产环境建议定期检查磁盘占用尤其是长时间运行后日志、数据库文件和临时文件都可能在数据目录里增长。7.3 性能优化和带宽注意事项RustDesk 远程控制的实际体验受链路影响较大。P2P 连接不消耗服务器带宽但中继连接会消耗服务器的出口和入口带宽。如果中继用户较多需要评估服务器的带宽上限1 Mbps 带宽只能支持质量较低的单路远程画面10 Mbps 带宽可以支持少量用户的日常运维多人同时中继时需要按并发数计算带宽需求。如果主要场景是服务器运维建议设置较高分辨率但控制帧率。如果主要场景是办公协助画面稳定比高帧率更重要。这些参数可以在客户端连接窗口调整不需要在服务端配置。7.4 后续可以扩展的方向RustDesk 生态不只包含基础远程控制。服务端跑通后可以继续研究以下方向使用域名代替 IP并结合 HTTPS 证书进行更完整的访问方式管理把 RustDesk 服务端集成到内部运维平台通过固定密码和客户端分发方式管理员工电脑为服务端增加监控告警当 hbbs 或 hbbr 容器停止时自动通知在隔离网络中部署完全离线的版本客户端和服务端都不需要访问公网结合系统防火墙和云安全组做好更细粒度的来源访问控制。对大多数团队而言自建 RustDesk 服务器并不是为了节省第三方软件订阅费而是为了把远程控制的入口、中继和密钥掌握在自己手里。部署完成后最值得做的事是维护好密钥备份和版本固定的习惯并定期用另一台设备测试从不同网络发起连接确认自建服务器在真实网络环境下仍然能完成打洞、中继和远控三条链路的完整闭环。
返回列表