Windows 远程桌面(RDP)是怎么建立的

1. 先建立共同语言:什么是「远程桌面」

远程桌面要解决的问题很简单:

人坐在 本机 A ,操作 远端机 B 上的桌面(鼠标键盘进、画面出),就像坐在 B 跟前一样。

对 Windows 来说,业界最常用的协议是 RDP(Remote Desktop Protocol) ,默认监听 TCP 3389

注意区分三层概念:

概念 是什么 举例
协议 双方约定怎么传键鼠、画面、剪贴板等 RDP、VNC、SSH
服务端 远端机上接受连接、提供桌面会话的一方 Windows「远程桌面服务 / TermService」
客户端 本机上发起连接、显示画面的一方 mstsc、Guacamole 前端、IronRDP

本项目里,能源站 / 照明系统 等机器扮演的是 RDP 服务端 (只需开 3389);门户客户端要做的是选一种 客户端方案 去连它们。


2. Windows 建立远程桌面的原理

2.1 远端机(被控端)要具备什么

在 Windows 上打开「设置 → 系统 → 远程桌面」并允许连接后,大致会发生:

  1. 远程桌面服务TermService)启动,并监听 0.0.0.0:3389(或你改过的端口)。
  2. 系统准备好 会话(Session) 机制:本地登录是 Session,远程登录也是 Session;远程用户登录后得到自己的桌面环境(或接管已有会话,取决于策略与版本)。
  3. 可选但常见的安全层:
    • TLS / 证书(传输加密)
    • NLA(Network Level Authentication):先用凭据认证,再进入完整桌面会话,减少未认证连接占用资源
    • 防火墙放行 3389(域策略 / 本机防火墙)

远端机不必 安装 Guacamole、不必装任何第三方远程软件------微软内置 RDP 服务端即可。

本项目设计也是:远端只开 3389

2.2 一次典型连接时序(简化)

text 复制代码
本机客户端                         远端 Windows (3389)
    |                                    |
    |  1. TCP 连接到 host:3389           |
    |----------------------------------->|
    |  2. 能力协商(协议版本、加密、GFX...) |
    |<---------------------------------->|
    |  3. 身份认证(用户/密码/域/智能卡...) |
    |----------------------------------->|
    |  4. 建立会话,进入桌面              |
    |<---------------------------------->|
    |  5. 持续双向流:                    |
    |     ← 画面/光标/剪贴板/声音...        |
    |     → 键鼠/触控/文件重定向...         |
    |<---------------------------------->|

要点:

  • 画面:服务端把桌面变化编码后推给客户端(现代 RDP 常用 GFX / RemoteFX 一类图形管线,效率高于「整屏位图硬刷」)。
  • 输入:客户端把键盘、鼠标事件编码发回服务端,由服务端注入到对应会话。
  • 这是二进制私有协议:浏览器不能「直接」说 RDP;要么用系统客户端(mstsc),要么在中间加一层翻译,要么在浏览器里跑一套完整的 RDP 协议栈(WASM)。

2.3 凭据从哪来(和本项目的关系)

mstsc 可以弹窗让用户手输账号密码,也可以事先用 cmdkey 把凭据写入 Windows 凭据管理器,再无感拉起 mstsc /v:host

本项目「微软原生」模式走的就是:读配置里的账号密码 → cmdkeymstsc

Web / WASM 方案则是把同一份 host/user/pass 交给自研编排层 ,由 guacd 或 IronRDP 去完成 RDP 握手,而不是交给系统的 mstsc


3. 三种方案分别是什么

下面三个名字,经常被混在一起谈,其实处在不同层次。

