自建 RustDesk 进阶篇:把信令和中继藏进 443,

moonjerx
2026-06-20 / 0 评论 / 9 阅读 / 正在检测是否收录...
这是上一篇《自建 RustDesk 服务端的三个容器,到底各干什么?》的续集。建议先看完上一篇,理解 hbbs / hbbr / api 各自的角色,这篇会直接用到。

上一篇结尾留了个尾巴:在跨境(比如大陆访问香港节点)场景里,RustDesk 的默认信令端口 21116 容易被链路上的设备做 RST 干扰,导致服务器一切正常、端口看着也通,但主控端就是连不上

当时给的应急办法是换端口(21116 → 31116 之类)。它的问题在于:

  • 如果干扰是按端口号识别的,换个端口能躲一阵;
  • 但如果是按协议特征(DPI) 识别的,换端口只是续命,过几天新端口照样被追上。

这篇讲根治方案:把 hbbs 的信令和 hbbr 的中继,全部塞进 443 端口的 TLS 加密流量(WSS) 里。


一、为什么 443 + WSS 能根治

核心就一句话:让你的远控流量,在链路上看起来和访问一个普通 HTTPS 网站一模一样。

  • 躲开端口特征:对外只暴露 443,没有 21116、21117 这些一眼就知道是远控的"特征端口"。
  • 躲开协议特征(DPI):流量被 TLS 加密,中间设备拆不开,看不到里面的 RustDesk 握手,自然没法按协议指纹下手。
  • 顺带一个安全红利:全部走 443 之后,21114-21119 这些端口可以对公网全部关掉,攻击面大幅缩小。

WSS = WebSocket over TLS。RustDesk 服务端本来就内置了 WebSocket 端口,我们要做的就是用 nginx 在 443 上做 TLS 终止,再把 WebSocket 转发给它们。


二、用到哪些 WebSocket 端口

RustDesk 服务端的两个核心服务,各自有一个专门的 WebSocket 端口:

服务WebSocket 端口干什么
hbbs(红娘)21118信令的 ws 通道
hbbr(搬运工)21119中继的 ws 通道
rustdesk-api(前台)21114网页后台 / API(普通 HTTP)

这三个端口只需要 nginx 在本机访问,不用对公网开放。客户端永远只连 443。

注意:如果你之前用了"换端口"的招(比如 hbbs 改成了 31116),上 WSS 之后可以撤回默认 21116。因为公网根本碰不到 21116 了,只有本机 nginx 去连它,换不换端口都无所谓。回归默认反而更省心。

三、服务端:nginx 在 443 做 TLS 反代

假设你的域名是 rustdesk.example.com,证书已经签好(下一节讲证书)。

nginx 站点配置:

server {
    listen 443 ssl http2;
    server_name rustdesk.example.com;

    ssl_certificate     /etc/nginx/cert/rustdesk.example.com.pem;
    ssl_certificate_key /etc/nginx/cert/rustdesk.example.com.key;

    # 网页后台 + API(rustdesk-api 容器,本机 21114)
    location / {
        proxy_pass http://127.0.0.1:21114;
        proxy_set_header Host       $host;
        proxy_set_header X-Real-IP  $remote_addr;
    }

    # ① hbbs 信令的 WebSocket(本机 21118)
    location /ws/id {
        proxy_pass http://127.0.0.1:21118;
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host       $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_read_timeout 120s;
    }

    # ② hbbr 中继的 WebSocket(本机 21119)
    location /ws/relay {
        proxy_pass http://127.0.0.1:21119;
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host       $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_read_timeout 120s;
    }
}

三个关键点:

  1. /ws/id → 21118、/ws/relay → 21119 是 RustDesk 约定好的路径,不能改名。
  2. WebSocket 必须带 Upgrade / Connection "upgrade" 这两个头,并且 proxy_http_version 1.1,否则握手升级不了。
  3. proxy_read_timeout 给长一点(120s 起),远控是长连接,超时太短会被掐断。
如果你用宝塔面板,可以在站点的"反向代理"里分别加这几条;但 /ws/id/ws/relay 的 WebSocket 头宝塔默认可能不带,建议直接编辑站点的 nginx 配置文件手动加,最稳。

改完 nginx -t 测试无误后 nginx -s reload


四、证书

域名解析到服务器后,用 Let's Encrypt 签一张免费证书即可。宝塔面板里"网站 → SSL → Let's Encrypt"一键申请最省事。命令行用 acme.sh 或 certbot 也行。

证书路径填到上面 nginx 配置的 ssl_certificate / ssl_certificate_key 两行。

WSS 必须有合法证书,自签证书客户端会拒连。这是和"裸 TCP"最大的不同——但也正是这张证书,让你的流量长得像正经网站。

五、客户端:改成走 443 的 WSS

这一步是 WSS 方案的前提,也是要特别说明的地方:

客户端必须是支持 WebSocket 的版本/构建。 RustDesk 较新版本的服务端和客户端已原生支持 WebSocket 连接;如果你是自己编译的客户端(比如做了品牌定制),需要确认构建里开启了 WebSocket 能力。

配置上,客户端的 ID 服务器 / 中继服务器 / API 服务器都指向你的 443 域名(rustdesk.example.com),Key 不变。WebSocket 启用后,客户端会自动走 wss://你的域名/ws/idwss://你的域名/ws/relay,全程 443。

各版本开启 WebSocket 的具体开关可能不同(有的是网络设置里的选项,有的需要构建参数)。落地前请以你所用版本/构建的实际配置为准,先用一台客户端验证能连通,再全量下发。

六、收尾大杀器:只留 443,关掉所有远控端口

确认 WSS 能正常远控之后,就可以做这件最爽的事了:

把 21114-21119 对公网全部关闭,防火墙只留 443(和 SSH)。

按 RustDesk 官方说法,当客户端全部走 WebSocket 时,服务端可以关掉 21114-21119,只保留 443 一个对外端口。此时:

  • 对外扫描你的服务器,只看到一个 443,和千千万万个网站没区别;
  • 链路上的设备抓不到远控特征,也就没法按端口或协议来封;
  • 攻击面从一排端口缩成一个,安全性也上来了。

防火墙(云厂商安全组 + 服务器本地,两层都要)最终只需要:

协议端口说明
TCP443全部远控流量(WSS)+ 网页后台
TCP你的 SSH 端口远程管理

21114-21119 那一排,可以从两层防火墙里全部删掉


七、和"换端口"方案怎么选

换端口443 WSS
落地难度极低(改配置 + 放行端口)中(要证书 + nginx + 客户端支持 ws)
抗封能力续命,可能被重新识别根治,看起来就是普通 HTTPS
对外端口仍暴露一排远控端口只留 443
适合场景临时救急、先恢复使用长期稳定运营

实战建议:出问题先用换端口快速恢复业务,腾出手再上 WSS 做长期方案。 两步走,既不耽误用,又能根治。


小结

WSS 方案的本质,是把"一眼就能被认出来的远控流量",伪装成"满大街都是的 HTTPS 流量"。

  • 服务端:nginx 在 443 做 TLS,/ws/id 转 21118、/ws/relay 转 21119;
  • 客户端:用支持 WebSocket 的构建,指向 443 域名;
  • 收尾:关掉 21114-21119,只留 443。
0

评论 (0)

取消

您的IP: