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
364 lines
24 KiB
Markdown
364 lines
24 KiB
Markdown
# RemoteDesk Linux 被控端设计
|
||
|
||
## 1. 目标
|
||
|
||
RemoteDesk Linux Agent 是安装在 Linux 被控机器上的自研组件。它不使用 xrdp、GNOME Remote Desktop 或 KDE KRdp,负责把当前图形会话或命令行终端安全地交付给 Windows 客户端。
|
||
|
||
首个稳定版本支持:
|
||
|
||
- 已登录的 Wayland 和 Xorg 用户会话。
|
||
- 无图形环境的纯命令行终端会话。
|
||
- 用户首次确认后的设备配对。
|
||
- PipeWire 屏幕和系统音频捕获。
|
||
- libei/Portal 键盘与鼠标控制。
|
||
- H.264 视频、Opus 音频和 WebRTC 直连。
|
||
- 文本剪贴板、动态分辨率和断线恢复。
|
||
- GNOME 与 KDE Plasma 的主流发行版。
|
||
|
||
登录界面、任意合成器的永久无人值守和内核级抓屏不属于首个稳定版本。
|
||
|
||
## 2. 进程模型
|
||
|
||
```text
|
||
Windows Client
|
||
|
|
||
TLS WebSocket (pairing/signaling)
|
||
|
|
||
remotedesk-agentd root/system service
|
||
|
|
||
authenticated Unix Socket
|
||
|
|
||
+---------------------------+
|
||
| |
|
||
remotedesk-agent-session remotedesk-shell-session
|
||
graphical user service target user process
|
||
| |
|
||
+----+---------+----------+ +--- PTY/login shell
|
||
| | | +--- reliable terminal channel
|
||
Portal/X11 PipeWire Encoder
|
||
| | |
|
||
libei/XTest video/audio H.264/Opus
|
||
```
|
||
|
||
### 2.1 remotedesk-agentd
|
||
|
||
系统守护进程由 systemd 启动,职责严格限制为:
|
||
|
||
- 维护被控设备身份和已配对客户端公钥。
|
||
- 提供配对及会话信令入口。
|
||
- 通过 logind 发现当前图形用户会话。
|
||
- 验证并联络对应的用户会话 Agent。
|
||
- 验证终端权限并创建已降权的 PTY 会话进程。
|
||
- 管理版本兼容、健康状态和升级切换。
|
||
- 按明确策略调用可选的最小权限 Helper。
|
||
|
||
它不得读取桌面帧、音频、剪贴板、终端或文件内容,也不得持有用户的 PipeWire 流。
|
||
|
||
### 2.2 remotedesk-agent-session
|
||
|
||
用户会话进程通过 `systemd --user` 启动,并绑定到图形会话生命周期。职责包括:
|
||
|
||
- 请求并恢复 RemoteDesktop/ScreenCast Portal 授权。
|
||
- 消费 PipeWire 视频和音频节点。
|
||
- 通过 libei/EIS 接收远端输入。
|
||
- 进行色彩转换、硬件编码和 WebRTC 发送。
|
||
- 管理用户剪贴板及文件接收确认。
|
||
- 在本地显示连接状态和终止入口。
|
||
|
||
注销用户时进程和所有远程会话必须结束。
|
||
|
||
### 2.3 remotedesk-shell-session
|
||
|
||
终端会话进程由 `agentd` 在授权后创建。它通过 PAM 建立目标用户会话,完成补充组、GID、UID、工作目录和环境降权,然后创建 PTY 并执行允许的登录 Shell。
|
||
|
||
每个终端连接拥有独立进程。进程只接收终端字节流、窗口尺寸、信号和会话控制消息,不具备读取桌面或其他用户会话的能力。配对授权可明确允许 `root`(UID 0)会话;未列入授权的用户仍会被拒绝。
|
||
|
||
## 3. 本地 IPC
|
||
|
||
`agentd` 与用户会话进程使用 Unix Domain Socket 通信。每个已登录用户拥有独立 Socket,目录由 systemd/runtime directory 创建,不使用可预测的 `/tmp` 文件。
|
||
|
||
IPC 连接必须验证:
|
||
|
||
- Socket 文件所有者和权限。
|
||
- 对端 UID、PID 和安全标签。
|
||
- 用户是否对应有效的 logind 图形会话。
|
||
- Agent 主次版本是否兼容。
|
||
- 每条会话请求是否携带短期、单次使用的随机令牌。
|
||
|
||
IPC 只传递配对后的客户端身份、会话控制消息和 WebRTC 信令,不转发视频帧或终端内容。
|
||
|
||
## 4. Agent 生命周期
|
||
|
||
```text
|
||
Boot
|
||
-> agentd Ready
|
||
-> Client Paired
|
||
-> Desktop: User Login -> session Agent Registered
|
||
-> Terminal: PAM Session -> shell Session Spawned
|
||
-> Session Requested/Negotiated
|
||
-> Streaming or Terminal Active
|
||
-> Disconnecting
|
||
-> Resources Released
|
||
```
|
||
|
||
任何阶段失败都必须反向释放已创建资源,包括 Portal Session、PipeWire Stream、编码器、WebRTC Peer 和临时令牌。
|
||
|
||
## 5. 首次配对
|
||
|
||
Agent 安装时生成设备身份密钥,私钥仅由 `agentd` 读取。配对流程:
|
||
|
||
1. Linux 本地用户在 Agent 状态界面开启配对,生成短时一次性配对码。
|
||
2. Windows 客户端输入地址和配对码。
|
||
3. 双方通过 TLS 交换设备公钥和能力摘要。
|
||
4. Linux 本地界面显示客户端名称和公钥指纹,用户确认。
|
||
5. `agentd` 保存允许的客户端公钥、权限和创建时间。
|
||
6. 配对码立即作废,后续使用设备密钥认证。
|
||
|
||
配对记录可以授予独立权限:查看桌面、控制输入、打开终端、剪贴板、音频、文件传输和无人值守尝试。撤销记录后,现有会话立即结束。
|
||
|
||
## 6. Wayland 捕获与控制
|
||
|
||
### 6.1 Portal 会话
|
||
|
||
用户会话 Agent 通过 xdg-desktop-portal 创建远程桌面/屏幕共享会话,选择显示器并请求键鼠控制。首次请求由桌面环境显示系统授权窗口。
|
||
|
||
Agent 记录以下能力,而不是假设存在:
|
||
|
||
- 显示器和窗口捕获。
|
||
- DMA-BUF 或内存帧。
|
||
- 键盘、相对鼠标、绝对鼠标和触控。
|
||
- Portal 恢复令牌及其持久模式。
|
||
- 剪贴板接口。
|
||
- 系统音频捕获。
|
||
|
||
如果某项能力不可用,客户端必须禁用对应按钮并展示具体原因。
|
||
|
||
### 6.2 PipeWire 视频路径
|
||
|
||
默认零拷贝路径:
|
||
|
||
```text
|
||
PipeWire DMA-BUF
|
||
-> GPU color conversion/scale
|
||
-> VA-API/NVENC/AMF encoder
|
||
-> encoded frame
|
||
-> WebRTC RTP
|
||
```
|
||
|
||
零拷贝成立必须同时满足:
|
||
|
||
- PipeWire buffer 带可导入的 DMA-BUF fd、modifier 和 fence/synchronization 信息。
|
||
- Agent 根据 DMA-BUF 的 DRM device/render node 选择同一物理 GPU 的 video processor 和编码器。
|
||
- 色彩转换与分辨率缩放在同一 GPU 或可验证的共享 surface 路径完成。
|
||
- 硬件编码器直接导入 GPU surface,Agent 不 map 原始像素,也不通过 `appsink` 取帧。
|
||
- buffer 生命周期延续到编码器完成消费,再归还 PipeWire;队列满时丢弃旧帧而不是复制保活。
|
||
|
||
不同驱动分别验证 VA-API、NVENC/EGL-CUDA 等实际导入路径,不能因为元素名称包含硬件编码器就判定零拷贝。DMA-BUF modifier 不兼容或发生跨 GPU copy 时,状态必须降为 `gpu_copy` 或 `cpu_upload`。
|
||
|
||
Agent GPU 策略:
|
||
|
||
- `capture_device`:默认,跟随 PipeWire DMA-BUF 或 Xorg DRI3 pixmap 所属 DRM render node。
|
||
- `manual(adapter_identity)`:只在所选 Adapter 能直接导入捕获 surface 时生效;严格模式不允许为使用另一块 GPU 而复制原始帧。
|
||
- 稳定身份使用 PCI/DRM render node/driver 组合,不能持久化临时枚举序号。
|
||
|
||
显式 compatibility 回退路径:
|
||
|
||
```text
|
||
PipeWire memory frame
|
||
-> software color conversion
|
||
-> hardware/software encoder
|
||
-> WebRTC RTP
|
||
```
|
||
|
||
每个帧对象必须引用计数并设置明确的所有权,避免 PipeWire 回调线程等待编码完成。捕获、编码和传输使用有界队列;出现积压时丢弃旧视频帧,不能阻塞输入和控制消息。
|
||
|
||
配置 `zero_copy_policy`:
|
||
|
||
- `required_end_to_end`:默认。Agent 端任何 CPU 映射、跨 GPU copy 或软件编码都会终止媒体协商;还必须等待客户端报告已验证的 D3D11 零拷贝路径。
|
||
- `compatibility`:仅由用户显式开启,允许 PipeWire memory frame、GPU upload 或软件编码,并显示实际回退状态。
|
||
|
||
### 6.3 输入模型
|
||
|
||
Windows 客户端发送统一输入事件:
|
||
|
||
- 键盘:USB HID Usage、按下/释放、修饰键状态。
|
||
- 文本:Unicode 文本提交,处理无法由物理键盘布局表达的字符。
|
||
- 鼠标:标准化绝对坐标、相对移动、按键和高精度滚轮。
|
||
- 显示:事件携带显示器 ID 与拓扑版本,防止分辨率变化后位置错误。
|
||
|
||
Agent 优先通过 Portal 提供的 libei/EIS 通道注入输入。`uinput` 仅作为明确开启的兼容性后端,并由独立最小权限 Helper 处理。
|
||
|
||
### 6.4 音频与剪贴板
|
||
|
||
- 系统音频从 PipeWire 获取,编码为 Opus。
|
||
- 麦克风回传后续增加,默认关闭。
|
||
- 剪贴板优先使用 RemoteDesktop 会话关联的 Portal 接口。
|
||
- 仅在桌面能力允许时启用图片或文件剪贴板。
|
||
- 剪贴板内容不写日志、不落盘,并设置单项大小限制。
|
||
|
||
当前 Portal 剪贴板尚未接入,Wayland 会话不得据此声明剪贴板能力。协议 minor 15 已实现的范围仅为 X11 与 Windows 控制 helper 之间的 UTF-8 文本:`clipboard_read` 和 `clipboard_write` 独立授权,发送方先 Offer,收到匹配 Request 后才发送最多 32 KiB 的 canonical Base64 Data;接收方验证 sequence、长度、SHA-256、UTF-8、NUL 和规范换行,并用最近内容摘要阻止回写循环。root `agentd` 只做方向授权和结构化消息转发,不调用 X11 或 Win32 剪贴板 API。
|
||
|
||
## 7. Xorg 捕获与控制
|
||
|
||
Xorg 后端由同一个用户会话 Agent 提供,但不复用 Wayland Portal:
|
||
|
||
- 从 logind 会话环境获取 `DISPLAY` 和对应用户的 `XAUTHORITY`。
|
||
- 使用 XRandR 枚举显示器及监听拓扑变化。
|
||
- 默认使用 XComposite 获取目标 pixmap、XDamage 跟踪变化,再通过 DRI3 `BufferFromPixmap` 导出 DMA-BUF 并直接交给同 GPU 硬件编码器。
|
||
- XSync/Present fence 或驱动等效机制负责生产者与编码器同步,未确认完成前不复用 pixmap buffer。
|
||
- XShm/XImage 只属于显式 `compatibility` 模式。
|
||
- 使用 XTest 注入键盘和鼠标,键盘事件沿用统一 HID/Unicode 模型。
|
||
- 画面进入与 Wayland 相同的编码、WebRTC 和质量控制管线。
|
||
- 音频继续通过 PipeWire 获取。
|
||
|
||
Xorg 只有在 XComposite/DRI3 导出的 DMA-BUF 成功直达同一 GPU 编码器且没有 CPU map 时才报告 `zero_copy`。驱动、合成器或 pixmap 格式不支持导出时,默认拒绝图形会话;用户显式选择 `compatibility` 后才允许 XShm/XImage,并在客户端持续显示性能降级。不可通过 `xhost +`、复制其他用户 Cookie 或关闭 X server 访问控制来解决权限问题。
|
||
|
||
### 7.1 多显示器捕获
|
||
|
||
Wayland Portal 和 XRandR 的显示器枚举统一转换为协议 `DisplayLayout`。稳定 ID 不使用数组索引;矩形保留主屏左侧/上方的负坐标,scale 使用有理数,布局变化递增 generation。用户可选择主屏、全部显示器或自定义子集。
|
||
|
||
Agent 对每个选中显示器分别记录捕获 surface、DRM Adapter、import probe 和原始矩形,再生成组合桌面边界与输入坐标映射。分辨率上限作用于组合桌面画布,在保留各屏相对位置和比例的前提下统一缩放,不改变 Wayland/Xorg 实体模式。热插拔、旋转、DPI、分辨率或选择变化会清除旧选择与编码证明、递增 pipeline epoch 并请求新关键帧。
|
||
|
||
严格零拷贝要求所有选中显示器都能导入同一个目标编码 Adapter,且每屏均无 CPU map、跨 GPU copy 或 opaque 路径。任一屏失败则整个多屏严格会话失败;Compatibility 可以逐屏记录 `CrossAdapterCopy`、`CpuUpload`、`Software` 或 `Opaque`,但不能把组合后的结果提升为零拷贝。
|
||
|
||
输入事件包含稳定显示器 ID、布局 generation 和源物理坐标。Agent 只接受当前 generation 且坐标位于对应显示器矩形内的事件,随后再映射到 libei 或 XTest,避免拓扑变化后点击错误屏幕。
|
||
|
||
## 8. 纯命令行终端
|
||
|
||
命令行模式独立于桌面媒体管线,适用于没有安装桌面环境的 Linux:
|
||
|
||
```text
|
||
Windows Terminal View
|
||
-> reliable DataChannel
|
||
-> remotedesk-shell-session
|
||
-> PTY
|
||
-> user login shell
|
||
```
|
||
|
||
终端协议包含原始 UTF-8 字节、窗口行列、POSIX 信号、退出状态和会话恢复序号。Windows 客户端使用终端模拟器解析 ANSI/VT 序列,滚动缓存保存在客户端。
|
||
|
||
安全规则:
|
||
|
||
- 设备配对权限必须单独允许终端。
|
||
- 配置将客户端设备映射到允许登录的普通用户。
|
||
- PAM 负责账户状态、时间限制和会话审计。
|
||
- 启动 Shell 前清理环境,只传递白名单变量。
|
||
- 禁止把用户传入内容拼接为 root 命令行。
|
||
- `sudo`、`su` 和审计策略完全遵循目标系统配置。
|
||
- 断线后只保留有限宽限期和有界输出环形缓冲区。
|
||
|
||
## 9. 差网络处理
|
||
|
||
Linux Agent 的媒体管线必须导出 TWCC/GCC 目标码率、RTT、丢包、抖动、NACK 和 PLI 指标。质量控制器按状态动态更新编码码率、帧率和缩放档位:
|
||
|
||
- 轻微丢包先降低码率,不立即降低桌面分辨率。
|
||
- 持续或突发丢包再降低帧率和分辨率。
|
||
- 收到 PLI 时请求 IDR,并限制关键帧频率。
|
||
- 输入和音频队列优先于视频。
|
||
- 严重丢包时暂停文件传输并限制剪贴板大对象。
|
||
- 网络恢复后使用较长窗口逐级升档。
|
||
|
||
分辨率请求作用于捕获后的 scaler/caps 和编码器,不修改 Wayland/Xorg 实体显示模式。Agent 公布源尺寸、最小/最大编码尺寸、像素数上限、对齐要求和是否支持运行时重配;请求越界时返回结构化错误或明确的 capability clamp。切换成功后递增 generation、请求关键帧,并重新发布源尺寸与实际编码尺寸。输入坐标始终基于源显示器拓扑映射,不以降采样后的编码尺寸直接注入。
|
||
|
||
鼠标移动允许丢弃过期事件,键盘和鼠标按键必须可靠发送。断线恢复后双方同步输入状态,避免远端出现卡键。完整策略见 [差网络自适应设计](network-adaptation.md)。
|
||
|
||
## 10. 媒体和控制协议
|
||
|
||
WebRTC 负责 DTLS-SRTP、媒体时钟、丢包反馈和拥塞控制。Agent 不自行设计视频网络协议。
|
||
|
||
控制消息使用版本化 Protobuf,并在 DataChannel 上传输。协议包头至少包含:
|
||
|
||
```text
|
||
protocol_major
|
||
protocol_minor
|
||
session_id
|
||
message_type
|
||
sequence
|
||
monotonic_timestamp
|
||
payload
|
||
```
|
||
|
||
兼容规则:
|
||
|
||
- 主版本不同则拒绝会话并返回升级提示。
|
||
- 次版本能力通过握手位图协商。
|
||
- 未识别的可选字段忽略,未识别的必需能力拒绝。
|
||
- 输入、心跳和媒体控制使用独立 DataChannel,避免大剪贴板阻塞输入。
|
||
|
||
## 11. 编码策略
|
||
|
||
第一版以 H.264 为强制共同编码格式,Opus 为音频格式。能力协商顺序:
|
||
|
||
1. 枚举客户端解码能力。
|
||
2. 枚举 Linux GPU 和驱动编码能力。
|
||
3. 将捕获 surface 的 DRM device 与编码器 Adapter 对齐,再选择双方都支持的编码器和像素格式。
|
||
4. 用短帧验证 DMA-BUF/GPU surface 是否在无 CPU map 的情况下被编码器导入。
|
||
5. 根据 `zero_copy_policy` 同时确认 Agent 编码路径和客户端解码/呈现路径;默认任一端失败即拒绝。
|
||
6. 会话中监控编码耗时,超限时降低帧率或分辨率。
|
||
|
||
办公模式对文字区域保留较高质量并降低静态刷新;动态模式缩短编码队列并提高帧率。HEVC、AV1 和区域编码在 H.264 稳定后增加。
|
||
|
||
## 12. 无人值守边界
|
||
|
||
Wayland 的安全模型决定了通用 Agent 不能无提示控制任意会话。
|
||
|
||
支持层级定义为:
|
||
|
||
| 等级 | 能力 | 首版 |
|
||
|---|---|---|
|
||
| L1 | 用户在线并确认本次 Portal 授权 | 支持 |
|
||
| L2 | 首次确认后,使用 Portal 恢复令牌再次连接 | 按桌面能力支持 |
|
||
| L3 | 用户已登录但锁屏 | 按发行版验证 |
|
||
| L4 | 显示管理器登录界面 | 不承诺,需按合成器适配 |
|
||
| L5 | 无显示器、无图形用户会话 | 桌面不支持;命令行支持 |
|
||
|
||
客户端必须显示目标机器当前支持的等级,不能把 L1 描述为完整无人值守。
|
||
|
||
## 13. 安装与升级
|
||
|
||
Linux 发布物至少提供 DEB 和 RPM:
|
||
|
||
```text
|
||
/usr/bin/remotedesk-agentd
|
||
/usr/bin/remotedesk-agent-session
|
||
/usr/libexec/remotedesk-shell-session
|
||
/usr/lib/systemd/system/remotedesk-agentd.service
|
||
/usr/lib/systemd/user/remotedesk-agent-session.service
|
||
/usr/share/applications/remotedesk-agent-settings.desktop
|
||
/usr/share/dbus-1/services/...
|
||
/usr/share/polkit-1/actions/...
|
||
```
|
||
|
||
安装脚本只创建系统服务、受限用户/目录和必要策略,不修改 SELinux/AppArmor 为宽松模式。升级采用先写新文件再切换的方式,协议不兼容时保留上一版本回滚能力。
|
||
|
||
当前 `0.2.9` 工程切片已经提供四个二进制、systemd system/user unit、静态 x64 便携包、musl DEB,以及 Ubuntu CI 的原生 DEB/RPM 构建。`agentd` 可完成设备身份、一次性配对、证书指纹固定、Ed25519 客户端认证、终端授权和文件传输;用户会话进程通过 `SO_PEERCRED` 校验的 Unix Socket 注册;终端 helper 通过 `runuser --login` 建立 PAM/PTY 会话,文件 helper 以授权普通用户身份将路径限制在用户主目录并执行大小/SHA-256 校验,协议 minor 4 还通过目标端实测 partial offset 和整文件重新哈希支持上传/下载断点续传,Windows 控制端已包含配套 helper。可选 Edge 客户端注册 60 秒 Presence 路由、每 30 秒续期、失败有限退避并在 SIGINT/SIGTERM 时限时注销;在线时每次信令 poll/ack 都使用设备私钥、时间戳和一次性 nonce 签名。普通 Intent 重新验证已配对 Client、permission 和 allowed user;`pairing` Intent 只在 Agent 本机配对窗口有效时签发 relay,真正的一次性码仍在证书固定 TLS/WSS 内验证和消费。授权后 Agent 使用独立一次性票据主动连接 relay 并透明代理到本地 TLS listener。Windows 控制端录入 `pairing-code` 输出的设备公钥和证书指纹即可远程首次配对;成功后按证书指纹记录 Agent 公钥,后续已知设备同样无需 Client 连接 Agent 地址。`status --json` 和 WSS Hello/Status 会报告在线、信令能力、接受/拒绝计数和清洗后的错误,状态文件不含 URL、令牌、请求或配对码。
|
||
|
||
协议 minor 10 的源码包含 X11 兼容桌面:用户会话以 UID 固定的 `0600` Socket 注册 X11 捕获端点,Agentd 再次核对 Socket peer PID/UID;root window 在源尺寸和像素上限验证后通过 `GetImage` 捕获,XTEST 输入根据当前用户 X server 的 keyboard mapping 解析 keysym。输入覆盖缩放绝对坐标、有界相对移动、五键鼠标、水平/垂直滚轮和键盘;Windows helper 显式抓取光标后合并 Raw Input 位移,失焦、重连和退出会解除抓取并释放输入。帧使用有界 zlib BGRA 分块、整帧 SHA-256 和成功呈现后的逐帧 ACK,Windows 控制 helper 新增等比例软件 framebuffer、黑边输入排除、全屏与退出;跟随窗口模式合并 500 ms 内的连续变化,并在当前帧 ACK 后动态重配下一帧的 200..8192 捕获上限,不修改 Xorg 实体模式。Agent 根据真实编码耗时和呈现 ACK 调整 1..30 FPS,zlib 模式另在 level 1..6 内调整压缩。异常断线按 1、2、4 秒最多重连三次;用户会话进程会先释放全部 XTEST 输入,再保留 15 秒 X11 连接、帧序列和自适应控制器,恢复令牌绑定 Client 指纹和 Linux 用户。每次 UI 启动会生成受限会话 ID,helper 只写不含地址、用户或凭据的诊断,并回传 RTT、压缩比例和采集/编解码/呈现耗时。接受的 Edge 桌面会话在 Agent/Client 两端创建真实 WebRTC PeerConnection;用户会话复用同一次 BGRA 捕获,以 GStreamer 选择 VA/VAAPI/NVENC/QSV/OpenH264/x264 编码器,输出 Annex-B AU。AU 通过 16 MiB 总上限、45 KiB 分块、严格顺序、canonical base64、精确长度和 SHA-256 的内部 IPC 后,由 agentd 交给绑定 session 过期时间、目标用户和 Client 指纹的 H.264 sender;断开时撤销。Windows helper 使用单 NAL/STAP-A/FU-A 重组、跨帧序号检测、PLI/关键帧恢复和一槽有界媒体邮箱,再经 Media Foundation H.264 MFT 输出同 device NV12 surface 并由 D3D11 VideoProcessor 呈现。第一张原生帧呈现后双方确认 H.264-only,停止完整 zlib 编码和传输;每张 H.264 的 sequence 呈现 ACK 驱动下一次捕获。解码、媒体、sender/encoder 或 ACK 失败会显式恢复 zlib。协议 minor 11 的 Wayland 源码在认证后请求 Portal,只接受单显示器 DMABUF 到 VA H.264 严格管线,首个 IDR 与 `reis` EIS Sender/设备/XKB keymap 就绪后才打开会话;媒体复用相同有界 H.264 IPC、WebRTC sender 和 Windows 呈现 ACK,输入按 stream/region `mapping_id` 注入,resize 先停止旧管线再重建并等待新 IDR。协议 minor 12 在意外断线时释放全部 EIS 输入和旧编码器,把 Portal/EIS 置入绑定 Client 指纹、Linux 用户及轮换令牌的 15 秒租约;新 WebRTC sender 就绪且绑定校验通过后才消费租约、重建编码器并从新 IDR 恢复。协议 minor 13 复用同一媒体内核,经证书固定和 Ed25519 认证后的直连 WSS 交换有界 SDP/ICE,并把授权精确绑定 Client 指纹、Linux 用户、尺寸和 FPS;只有 PeerConnection connected 且双方 ICE 完成后才进入桌面协议,失败则显式同步 abort/unavailable。minor 14 增加默认关闭的 `opus_audio` 协商,只捕获 Linux 系统输出 monitor,以固定 48 kHz 双声道、20 ms Opus 经 4 KiB 有界 IPC 和 SRTP 发送;Windows 使用有界队列、IronRDP Opus 解码和 WASAPI 播放,音频失败不会关闭视频,minor 13 及更旧客户端不会收到音频事件。显式关闭、媒体/输入错误和超时仍立即关闭 Portal。新增路径按要求尚未解析依赖、编译或在真实 GNOME/KDE/VA/音频设备上运行,因此相关运行时能力仍受保守平台开关控制。
|
||
|
||
协议 minor 15 进一步把 X11 selection、Windows `CF_UNICODETEXT` 工作线程和桌面协议状态机接通。用户会话只在 `clipboard_read` 为真时轮询并 Offer 本地 X11 文本,只在 `clipboard_write` 为真时接受 Client Offer、请求并写入;Windows 侧使用有界线程和 channel 隔离同步 Win32 API。该源码尚未编译或在真实 Windows/Xorg 剪贴板所有者之间验收,Wayland 剪贴板仍关闭。
|
||
|
||
Edge Presence 默认关闭。只有同时设置 `REMOTEDESK_EDGE_API_URL`、`REMOTEDESK_EDGE_PRESENCE_TOKEN`、`REMOTEDESK_EDGE_REGION`、`REMOTEDESK_EDGE_GATEWAY_ID` 才会启动;缺少任一项会拒绝启动。公网 URL 必须为 HTTPS,HTTP 仅允许 loopback,Presence 令牌至少 32 字节且必须与管理员令牌、票据密钥分离。安装包只附注释模板,不生成或携带凭据。
|
||
|
||
Windows 控制端可在全局设置中保存无凭据的 Edge HTTPS Origin。首次配对时同时填写 Agent 本地命令输出的 `device_public_key` 和证书指纹,即可经 Edge 建立;缺少其中一项时 helper 保留直连回退。配对后 helper 把 Agent 公钥保存到 `RemoteDesk/Linux/agent/<certificate-sha256>`,该值不是秘密,但会决定 Edge 请求的目标设备身份,必须按完整性敏感数据保护。Linux helper 使用现有 Credential Manager Client key 公开提交签名 Intent,并以原始签名认证状态查询;它不接收 Edge 管理员或 Presence 令牌。Agent 返回授权后,两端分别使用角色绑定一次性票据连接 relay,终端和文件字节在 relay 内重新建立的证书固定 TLS/WSS 中传输。公网 relay authority 必须经系统信任 TLS/L4 入口发布,raw TCP 只允许 loopback。控制端 Linux Terminal 面板可查询或显式删除映射;删除后可再次经 Edge 或直连配对。
|
||
|
||
## 14. 安全检查项
|
||
|
||
- system daemon 媒体零接触。
|
||
- 所有外部输入先做长度、枚举和状态验证。
|
||
- 配对码限时、限次并带失败速率限制。
|
||
- 客户端权限可查看、修改和撤销。
|
||
- Portal 授权状态在 Linux 桌面上始终可见。
|
||
- 文件传输需要每次确认,保存路径不可目录穿越。
|
||
- 依赖生成 SBOM,并持续跟踪 GStreamer/WebRTC/PipeWire 安全更新。
|
||
- 崩溃转储默认排除视频帧、密钥和剪贴板缓冲区。
|
||
|
||
## 15. 首个开发切片
|
||
|
||
开发拆成三条窄路径,按顺序打通:
|
||
|
||
1. 基础:`agentd`、设备配对、受认证 IPC 和会话状态机。
|
||
2. 桌面:先打通 GNOME Wayland Portal/PipeWire,再复用媒体管线增加 Xorg/XDamage 后端。
|
||
3. 终端:完成 PAM 降权、PTY、可靠 DataChannel 和 Windows 终端控件。
|
||
|
||
三条路径稳定后再增加硬件编码验证、剪贴板、多显示器、KDE 和持久授权;系统输出 Opus 已进入源码链路,但仍需平台验收。
|