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
260 lines
12 KiB
Markdown
260 lines
12 KiB
Markdown
# 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 KiB;Offer 绑定非零 sequence、精确 UTF-8 字节数和小写 SHA-256,Data 必须是无 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/NLA,IronRDP 校验真实 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. 已知安全限制写入发布说明。
|