Files
曾志威 5db6b9ef68
ci / rust (push) Canceled after 0s
ci / web (push) Canceled after 0s
ci / package-preview (push) Canceled after 0s
ci / package-installer (push) Canceled after 0s
ci / linux-agent (push) Canceled after 0s
ci / edge-service (push) Canceled after 0s
ci / coturn-pop (push) Canceled after 0s
ci / package-windows-host (push) Canceled after 0s
Initial commit
2026-08-14 00:35:42 +08:00

12 KiB
Raw Permalink Blame History

RemoteDesk 安全设计

1. 安全目标

RemoteDesk 可以查看桌面、注入输入、传输文件和打开终端,属于高权限软件。安全目标:

  • 未配对设备不能创建任何远程会话。
  • 配对设备只能使用明确授予的能力和目标用户。
  • system daemon 不接触桌面、终端和文件内容。
  • Linux 媒体进程被攻破时不自动获得 root。
  • 网络攻击者不能窃听、篡改或重放会话。
  • 日志、崩溃转储和配置不泄露敏感内容。

不试图防御已经控制 Linux root、Windows 管理员或固件的攻击者。

2. 保护资产

  • Agent/客户端设备私钥。
  • Windows RDP 密码。
  • 桌面视频、音频、输入和剪贴板。
  • 终端内容与命令执行权限。
  • 文件内容和目标路径。
  • 已配对设备、权限和撤销状态。
  • Windows 端证书指纹绑定的 Linux Agent 公钥映射(非秘密、完整性敏感)。
  • 更新签名密钥和发布渠道。

3. 信任边界

Untrusted network
       |
TLS WebSocket / WebRTC
       |
remotedesk-agentd (system/root boundary)
       |
authenticated Unix Socket
       |
desktop-session / shell-session (target UID)
       |
Wayland/Xorg/PTY/user files

另一条边界存在于 Windows UI 与凭据存储之间。UI 只能获取短期凭据句柄或会话材料,不应长期缓存明文秘密。

4. 威胁模型

威胁 主要控制
局域网监听与篡改 TLS 1.3、DTLS-SRTP、设备密钥认证
中间人配对 本机开启配对、握手短指纹、本机确认
配对码暴力破解 短有效期、次数限制、指数退避、审计
重放会话请求 nonce、短期 Ticket、replay cache、sequence
已配对客户端越权 capability bitset、target UID allowlist、epoch
恶意协议消息 Protobuf 限制、状态校验、fuzz、有界分配
Agent 媒体漏洞提权 媒体进程普通 UID、agentd 零媒体接触
终端直接 root PAM、降权顺序、UID 0 默认拒绝
文件路径穿越 服务端生成路径、canonical check、原子落盘
剪贴板泄露 独立读写权限、按需请求、大小和 MIME 限制
依赖供应链 lockfile、cargo-deny、SBOM、签名发布

5. Agent 权限拆分

5.1 agentd

允许:

  • 读取设备身份和配对数据库。
  • 监听认证/信令端口。
  • 查询 logind 会话。
  • 验证 Ticket,并启动已降权的 session 进程。
  • 撤销客户端并终止对应会话。

禁止:

  • 读取或记录视频帧、音频、剪贴板、文件和终端数据。
  • 直接连接用户 PipeWire/X server。
  • 解释客户端提供的 shell 命令。
  • 使用用户提供的任意路径启动程序。

systemd unit 建议启用:

  • NoNewPrivileges=true
  • PrivateTmp=true
  • ProtectHome=true,仅通过明确路径访问必要数据
  • ProtectSystem=strict
  • PrivateDevices=true,除非最小 Helper 明确需要设备
  • RestrictAddressFamilies= 仅保留实际使用协议族
  • SystemCallFilter= 在兼容性验证后启用
  • 单独的 RuntimeDirectory/StateDirectory

具体沙箱项必须通过 Wayland/Xorg/PAM 集成测试,不可为通过测试整体关闭。

5.2 desktop-session

  • 以目标登录用户运行。
  • 只能访问该用户的 Portal、PipeWire、Xauthority 和剪贴板。
  • 不拥有 Agent 长期设备私钥。
  • 只接受 agentd 签发的单次 Ticket。
  • 会话结束后释放 Portal token、帧、编码器和临时密钥。
  • X11 短时恢复令牌由用户会话进程使用系统随机源生成,只经固定证书 TLS/WSS 和 root-owned Unix Socket 传递;令牌绑定已认证 Client 指纹与 Linux 用户、15 秒过期、每次恢复旋转,不写日志或诊断文件。Windows Client 仅将最新令牌写入当前用户 Credential Manager,并以 Agent TLS 证书指纹和 Linux 用户构造隔离目标;正常关闭、服务端关闭或恢复拒绝时删除。断线时先释放全部 XTEST 输入,未完成帧和 ACK 不恢复。