text 复制代码
┌─────────────────────────────────────────────────────────────┐
│  用户眼睛看到的「桌面画面」                                    │
└─────────────────────────────────────────────────────────────┘
        │                    │                    │
   ┌────▼────┐         ┌─────▼─────┐        ┌─────▼─────┐
   │  mstsc  │         │ Guacamole │        │ IronRDP   │
   │ 系统窗口 │         │ 网页 Canvas│        │ 网页 Canvas│
   └────┬────┘         └─────┬─────┘        └─────┬─────┘
        │                    │                    │
        │              ┌─────▼─────┐              │
        │              │ guacamole │              │
        │              │ -lite /   │              │
        │              │ 网关 WS   │              │
        │              └─────┬─────┘              │
        │                    │                    │
        │              ┌─────▼─────┐              │
        │              │   guacd   │              │
        │              │ 协议翻译  │              │
        │              └─────┬─────┘              │
        │                    │                    │
        └──────────┬─────────┴────────┬───────────┘
                   │                  │
                   ▼                  ▼
            远端 Windows RDP (3389) ------ 三种最终都要连这里

3.1 mstsc(微软原生客户端)

是什么

Windows 自带的「远程桌面连接」程序,可执行文件一般是:

text 复制代码
%SystemRoot%\System32\mstsc.exe

怎么工作

  1. 本机直接对 host:3389 发起 原生 RDP 连接。
  2. 系统弹出或使用已存凭据完成认证。
  3. 独立的系统窗口 里渲染远端桌面(不是嵌在你的 Vue/Tauri 页面里)。

在本项目中的角色

设置里的「微软原生」:cmdkey 写凭据 → 启动 mstsc

稳定、零第三方依赖,但体验是「跳出门户、打开系统远程桌面窗口」。

优点

  • Windows 自带,无需打包 guacd / Node / WASM
  • 兼容性最好(NLA、证书、打印机/剪贴板/驱动器重定向等成熟)
  • 性能通常最好(本地原生渲染)
  • 内网离线部署最省事

缺点

  • 无法嵌进应用窗口(或很难无缝嵌;本质是另一个进程的 HWND)
  • 凭据落在 Windows 凭据管理器,生命周期与卸载策略要单独考虑
  • 多会话、统一 UI、水印、审计等产品化能力弱(除非再包一层)

3.2 guacd(Apache Guacamole 代理)+ 网页前端

是什么

guacd 是 Apache Guacamole 的 服务端代理守护进程(C 语言)。它自己不是「给用户看的窗口」,而是:

一边说 Guacamole 协议 (给浏览器用的文本/指令协议),

一边说 RDP/VNC/SSH...(连真实远端)。

浏览器端用 guacamole-common-js 在 Canvas 上画图;中间通常还有一层 WebSocket 网关。本项目用的是:

  • guacd:RDP ↔ Guacamole 协议翻译
  • guacamole-lite(Node):浏览器 WebSocket ↔ guacd
  • 前端:内嵌 Guacamole 客户端

完整链路(本项目 Web 模式)

