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

260 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RemoteDesk 安全设计
## 1. 安全目标
RemoteDesk 可以查看桌面、注入输入、传输文件和打开终端,属于高权限软件。安全目标:
- 未配对设备不能创建任何远程会话。
- 配对设备只能使用明确授予的能力和目标用户。
- system daemon 不接触桌面、终端和文件内容。
- Linux 媒体进程被攻破时不自动获得 root。
- 网络攻击者不能窃听、篡改或重放会话。
- 日志、崩溃转储和配置不泄露敏感内容。
不试图防御已经控制 Linux root、Windows 管理员或固件的攻击者。
## 2. 保护资产
- Agent/客户端设备私钥。
- Windows RDP 密码。
- 桌面视频、音频、输入和剪贴板。
- 终端内容与命令执行权限。
- 文件内容和目标路径。
- 已配对设备、权限和撤销状态。
- Windows 端证书指纹绑定的 Linux Agent 公钥映射(非秘密、完整性敏感)。
- 更新签名密钥和发布渠道。
## 3. 信任边界
```text
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 与边缘中继](edge-relay.md)。
## 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. 已知安全限制写入发布说明。