5.3 shell-session

安全顺序:

  1. 验证 Ticket、客户端权限和 target UID。
  2. PAM account/session 检查。
  3. 初始化补充组。
  4. 设置 GID/UID,确认不能恢复 root。
  5. 清理文件描述符和环境变量。
  6. 切换 HOME/工作目录。
  7. 创建 PTY 并 exec allowlist 中的登录 Shell。

权限下降后进行自检:effective/real/saved UID/GID、groups 和 capabilities 均符合目标用户。失败立即终止,不尝试宽松回退。

6. 配对与设备身份

  • 配对必须由 Linux 本地用户显式开启。
  • 配对窗口默认短时关闭,不永久监听匿名配对。
  • 配对码至少具有足够熵,并限制每次窗口的失败次数。
  • Linux 本地 UI 显示客户端名称、公钥短指纹和请求权限。
  • Windows 同时显示 Agent 短指纹,用户确认两端一致。
  • 长期记录保存完整公钥,不保存配对码。
  • Windows 控制端将 Agent 公钥绑定到已确认的 TLS 证书 SHA-256;后续 Edge 会话同时校验该公钥和固定证书。
  • 映射目标为 RemoteDesk/Linux/agent/<certificate-sha256>,只能通过显式“忘记身份”操作或 Windows Credential Manager 删除。
  • 设备可以本地查看、改权、改名和撤销。

远程首次配对要求用户从 Agent 本地 pairing-code 命令取得设备公钥、证书指纹和一次性码。Edge pairing Intent 只有在 Agent 本机配对窗口未过期、未耗尽且允许目标用户/terminal 时才会获得 relay;配对码只在固定证书的端到端 TLS/WSS 内验证和消费。Client 同时核对 relay 内 Hello 的 Agent 公钥与用户录入值,成功后才保存证书到公钥映射。缺少这些材料时不通过 Edge 猜测或枚举设备。

配对协议采用经过审查的 PAKE/Noise/设备认证库。确定具体库前,配对只能处于实验状态,不能声明抵抗主动中间人。

7. 会话票据

  • 由 agentd 签发并签名。
  • 有效期短,单次使用。
  • 绑定客户端公钥、session type、UID、权限和 capability digest。
  • 使用后写入 replay cache。
  • 权限或设备撤销时递增 authorization epoch,使旧票据立即失效。
  • session 进程不接受客户端自报权限。

8. 网络入口

  • 只允许 TLS 1.3 或安全基线允许的版本。
  • 禁止匿名弱密码套件和 TLS compression。
  • 设置握手、读写和空闲超时。
  • 限制半开连接、并发认证和消息速率。
  • 每条消息先检查认证状态、长度、类型和当前会话状态。
  • WebRTC DTLS fingerprint 绑定到已认证 Session Ticket。
  • ICE candidate 数量、地址长度和 SDP 大小受限。

公网中继使用短期 TURN credential、限速和 allocation 配额。Relay 只看到网络元数据,媒体与 DataChannel 仍由端点 DTLS 加密。边缘控制面不能签发 Linux Session Ticket,详细边界见 CDN 与边缘中继

9. Windows 客户端

  • 设备私钥和 RDP 密码使用 Credential Manager/DPAPI。
  • SQLite 只存凭据引用和证书指纹。
  • 凭据读取后缩短明文生命周期,避免 Clone 和 Debug 输出。
  • 远端地址、用户名和文件路径在诊断导出时可脱敏。
  • Tauri/WebView 使用本地资源、严格 CSP、窗口级 capability 和导航 allowlist。
  • Release 禁用 devtools,不执行远端 HTML/JavaScript。
  • Linux 桌面视频由原生 helper 处理,不把 frame 传入 WebView。
  • 原生 helper 的 TURN credential、SDP 和 Session Ticket 通过受限 Named Pipe 交付,长期设备私钥和短期会话材料均不进入 JavaScript。
  • Tauri command 校验 window label、session ID、generation、权限和 payload size。
  • RDP viewer Named Pipe 源码使用当前用户 SID 的保护 DACL、单实例和拒绝远程客户端;控制服务核对 OS 报告的 pipe 客户端 PID、进程创建时间、实际镜像路径及 SHA-256 build hash,再验证一次性 HMAC-SHA256 challenge。viewer 只有在严格 JSON schema、目标、显示、证书、会话标识和 opaque 凭据引用全部通过校验后,才返回绑定载荷 SHA-256 与 challenge 的 HMAC ACK;错误摘要、错误 MAC、版本不符或未 ACK 都会令服务端失败关闭。双方使用非阻塞有界读取,连接、认证、配置与 ACK 受同一绝对 deadline 约束,已连接但停滞的 helper 也会超时失败。viewer 同时绑定带 KILL_ON_JOB_CLOSE 的独立 Job Object,控制服务终止时由内核清理;native-video helper 尚未接入该运行时。
  • 原生 helper 不接受来自远端的窗口标题或任意 Win32 消息 ID。
  • IronRDP 证书变化必须阻断自动连接。
  • mstsc 回退使用受限临时 .rdp 配置,文件不包含密码并在启动后删除。