text 复制代码
Tauri WebView
  └── guacamole-common-js (Canvas)
        │  WebSocket  (ws://127.0.0.1:随机端口/?token=...)
        ▼
  node-gateway (guacamole-lite)
        │  Guacamole 协议 TCP
        ▼
  guacd.exe
        │  RDP (3389)
        ▼
  远端 Windows

用户感知:「还在门户窗口里,桌面嵌在页面中」。

远端感知:「就是一个普通 RDP 客户端连上来了」。

为什么需要 guacd

浏览器不能直接发 RDP 二进制流(安全模型 + 协议复杂度)。Guacamole 的经典解法是:把「会说 RDP 的重活」放到本机/服务器上的 guacd,浏览器只处理相对简单的 Guacamole 协议。

优点

  • 可嵌窗:体验统一在 Tauri 窗口内
  • 生态成熟(运维界用 Guacamole 做堡垒机很常见)
  • 同一套栈还可扩展 VNC/SSH(本项目只用 RDP)
  • 凭据可由应用签发一次性 token,不必先弹 mstsc 登录框

缺点

  • 组件多:guacd + Node 网关 + 前端 JS,任一挂掉都要编排重启
  • Windows 版 guacd :Apache 不提供官方 guacd.exe ;Docker 镜像是 Linux;社区移植/预编译少且老旧 → 打包进 Win 客户端是最大现实阻力
  • 安装包体积大(guacd+DLL + 便携 Node + node_modules)
  • 性能与功能(打印机、部分 GFX/NLA 组合)通常弱于 mstsc
  • 多进程,排障成本高

和「第三方封装」的关系(调研结论)

  • Docker guacamole/guacd:最常见封装,但是 Linux 容器,不是原生 Win exe
  • guacamole-lite :封装的是 WebSocket 网关,不是 guacd 本身
  • 社区 Windows 移植 (如源码级 port):多为过时版本、需自行编译,鲜有可靠现成 guacd.exe+DLL Release

所以:「有第三方封装」≠「有一份能直接塞进 NSIS 安装包的稳定 Windows guacd」。


3.3 IronRDP-WASM(浏览器内 RDP 协议栈)

是什么

IronRDP 是 Devolutions 开源的 纯 Rust 实现的 RDP 客户端

其中的 WASM / Web 产物可以在浏览器(或 WebView2)里跑完整 RDP 逻辑,用 Canvas 画桌面。

怎么工作(概念)

text 复制代码
Tauri WebView
  └── ironrdp.wasm + JS 胶水
        │  需要一条「到远端 3389」的字节通道
        │  (浏览器不能随意 TCP,通常要:
        │    WebSocket / WebTransport 代理,或 Tauri 本地转发)
        ▼
  (可选)本机很薄的 TCP↔WS 转发
        │  RDP
        ▼
  远端 Windows :3389

与 Guacamole 的关键差异:

Guacamole IronRDP-WASM
RDP 协议在哪实现 guacd(本机/服务器原生进程) 浏览器里的 WASM
是否需要 guacd 需要 不需要
中间层 guacamole 协议 + 常驻代理 主要是「字节管道」转发
典型体积 guacd + Node 较大 WASM 量级通常更小(约数 MB 级,视构建而定)

优点

  • 无 guacd:避开 Windows 预编译二进制难题
  • 可嵌在 WebView 内,接近 Guacamole 的产品体验
  • 组件更少(相对 guacd + guacamole-lite)
  • 与「纯前端 + 薄网关」架构契合 Tauri

缺点

  • 仍不是零后端 :浏览器一般不能直连任意 TCP 3389,需要 本机或服务器上的转发/网关(工作量小于 guacd,但不是零)
  • WebView2 / WASM 工具链、剪贴板、音频、分辨率自适应等要逐项验证
  • 相对 mstsc,企业环境边角兼容性(NLA、证书、特殊策略)可能踩坑
  • 本项目前期调研推荐过 IronRDP;现行 Web 主路径已切到 IronRDP-WASM + Devolutions Gateway,guacd 已弃用

4. 对照总表

维度 mstsc guacd + Guacamole Web IronRDP-WASM
画面出现在哪 系统独立窗口 应用内 Canvas 应用内 Canvas
谁实现 RDP 微软客户端 guacd WASM 内 IronRDP
远端要求 仅 3389 仅 3389 仅 3389
本机额外进程 无(系统自带) guacd + Node 网关 合规转发(如 Devolutions Gateway / RDCleanPath)
Win 客户端打包难度 极低 高(缺官方 guacd.exe) 中(WASM + 转发;转发有官方 Win 发行可参考)
内网离线友好 最好 需预置全部 sidecar 需预置 WASM + 转发组件
性能 / 兼容 通常最好 中等 中等(视实现成熟度)
本项目现状 ✅ 已实现「原生」 ❌ 已弃用 ✅ 现行「Web」路径(Gateway + ironrdp-web)

5. 「需验证转发与 WASM」是什么意思?

这句话不是说 IronRDP「理论上不行」,而是说:接入前有两块必须真机跑通的工程,不能当成已交付。

5.1 WASM 是什么(要验证的第一块)

WASM(WebAssembly) = 把 IronRDP 的 RDP 客户端编译成浏览器能跑的二进制模块(通常是 *.wasm + 一小段 JS 胶水)。

在本项目里它会跑在 Tauri 的 WebView2 里,负责:

  • 完成 RDP 握手 / NLA / 画桌面到 Canvas
  • 把键鼠事件编码成 RDP 发回去

要验证的具体事项:

检查项 为什么
能否用 wasm-pack / 官方 web-client 打出可用产物 工具链、依赖版本常踩坑
WebView2 能否加载该 .wasm CSP、MIME、路径、跨域
画布是否出画、分辨率缩放是否正常 渲染与输入事件
剪贴板 / 键盘布局 / 重连 产品可用性
目标机 Win7~Win11 兼容 甲方环境跨版本(Win7 风险更高)

这和「有没有 guacd.exe」是两类问题:WASM 是前端协议栈能不能在我们窗口里活起来

5.2 转发是什么(要验证的第二块)

浏览器 / WebView2 不能mstsc 那样随便打开一条到 host:3389 的原始 TCP。

所以 WASM 客户端通常只能走 WebSocket(或自定义 transport) ,中间必须有人把字节接到真正的 RDP 端口------这就是文档里说的 转发(proxy / gateway)

text 复制代码
WebView 里的 ironrdp.wasm
        │  WebSocket(浏览器允许)
        ▼
本机「转发」进程(只应绑 127.0.0.1)
        │  TCP 3389(RDP 需要)
        ▼
远端 Windows

重要:不是任意 WS→TCP 都行。

官方 ironrdp-web 默认期望代理理解 RDCleanPath 扩展(先处理一段预连接/证书信息,再进入 RDP)。

随便写一个「WebSocket 字节透传」往往不够;社区常见可用方案是:

  • 使用 Devolutions Gateway(官方配套、有 Windows 发行,实现了 RDCleanPath),或
  • 自己实现 RDCleanPath,或
  • 不用 WASM,改在 Tauri Rust 进程内直接跑原生 IronRDP(可直连 TCP,但要把画面嵌进 UI 的方式另做设计)

本仓库早期曾写过简易 rdp_gateway(裸 WS↔TCP),那只是预研骨架;不能默认它已满足现行 ironrdp-web

所以「验证转发」=:选定一种合规网关/transport,并在真机 RDP 上连通

5.3 和 guacd 路线对比(为何常觉得 IronRDP 更合适)

Guacamole / guacd IronRDP-WASM
重依赖 Windows 上难找官方 guacd.exe 不需要 guacd
中间层 guacd + Node guacamole-lite 转发(常为 Devolutions Gateway 或自研 RDCleanPath)
画面 嵌窗 Canvas 嵌窗 Canvas
打包 卡在第三方 Win guacd 卡在「WASM 构建 + 合规转发」是否跑通
对本项目 现有 Web 模式已铺管线,但缺 guacd 二进制 更贴「客户端自带、嵌窗、少 C 依赖」的目标,但要重做/换 Web 分支

结论可以概括成:

  • 你的直觉有道理:就「避开 Windows guacd」和「嵌在门户里」而言,IronRDP 往往更适合我们。
  • 「需验证转发与 WASM」的意思是:适合 ≠ 已经能用;还差两块可演示的验收,而不是再去找 guacd.exe。

5.4 若决定切到 IronRDP,建议的验收顺序

  1. WASM:官方 web-client / 预构建能否在本机浏览器出画(先不管门户)。
  2. 转发:Devolutions Gateway(或等价 RDCleanPath)本机启动,WASM 经它连上一台真实 3389。
  3. 嵌入 TauriRdpViewer 改为加载 IronRDP 页;凭据仍由 Rust 下发。
  4. 兼容:至少测一台 Win10/11;有条件再测 Win7。
  5. 保留 mstsc:作为设置里的兜底(已通,不要删)。

6. 和本项目目标的匹配

门户目标可以概括成:

  1. 用户只点卡片,尽量少感知「又开了一个系统工具」
  2. 凭据由客户端配置/后台管理,不要让用户每次手输
  3. 内网环境,目标机不装额外软件,安装包尽量自包含
  4. PoC 要尽快可演示,也要能讲清正式方案风险

据此:

目标 mstsc Guacamole/guacd IronRDP-WASM
嵌在门户窗口内
远端零改造(只开 3389)
内网安装包自包含 ⚠️ 卡在 guacd.exe ⚠️ 需验证转发与 WASM
实现与运维复杂度
当前可演示性 立刻可用 差 guacd 二进制则 Web 不通 需重新接入

务实结论(给决策用):

  • 要稳定演示 / 内网交付兜底 → 保留并优先保证 mstsc 原生模式(已通)。
  • 要窗口内嵌体验 → 使用现行 IronRDP-WASM + Devolutions Gateway(已替代 guacd);保留 mstsc 兜底。
  • 不要再投入 Windows guacd 二进制寻找;官方路径是 Gateway + IronRDP。

7. 一张图看清「建立连接」时你在用谁

text 复制代码
用户点击「打开远程」
        │
        ▼
  读取有效模式(全局 defaultMode / 项目 rdpMode)
        │
        ├── native ──────────────────────────────────────┐
        │                                                ▼
        │                                     cmdkey 写入凭据
        │                                                ▼
        │                                     启动 mstsc /v:host
        │                                                ▼
        │                                     系统窗口 ←──RDP──→ 远端:3389
        │
        └── web ─────────────────────────────────────────┐
                                                         ▼
                                              本地 Devolutions Gateway
                                              是否就绪?
                                                         │
                                    ┌────────是──────────┴────────否──┐
                                    ▼                                  ▼
                         签发 ASSOCIATION token,              若有 webUrl → 外链兜底
                         打开内嵌 IronRDP 画面                  否则提示失败 / 改用原生
                                    │
                                    ▼
                         Canvas ←WS /jet/rdp→ Gateway ─RDP→ 远端:3389

(历史 Guacamole / guacd 路径已弃用。)


8. 常见误解

  1. 「装了 Guacamole,远端也要装?」

    否。Guacamole/guacd 装在 客户端或网关机;远端只开 RDP。

  2. 「guacamole-lite 能代替 guacd?」

    否。lite 只做 WebSocket 与会话编排;不会自己说 RDP。

  3. 「IronRDP 完全不用本机任何服务?」

    几乎不行。浏览器环境通常仍要一条到 3389 的转发通道;只是不必再跑完整 guacd。

  4. 「mstsc 和 RDP 是两个东西?」

    RDP 是协议;mstsc 是微软对该协议的官方客户端之一。

  5. 「Web 模式更不安全 / 更安全?」

    不绝对。安全取决于凭据存放、token 时效、是否只绑 127.0.0.1、日志是否落盘等。mstsc 用系统凭据库;Web 模式用应用自己的编排------各有审计与泄露面,需要产品层统一设计。


相关推荐
程序员贺加贝42 分钟前
库存不是一个数字:从 On Hand 到 Available、Reserved 的销售订单库存预留设计
架构·saas
博、、1 小时前
本地AI智慧电商平台定制开发:技术架构与实战指南
人工智能·架构
老郑聊AI业财智造1 小时前
数据不搬家,也能做检索:Milvus的“湖原生”架构革命
人工智能·ai·架构·软件工程·软件构建·milvus
shiyi.十一1 小时前
第8章:计算机网络中的安全 — 知识要点与架构
计算机网络·安全·架构
国科安芯2 小时前
小卫星综合电子系统中RISC-V抗辐射MCU的功能安全与多接口集成架构分析
单片机·嵌入式硬件·安全·fpga开发·架构·risc-v
深念Y3 小时前
微服务抽取路线图:从胖单体到 ARM 集群
前端·arm开发·数据库·后端·微服务·云原生·架构
凤山老林3 小时前
高可靠 API 网关架构:Spring Cloud Gateway 集成 Sentinel 实现智能限流、动态路由与安全管控
安全·spring cloud·架构·sentinel
我滴老baby4 小时前
部署 Portainer CE,把日志、镜像和数据卷搬进网页
数据库·人工智能·架构
^酸酸4 小时前
Prometheus 监控架构部署实战:二进制与 Docker 双方案
docker·架构·prometheus