17 KiB
RemoteDesk CDN 与边缘中继设计
1. 定义
RemoteDesk 所说的“流量支持 CDN”分为两类:
- 实时远程流量:使用全球边缘 TURN/Relay POP,不使用缓存型 CDN。
- 静态分发:客户端、Agent、更新元数据和符号文件使用普通 CDN。
远程桌面视频是每会话唯一的加密实时流,无法像图片或点播视频一样缓存。边缘网络的价值是让两端尽快进入 CDN POP,并尽可能通过供应商的私有/优质跨区域骨干网传输,同时提高 UDP 可达性并提供 TCP/TLS 回退。
2. 路径模式
1. Direct:两端直接连接。
2. Single Edge:一端或两端通过同一个 TURN POP。
3. Dual Edge:两端分别进入最近 POP,POP 间走优质骨干网。
4. Restricted Edge:UDP 不可用时使用 TURN TCP/TLS 443。
默认“智能优选”并行测量 Direct、Single Edge 和 Dual Edge。Direct 不再无条件优先:当 CDN 骨干路径的 RTT、丢包、抖动综合更好时,即使直连可用也选择 CDN。用户还可以选择“直连优先”或“CDN 优先”。
3. 总体拓扑
3.1 Direct
Windows Client <============ WebRTC ============> Linux Agent
end-to-end DTLS-SRTP
3.2 Single Edge Relay
Global Rendezvous API
/ \
outbound control session request
/ \
Linux Agent Windows Client
\ /
\---- selected TURN POP --/
DTLS-SRTP packets
TURN 只转发加密 packet,不终止媒体、不解码、不转码。客户端和 Agent 校验的 DTLS fingerprint 与 Session Ticket 绑定,因此 Relay 无法替换端点。
3.3 Dual Edge Backbone
Windows Client Linux Agent
| |
nearest Client POP nearest Agent POP
| |
+====== CDN private backbone =========+
end-to-end encrypted packets
每个端点从自己的本地 TURN POP 获得 relay candidate。两个 relay candidate 之间的包由同一 CDN/边缘供应商内部路由进入优质骨干网,形成:
Client -> TURN A -> provider backbone -> TURN B -> Agent
双中继会增加带宽成本,但可以绕开质量较差的跨运营商公网段。必须验证供应商确实提供 POP 间私有骨干与会话亲和,不能仅因为服务名称包含“CDN”就假设线路更好。
4. 组件
4.1 Rendezvous Gateway
Rust/Tokio 服务,负责:
- 接收 Agent 主动建立的长期 TLS WebSocket/QUIC 控制连接。
- 将 Device ID 映射到当前 region/gateway connection。
- 转发已签名的 Session Request 和 WebRTC 信令。
- 不读取视频、音频、终端、剪贴板和文件内容。
- 使用短 TTL presence,Agent 离线后自动删除。
第一版使用 TLS WebSocket。QUIC control channel 只在有明确收益且部署环境支持时增加。
4.2 Relay Allocator
负责:
- 返回候选 POP 列表和探测 token。
- 汇总客户端与 Agent 的 RTT、丢包和可达性测量。
- 分别选择 Client POP、Agent POP 和备用 POP 组合。
- 获取 POP 间骨干 RTT、丢包、容量和供应商线路等级。
- 签发短期 TURN credentials。
- 记录配额和 allocation correlation ID。
Allocator 不签发 Linux Session Ticket;设备会话权限仍由 Agent 自己决定。
4.3 TURN POP
优先部署成熟的 coturn 或经过审计的托管 TURN,不从零实现 TURN/STUN。
每个 POP 提供:
- TURN UDP。
- TURN TCP。
- TURN TLS 443。
- STUN binding。
- 标准 metrics、连接限制和 bandwidth quota。
- 与控制面共享的 TURN REST credential secret 或密钥接口。
- POP 间 relay 地址可以通过供应商内部骨干路由。
- Anycast/GeoDNS 接入具有 allocation/session affinity,不能把同一 allocation 漂移到其他 POP。
TURN 进程与控制面分开扩容。
4.4 Global Directory
只保存短期在线路由:
device_id -> region, gateway_id, connection_id, expires_at
不保存桌面密码、Agent 私钥、终端内容或长期会话密钥。在线状态适合使用 TTL KV/Redis 类存储;长期设备元数据单独存储并最小化。
4.5 Static CDN
用于:
- Windows MSI。
- Linux DEB/RPM repository。
- 签名更新 manifest。
- SBOM 与第三方许可证。
- 可选的公开 debug symbols。
所有发布物在上传 CDN 前签名,客户端验证签名而不是信任 CDN 响应。
5. 无云账户配对
初期可以不建立用户账号体系:
- Agent 生成不可猜测的 Device ID 和长期设备公钥。
- 本地配对把 Client 公钥写入 Agent allowlist。
- 云控制面只根据 Device ID 路由加密请求。
- Session Request 由已配对 Client key 签名。
- Agent 独立验证签名、权限、nonce 和 authorization epoch。
- 控制面不能自行给未配对客户端授权。
为了防止 Device ID 被用于枚举在线状态,查询必须携带可验证的设备授权材料并限速。
6. 建立边缘会话
1. Agent -> Gateway: authenticated online presence
2. Client -> Rendezvous: signed connect intent
3. Gateway -> Agent: forwarded intent
4. Agent -> Client: permission/capability response
5. Both -> Allocator: endpoint-local POP probes
6. Allocator: compare Direct/Single/Dual path and backbone metrics
7. Allocator -> Both: endpoint POPs + backups + TURN credentials
8. Agent -> Client: Session Ticket + WebRTC offer/answer
9. ICE: direct and relay candidates are measured
10. Selected pair: best policy-compliant path
控制面无法替 Agent 创建桌面或终端会话。Agent 本地权限、Portal 授权和 target UID 检查保持不变。
7. POP 选择
客户端和 Agent 分别并行探测有限数量的本地候选 POP,控制面同时读取 POP 间骨干指标:
- UDP 可达性与 RTT。
- TCP/TLS RTT。
- 短窗口丢包和抖动。
- POP 当前负载与可用带宽。
- POP A 到 POP B 的内部 RTT、丢包、抖动和线路等级。
选择目标不是只让客户端最近,而是降低两端综合路径:
score = client_to_pop_rtt
+ pop_to_pop_backbone_rtt
+ agent_to_pop_rtt
+ loss_penalty
+ jitter_penalty
+ load_penalty
+ transport_penalty
Direct path 使用相同维度评分。具体权重通过真实会话数据调整。探测结果有短期有效期,且必须绑定 session/endpoint,防止伪造结果影响他人调度。
路径切换设置迟滞:新路径必须持续明显优于现路径才触发 ICE restart,避免 Direct/CDN 来回震荡。
8. TURN Credentials
- 使用标准短期 credential 机制。
- Username 绑定 expiry、session allocation ID 和可选 device hash。
- Password 由 TURN REST secret/HMAC 生成,默认仅数分钟有效。
- 凭据限定 realm、POP 和配额。
- 凭据不等同于 RemoteDesk Session Ticket,不能创建桌面会话。
- Relay 日志不得记录完整 credential。
- POP secret 支持轮换,并允许短时间双密钥验证。
9. Linux 媒体与 DataChannel
通过 TURN 时仍保持:
- H.264/Opus 使用 DTLS-SRTP。
- Input/Control/Terminal/Clipboard/File 使用 DTLS/SCTP DataChannel。
- Relay 只能看到 IP、端口、包大小、时间和总流量元数据。
- 质量控制仍基于端到端 RTCP/TWCC,不使用 Relay 推测替代。
严重丢包时优先级仍为输入、控制、音频、视频、剪贴板、文件。Relay 不应把所有流量放入一个无优先级的应用层 TCP tunnel。
10. Windows RDP 边缘加速
Windows RDP 不使用 WebRTC ICE/TURN,不能直接复用 Linux 媒体中继。要让 RDP 走 CDN 优质骨干,需要透明 L4 Edge Connector:
IronRDP Client
-> Client Edge POP
-> CDN private backbone
-> Target Edge POP
-> outbound RemoteDesk Connector
-> Windows RDP service
- Connector 部署在目标 Windows 网络内并主动连接最近 POP。
- Edge 只转发 RDP TCP/UDP 字节,不终止 TLS/NLA。
- IronRDP 仍使用真实目标主机名完成证书和 CredSSP 校验。
- TCP 和 RDP UDP 使用独立有界通道,不能把 UDP 全部塞入同一个 TCP 流。
- RDP CDN 加速依赖 IronRDP 的自定义 transport 与 UDP multitransport。
- mstsc 回退默认不能接入自定义 Edge Connector;需要标准 RD Gateway 或供应商 L4 服务才可加速。
因此 Linux WebRTC Edge 可以先交付,Windows RDP Edge 必须作为独立 Spike 验证,不能宣称 TURN 已覆盖 RDP。
11. 故障切换
11.1 POP 失效
- 会话建立时保留备用 POP 信息,但不长期占用完整 allocation。
- Relay 心跳或 ICE consent 失败后进入 Degraded。
- Allocator 签发新的短期凭据。
- WebRTC 执行 ICE restart,优先尝试备用 POP。
- Session ID、输入状态和终端/file sequence 保持。
- 恢复媒体后请求 IDR。
11.2 网络切换
客户端网卡、Wi-Fi/有线或地址变化触发 candidate 更新/ICE restart。旧路径在新 candidate pair 确认前保持短暂宽限,避免主动切断可用会话。
11.3 控制面失效
已建立 WebRTC 会话不依赖持续在线的 Rendezvous 控制面。控制面短时故障不应中断现有 direct/TURN allocation;只影响新会话和 POP 迁移。
12. 多区域控制面
首期单区域验证,正式 CDN 模式至少包含:
- Anycast/GeoDNS API 入口。
- Region-local Gateway 和 Allocator。
- POP 间私有骨干路由与质量数据接口。
- 全局短 TTL device directory。
- Agent 到最近 Gateway 的出站连接。
- 区域故障时 Agent 自动连接备用 region。
信令消息携带 request/session ID,并保证幂等。跨区消息至少一次投递时,Agent 必须依靠 request ID 去重。
13. 容量与成本
TURN 是带宽服务,不是缓存服务。容量指标:
- POP ingress/egress Gbps。
- concurrent allocations。
- packets per second。
- 平均/95/99 会话码率。
- UDP/TCP/TLS 分布。
- egress cost per session-hour。
- allocation failure 和 saturation。
控制策略:
- 智能优选默认选择质量/成本策略允许的最优路径。
- Dual Edge 按两端 TURN 流量和骨干流量核算,成本高于 Single Edge。
- 每设备/会话码率和总流量配额。
- POP 达到阈值后停止新 allocation,迁移到备用 POP。
- 文件传输可设置比媒体更低的 Relay 配额。
- 不在 Edge 做转码,避免 GPU 成本和端到端解密。
14. 安全
- Rendezvous 与 Agent/Client 双向设备认证。
- 所有 Session Request 由 Client key 签名,Agent 最终授权。
- TURN credential 短期、限 POP、限 session、限速。
- DTLS fingerprint 与 Session Ticket 绑定。
- 防止匿名 STUN/TURN amplification,启用 nonce、认证和限速。
- Gateway、Allocator、TURN 使用不同 service identity 和密钥。
- Relay metadata 有最短保留期限和访问审计。
- 管理 API 不暴露在媒体监听地址。
- DDoS 防护和费用异常报警属于上线门槛。
15. 可观测性
Client/Agent:
- candidate type:host/srflx/relay。
- path mode、Client POP、Agent POP、transport。
- Direct 与 CDN 路径的并行质量分数。
- ICE state/restart count。
- RTT/loss/jitter/bitrate。
- POP 切换原因。
Control plane:
- online Agent connection count。
- rendezvous success/latency。
- POP allocation success/capacity。
- credential failures/rate limits。
日志使用不可逆短 ID 关联,不记录会话内容、完整 Device ID、SDP、credential 或 IP 超出必要保留期。
16. 测试
- Direct 成功时不产生 Relay 流量。
- Direct 失败后 TURN UDP 建立。
- Direct 可用但质量差时选择 Dual Edge 优质骨干。
- Client/Agent 分别接入最近 POP,确认 POP 间流量走指定骨干。
- 禁 UDP 后 TURN TCP/TLS 回退。
- 主 POP 故障后 ICE restart 到备用 POP。
- 控制面停止后已建立会话继续工作。
- 过期/跨 POP/跨 session credential 被拒绝。
- 恶意 Device ID 枚举和配对请求限速。
- 5%~15% Relay 路径丢包的动态质量调整。
- POP 满载拒绝新 allocation,不破坏现有会话。
- 端到端验证 Relay 无法解密媒体和 DataChannel。
- Windows RDP Edge Connector 分别验证 TCP 与 RDP UDP,不把 UDP 隧道化到 TCP。
17. 实施阶段
当前仓库已交付独立 remotedesk-edge-service:短 TTL Presence、管理员/Agent 分权认证、Direct/Single/Dual 评分、coturn REST 凭据、签名 Session Intent 队列和限额透明 TCP byte relay。Intent 使用共享的域隔离、字段标签、长度前缀稳定签名输入,最长 120 秒、request ID 幂等、全局/设备/Client 容量有界并带 15 秒投递租约;Windows Client 以 Ed25519 key 直接认证公开提交和状态查询,不持有 Edge 管理员令牌。Agent poll/ack 除 Presence Token 外还必须提供设备私钥签名、短时钟窗口和一次性 nonce,且 connection ID 必须仍是当前 Presence。普通会话由 Linux Agent 最终验证已配对 Client、permission 和 allowed user;pairing 会话只在 Agent 本机存在未过期、未耗尽且允许目标用户/terminal 的配对窗口时接受。Edge 随后分别交付 Client/Agent 角色绑定一次性票据,Agent 主动连接 relay 并代理本地 TLS listener;Windows helper 在 opaque relay 内重新完成证书固定 TLS/WSS、Agent 公钥核对、Client challenge 和一次性配对码验证,配对码不进入 Edge API。成功后 Windows Credential Manager 以证书指纹绑定 Agent 公钥,后续会话同样无需 Client 连接 Agent listener。控制端提供映射状态和显式删除。
已接受且未过期的会话另外开放 POST /v1/negotiation/send 和 POST /v1/negotiation/poll。每次请求由发起端设备 key 签名,稳定输入覆盖 request/session、Client/Agent 角色、send/poll、sequence、generation、offer/answer/candidate/end/restart、payload、一次性 nonce 和最长 30 秒生命周期。Edge 从已接受 Intent 和 Agent ack 取得两端公钥,不使用共享 Presence token 认证协商流量。mailbox 只向调用者返回 peer 消息,并限制会话、消息、candidate、单次响应和总内存;只有 restart 能将共享 generation 精确增加一。联合测试通过真实 Intent、Agent poll/ack 建立绑定后连续验证双向 offer/answer,以及端点伪造、nonce 重放、错误会话、乱序和错误 generation 拒绝。GET /health 以 sdp_ice_signaling=true 和 active_negotiation_sessions 报告这个服务端边界。
Agent/Client 已在接受的 desktop 会话上使用 webrtc-rs 0.20.1 创建真实 PeerConnection:Client 固定作为初始 offerer,Agent 作为 answerer;双方经设备签名 mailbox 逐候选交换 SDP/ICE,注册 H.264/RTX/Opus、NACK/PLI/transport-cc 与控制 DataChannel。Edge 只在 Agent 本地授权成功后,分别向 Agent ACK 和 Client 签名状态响应下发绑定同一 session/expiry 的 coturn REST 短期凭据,不向端点暴露管理员令牌。Linux 用户会话已将 X11 BGRA 捕获送入 GStreamer H.264 编码器,并经有界完整性校验 IPC 接到绑定 session 过期时间、用户和 Client 指纹的 WebRTC sender。Windows 控制 helper 源码已把远端 RTP 以 RFC 6184 重组为有界 Annex-B AU,丢包或本地积压后请求 PLI 并等待关键帧,再输入绑定同一 D3D11 device manager 的 Media Foundation H.264 MFT;输出必须是同 device NV12 IMFDXGIBuffer,由 VideoProcessor 呈现到桌面窗口,失败时恢复 zlib 软件路径。该源码按当前要求尚未解析依赖、编译或跨网执行;Opus、真实 coturn POP 和 Windows RDP transport 仍未接入,因此仍不等于完整媒体 transport。
协议 minor 9 不再把 zlib 作为与原生媒体长期并行的画面。Client 呈现第一帧后请求 H.264-only,Agent 在当前 zlib ACK 的完整帧边界确认切换;随后每个 H.264 sequence 的 D3D11 呈现 ACK 驱动下一次捕获。RTP 序号中断会立即通知控制状态机回到 zlib,sender/encoder、解码、积压、轨道结束和 ACK 超时具有相同回退语义。Client 继续读取媒体轨道,收到后续关键帧并成功呈现后可再次执行帧边界切换。
Edge M0
- 单个 coturn POP。
- Rust Rendezvous/Allocator 原型。
- Agent 主动 Presence、签名 Session Intent 投递、本地授权、签名回执、session-bound TURN 凭据、Edge 双向 SDP/ICE mailbox、端点 PeerConnection、Linux H.264/Opus 媒体源发送和 Windows H.264 原生接收/呈现及 Opus/WASAPI 播放源码接线已完成;仍缺平台运行验证。
- 短期 TURN credentials。
- Direct -> TURN UDP -> TURN TLS 切换。
Edge M1
- 两端独立 POP 探测和 Dual Edge 骨干选择。
- Direct/Single/Dual 路径评分与迟滞。
- ICE restart 与 POP 故障切换。
- 配额、metrics 和安全限速。
Edge M2
- 多区域 Gateway/Directory。
- Windows RDP L4 Edge Connector。
- 容量调度、密钥轮换和 DDoS/成本保护。
- 静态发布 CDN 与签名更新。
只有 Edge M0 的端到端加密、短期凭据和流量限制通过后,才允许外部网络试用。