10. 输入安全

  • 仅活动且获得输入权限的会话可以注入输入。
  • 客户端失焦可按配置暂停键盘捕获。
  • 本地保留紧急释放组合键,不能转发给远端。
  • 远端请求不能主动抓取本地输入。
  • 重连和断开时释放所有远端按键与按钮状态。
  • uinput Helper 只接受结构化输入事件,不接受任意 ioctl 或设备路径。

11. 剪贴板和文件

剪贴板:

  • 读、写分开授权。
  • 远端先 Offer,本端接受后才读取内容。
  • MIME allowlist,首版仅 UTF-8 文本。
  • 单项最多 32 KiBOffer 绑定非零 sequence、精确 UTF-8 字节数和小写 SHA-256Data 必须是无 padding 的 canonical Base64。
  • 拒绝 NUL、无效 UTF-8、非规范换行和未匹配的 Offer/Data;最近内容摘要用于阻止双端回写循环。
  • agentd 只验证权限并转发结构化消息,X11/Win32 剪贴板访问分别留在普通用户会话进程和控制 helper 的有界工作线程。
  • 内容不进入日志或 crash dump。

文件:

  • 每次传输可要求用户确认。
  • Agent 决定最终目录和临时文件名。
  • 拒绝绝对路径、父目录、软链接、设备和 FIFO。
  • 使用 no-follow、size limit、free-space check 和 hash。
  • 写入临时文件,校验后原子 rename。
  • 可选接入系统恶意软件扫描钩子,但不能假设一定存在。

13. CDN Edge Connector

  • Linux WebRTC TURN 与 Windows RDP L4 Connector 使用不同 service identity 和 credential scope。
  • RDP Connector 只允许连接策略中列出的目标地址/端口,不能成为通用 TCP/UDP 代理。
  • Connector 通过出站连接进入最近 POP,不开放匿名公网监听。
  • Edge 不终止 RDP TLS/NLAIronRDP 校验真实 Windows 目标身份。
  • Client/Agent POP 及骨干路由元数据设置最短保留期。
  • 双 POP credential 分别绑定 endpoint、POP、session 和 authorization epoch。
  • 路径选择数据可影响质量但不能授予会话权限。

14. 日志和崩溃

禁止记录:

  • 密码、私钥、Session Ticket 和完整 Token。
  • 桌面像素、音频、剪贴板和终端内容。
  • 文件内容和配对码。

允许记录:

  • correlation/session ID 的不可逆短标识。
  • 状态转换、稳定错误码、版本和能力。
  • 非敏感性能指标。

崩溃转储默认关闭或使用最小转储;发布前验证密钥、帧缓冲和剪贴板不会进入转储。诊断包生成后提示用户保存位置和包含的数据类型。

15. 更新安全

  • Windows MSI、Linux DEB/RPM 和更新元数据均签名。
  • 客户端/Agent 只接受可信发布密钥签名的更新。
  • 更新检查与下载分离,下载失败不影响现有版本。
  • 协议/数据库迁移可回滚,不能在验证前删除旧数据。
  • 生成 SBOM,跟踪 Rust crates、IronRDP、GStreamer 和系统库公告。
  • 发布密钥离线保存并具有轮换/撤销流程。

16. 安全测试

  • Pairing、Ticket、Envelope 和文件协议 fuzz。
  • 过期、重复、乱序、跨设备 Ticket。
  • 未授权权限位和 target UID。
  • Unix Socket 对端 UID/PID 欺骗测试。
  • PAM 失败、锁定账户、过期账户和 shell 禁用。
  • 路径穿越、软链接竞争、磁盘耗尽和超大文件。
  • DataChannel flood、WebSocket slowloris 和配对爆破。
  • 日志/诊断包/崩溃转储敏感数据扫描。
  • systemd sandbox 与 SELinux/AppArmor 环境测试。
  • 依赖漏洞、许可证和签名验证。
  • RDP Connector 目标 allowlist、端口扫描和代理滥用测试。
  • 双 POP credential 跨 endpoint/POP/session 重放测试。

17. 发布门槛

首个稳定版本发布前必须完成:

  1. 配对协议威胁建模与独立代码审查。
  2. Agent root 边界和 PTY 降权专项审计。
  3. 文件传输未完成时默认关闭。
  4. 协议解析器 fuzz 达到约定运行时长且无崩溃。
  5. 所有安装包签名并生成 SBOM。
  6. 已知安全限制写入发布说明。