Files
nyaterm/docs-site/docs/guide/sync-and-backup.md
T
Kang 9c17cb6b2f feat(sync): introduce cloud synchronization features with encryption and AI configuration
- Added new modules for cloud synchronization, including `sync_schema`, `encryption`, and `ai`.
- Implemented encryption for credential values to enhance security.
- Introduced AI configuration policies and structures for managing AI-related data.
- Enhanced `CloudSyncRemote` trait with methods for writing and listing sync files.
- Updated `Cargo.toml` and `Cargo.lock` to include new dependencies and workspace members.
- Added tests for new functionalities to ensure reliability and correctness.
2026-10-30 20:04:25 +08:00

327 lines
17 KiB
Markdown
Raw 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.
# 云同步
## Cloud Sync V3 预览
设置中的 **Cloud Sync V3** 提供独立的 V4 同步空间,首批支持 WebDAV、S3 和本地目录后端。选择 V3 后先保存设置,再生成同步预览。确认时会重新检查本地数据和已可见的远端发布;预览过期时须重新生成。
连接、分组、代理、隧道、快捷命令、笔记、自定义图标和主题按稳定 ID 合并。不同字段可自动合并,同字段冲突保留候选和本机当前值;可以在预览中选择候选,也可以先同步无冲突部分。删除和并发编辑会保留存在性冲突。外观偏好可单独开启,仅同步主题、终端字体、光标和对比度白名单。快捷键是独立的可选范围,按操作合并;关闭后保留已有配置。
首次确认会在配置目录创建并回读验证加密的 `cloud-sync-v3-safety-<id>.nya` 备份。旧云端数据保留,检测到旧客户端后续写入时暂停自动同步;可手动生成导入预览,确认后保留双方资源和冲突候选。V4 的合并结果先原子应用到本机,再发布;上传失败显示“等待发布”,重试会复用已保留的精确密文。已完成回读验证的状态会单独显示。
AI 非敏感配置是独立的可选范围,包含供应商配置、手动添加的模型、自定义操作及默认模式。API 密钥和请求头由独立的敏感数据范围控制;代理、执行权限、外部工具路径和自动发现的模型保留在本机。未开启敏感数据同步时,涉及本机密钥的地址变更和删除会暂缓,需先在本机编辑确认。无效引用、循环和不完整配置也会暂缓相关原子组;预览列出暂缓字段,其他有效修改继续应用,完整候选保留在副本中。
密码、私钥、凭据、OTP、连接/代理密码及 AI 密钥可在独立的敏感数据范围中开启,默认关闭。因果副本只保存版本引用,值使用独立加密对象;接收后用本机密钥重新加密。SSH/VNC 信任范围也默认关闭,每项收到的身份新增、变更和删除都须在本机预览中单独确认;自动同步不会授予信任。关闭范围保留已有数据,重新开启会重新合并。其他 Provider 的 V4 写入尚未开放。引用缺失凭据的认证组会暂缓,待接收设备补齐本机凭据后重新应用。原有 Provider 的旧协议入口保留;选择 V3 后不会因失败而自动写回旧协议。自动双向同步要求首次迁移已确认、自动推送和拉取均开启,并且没有活动会话或未保存设置。
完成 V3 迁移后,在安全设置修改主密码会先发布并回读验证新的 `rotation-<id>` 子空间,再原子切换密码、远程命名空间和本地副本。失败或上传期间有新的本地编辑时,原密码和原空间继续有效;重试复用已保存的密文。旧空间保留,其他设备须使用新的命名空间和密码接入。云账户/范围变更须与改密分开保存。已有 V4 副本时不能直接关闭主密码。
下面介绍的是保留用于兼容的旧快照协议与 Provider 设置。`.nya` 始终是独立备份,不携带 V4 Writer 身份、发布历史或同步副本。
NyaTerm 的 **云同步** 能力,解决的不是“远程文件传输”,而是把应用里的可移植配置数据同步到一份加密的远端核心快照。
远端使用不可变快照和每台设备独立的提交记录:
- `sync/snapshots/<revision>.redb.enc` 保存加密快照,是当前协议的正常数据路径
- `sync/heads/` 保存每台设备的提交记录及上传中的临时标记,用于识别并保留并发修改
- `sync/latest.redb` 保存供兼容读取使用的最新 revision、设备、时间和 hash 元数据
- `sync/current.redb.enc` 是尽力更新的兼容/恢复副本,不是唯一权威数据源
两台设备同时推送时,各自的提交都会保留;下一次检查发现并发分支后,会要求明确选择本地或云端。远端存储若存在可见性延迟,冲突可能在后续检查才出现。判断先后关系使用因果记录,不依赖设备时钟。
`.nya` 本地导出 / 导入仍然是配置备份和迁移入口。云端旧快照会按保留策略清理;设备正在引用、尚未解决的并发分支及上传中的快照受到保护。云同步不会自动删除用户云端已有的旧 `backups/` 数据,保留的快照也不替代独立备份。
当前支持这些远程存储提供方:
- **WebDAV**
- **S3 兼容**存储
- **Gitee 代码片段(Gitee Snippet)**
- **GitHub Gist**
- **Google Drive**
- **OneDrive**
- **AliyunDrive**
## 先决条件:先设置主密码
在使用 **设置 → 云同步** 前,你必须先到 **设置 → 安全** 设置 **主密码**。
这是硬性前置条件。没有主密码时:
- 不能启用云同步
- 不能执行测试连接、推送、拉取等手动操作
上传到云端的是**加密后的可移植快照**。新快照使用随机盐的 Argon2id 派生密钥,再通过 AES-256-GCM 加密和认证;版本头、参数、盐和 nonce 也参与认证。
旧 NyaTerm 和 Dragonfly 快照仍可读取。下次实际上传或显式覆盖会写成新格式;仅检查到内容相同不会重写旧密文。新格式需要所有参与同步的设备升级到支持它的版本,旧客户端无法解密新快照,也不具备新的并发保护。升级前建议保留本地 `.nya` 备份。
升级后第一次检查,如果旧同步基线无法证明完整数据未变,可能需要手动确认冲突;这是为了保护此前未计入变更 hash 的 VNC 信任记录和扩展数据。
## 从哪里进入
这项功能主要有两个入口:
### 1. 设置 → 云同步
这里是主要配置页,负责:
- 选择 provider
- 配置远程命名空间与 provider 根路径
- 设置自动同步策略
- 运行测试连接、立即推送、立即拉取
- 在冲突发生时执行处理
### 2. 工作区中的 Cloud Sync / 云同步面板
主工作区侧栏里的 **云同步** 面板用于查看:
- 当前状态
- 最近的同步活动
- 最近一次检查、同步时间
- 冲突状态与快速处理入口
改配置去设置页,看运行状态看工作区面板。
## Provider 配置
### 通用项
无论使用哪种 provider,都需要先确认这几项:
- **启用云同步**
- **存储提供方配置**
- **设备名称**
- **远程命名空间**
其中:
- **设备名称** 会写入快照元数据,方便你识别是哪台设备上传的内容
- **远程命名空间** 是 NyaTerm 在远端保存云同步快照时使用的顶层路径前缀
### WebDAV
如果 provider 选的是 **WebDAV**,通常需要填写:
- **WebDAV Endpoint**
- **Provider Root**(可选)
- **用户名**
- **密码**
WebDAV 认证同时支持 **Basic** 和 **Digest** 两种方式。当服务端要求 Digest 时,NyaTerm 会自动改用 Digest,以提升对 NAS / 网关的兼容性。
### S3 兼容存储
如果 provider 选的是 **S3 兼容**,通常需要填写:
- **S3 Endpoint**
- **Bucket**
- **Region**
- **Provider Root**(可选)
- **Access Key ID**
- **Secret Access Key**
- **Session Token**(可选)
- **Virtual Host Style**(按 provider 要求决定是否开启)
### Gitee 代码片段(Snippet)
如果 provider 选的是 **Gitee 代码片段**,NyaTerm 会把加密后的云同步对象保存到一个 Gitee 代码片段中。
Gitee 的文件数量限制也适用于快照、设备提交及临时标记。设备较多或保留了多个冲突分支时,可能需要使用新的代码片段或更换存储提供方;不会为了腾出位置删除未解决的分支。
通常需要填写:
- **Gitee 个人访问令牌(Personal Access Token)**
- **代码片段 ID**
### GitHub Gist
如果 provider 选的是 **GitHub Gist**,NyaTerm 会通过 GitHub device flow 授权,并把加密后的云同步对象保存到一个私有 Gist 中。
通常需要:
- 点击 **连接 GitHub**
- 在浏览器打开的 GitHub 授权页面输入设备码
- 授权 `gist` scope
在 GitHub device-flow 授权流程中,如果没有填写 Gist ID,NyaTerm 会在授权成功后自动创建并回填一个私有 Gist;已有 Gist ID 时,会先验证并复用该 Gist。
### Google Drive / OneDrive / AliyunDrive
如果 provider 选的是 **Google Drive**、**OneDrive** 或 **AliyunDrive**,NyaTerm 会通过桌面端原生 HTTP adapter 访问对应网盘服务。
当前需要手动填写 OAuth 信息:
- **Refresh Token**
- **Client ID**
- **Client Secret**
- **Access Token**(可选,长期同步建议依赖 Refresh Token)
- **Provider Root**(可选)
AliyunDrive 还需要填写 **Drive Type**,通常为 `resource`。
### 配置校验
当前实现会先做最基本的 provider 校验:
- WebDAV 至少需要填写 endpoint
- S3 至少需要填写 endpoint 与 bucket
- `Access Key ID` 和 `Secret Access Key` 需要成对出现
- GitHub Gist 需要完成 GitHub 授权;Gist ID 可以在授权流程中自动创建并回填,也可以使用已有 ID
- Google Drive / OneDrive / AliyunDrive 需要填写 Refresh Token、Client ID、Client Secret
建议在真正启用自动策略前,先执行一次 **测试连接**。
## 自动同步策略
### 启动时检查
开启后,NyaTerm 会在启动时检查远端是否已经有新的同步快照。
常见结果包括:
- 本地与云端一致
- 远端有更新,可以拉取
- 本地有尚未同步的变化
- 本地和云端都变了,进入冲突状态
所有 Provider(包括 GitHub Gist)还会每 15 分钟检查一次;窗口重新聚焦时也会检查,聚焦检查至少间隔 120 秒。关闭“启动时检查”只跳过启动检查。失败时会退避重试,限流时遵守服务端有效的 `Retry-After`;认证失效会暂停,修改设置后恢复。
### 自动拉取远端变更
开启 **自动拉取远端变更** 后,如果启动检查或同步检查发现“只有远端发生变化”,NyaTerm 会自动拉取并应用当前云端快照。
它只处理本地没有未同步变更的情况;存在活动会话或未保存设置草稿时,会等到安全后再拉取。本地和云端都变了时仍然进入冲突状态,不会自动选一边覆盖另一边。
### 本地变更后的自动推送
开启后,当受支持的本地配置数据发生变化并保存完成时,NyaTerm 会在一个防抖窗口后自动推送快照。
你可以设置:
- **同步防抖秒数**
它是「保存后延迟推送」,不是实时双向同步。
## 手动操作
### 测试连接
先验证 provider 配置与远端布局是否可用。
### 立即推送
把当前设备的可移植配置快照上传到云端。用于刚完成一组设置调整后,或需要明确控制何时写入云端时。
### 立即拉取
把云端当前最新同步快照拉回本地并应用。用于另一台设备已经推送过更新,需要让当前设备显式对齐时。
## 冲突是怎么出现的?
如果**本地状态**和**云端状态**自上次同步后都发生了变化,就会进入冲突状态。
典型场景:
- A 设备改了设置但还没拉取 B 的更新
- B 设备已经把新的同步快照推到了云端
- A 再尝试推送或启动检查时发现双方都变了
这时你会看到冲突预览,例如:
- 本地快照哈希
- 远程 revision
- 远程设备信息
- 当前云端快照时间与 hash
- 冲突提示信息
## 冲突怎么处理?
当前实现提供两种处理方式:
### 下载远程版本
分支列表显示每个并发 revision、设备名称(旧快照显示缩短的 UUID)、时间、可读状态及差异数量。仅有一个可读分支时自动选中;有多个可读分支时必须先选择。差异摘要仅展示已知集合新增、删除、修改数量、设置分类以及未知实体是否变化,不显示凭据、OTP、笔记或命令正文。
把选定的远端快照拉回当前设备并应用。**当前设备上未同步的本地变更会丢失**,选它之前先确认云端版本是要保留的那份。
### 上传本地版本
用当前设备的本地快照解决当前预览中已观察到的分支。确认时会重新校验本地内容、所选快照和分支集合;发生变化会刷新预览,要求再次确认。**远端那份变更会被覆盖**,其他设备后续会以这份状态为准。
这里要特别注意:
- 当前不是字段级 merge
- 也不是多人协作式冲突解决
- 本质上是“本地快照”和“远程快照”二选一
NyaTerm 保留独立的设备提交和因果记录。明确选择本地或云端会生成覆盖已观察到分支的新提交;选择云端时会固定使用预览中明确选定的 revision。若其他设备随后提交新的并发修改,仍会再次提示冲突。`sync/snapshots/` 是现行协议的数据路径,不要手动清空。
## 会同步哪些内容?
当前实现基于 **portable snapshot**,覆盖的是 NyaTerm 的可移植配置数据,例如:
- 已保存连接 / 分组
- 密钥、密码、OTP 配置
- 代理与隧道
- 快捷命令
- 大部分应用设置
- known_hosts 与主密钥 token
命令历史不会进入云同步核心快照;如需离线留档或迁移,使用本地 `.nya` 导出 / 导入。
当前实现会保留一部分设备本地 UI 状态,例如:
- 当前打开的标签页
- 面板开合与尺寸等运行态布局
所以它同步的是可移植配置,让多台设备共享当前核心配置状态,不是完整的桌面会话镜像。
## 建议的首次配置顺序
首次启用按这个顺序:
1. 在 **设置 → 安全** 中设置主密码
2. 打开 **设置 → 云同步**
3. 先选 provider,再填写 endpoint / bucket / root / 凭据
4. 设置设备名称与远程命名空间
5. 先执行 **测试连接**
6. 再决定是否启用:
- 启动时检查
- 自动拉取远端变更
- 自动推送
7. 最后手动执行一次 **立即推送**,确认整条链路可用
## 凭据、设备名称与活动历史
三个网盘刷新令牌后,会先加密保存新的 Access Token 和服务端返回的 Refresh Token,再继续认证请求;未返回 Refresh Token 时保留原值。保存失败会停止操作,后续同步失败或取消不会撤销已完成的令牌保存。未编辑的设置令牌字段会跟随轮换更新,显式编辑的凭据仍需通过保存冲突检查。
设备名称保存在加密快照中;UUID 仍是设备身份。名称修改在下一次实际发布时生效,不会仅为改名重新上传。
自动上传、下载、冲突、失败和恢复成功会由进程统一写入活动历史,多窗口共享一条记录。无变化、忙碌、防抖或禁用检查不会刷屏;相同错误分类、触发原因和 revision 在 15 分钟内去重。错误只包含受控分类、Provider、操作和 HTTP 状态,不包含请求 URL、签名地址或响应正文;历史写入故障不会改变已经成功的同步结果。
## 后台检查与流量
自动检查先检查指针和全部设备提交,已验证且未变化的快照最多每 24 小时完整下载校验一次。轻量检查不会延长这个期限。S3 支持 ETag 条件请求时,未变化的指针返回 304,设备提交可以复用本次列表确认的缓存;服务不支持时退回普通 GET。
其他 Provider 仍需传输各自的指针和目录 API 响应;Gist/Snippet 的容器响应还可能包含文件内容。因此每日校验限制针对显式快照读取和验证,不能保证每个 Provider 的网络正文都只包含元数据。
缓存由同一进程的窗口共享,关闭应用后丢弃。首次启动、切换远端配置或账号、轮换凭据、修改主密码、缓存淘汰及分支变化都可能增加完整读取。实际推送、拉取、恢复和冲突确认仍验证快照;每日历史清理、上传回读及兼容副本也会产生流量。
本地变更通知没有改变实际同步内容时,可以跳过联网。持续编辑不会推迟定时远端检查,但上传仍等待防抖结束。最近成功的手动或自动检查会推迟下一次定时检查,并在 120 秒内抑制聚焦重复检查;测试连接不算完整检查。关闭“启动时检查”不会关闭 15 分钟定时检查。
日志提供受控的操作汇总:请求数、上传和下载正文的字节、304、缓存命中及完整校验次数。所有 Provider 均在 HTTP 边界统计,包含认证重试和已读取的错误正文;上传字节为每次尝试提交的正文大小,下载字节为应用实际读取量,不包含 HTTP 头和 TLS 开销,不能直接视为云厂商账单。日志不包含地址、对象路径、ETag、凭据或同步正文。实际流量取决于在线时长、设备数、快照大小、变更、重试和存储服务能力。
## 排障建议
按钮不可用或操作被拦住时,依次检查:
- 是否已经设置主密码
- 当前设置是否已经保存(未应用的草稿会阻止某些手动操作)
- provider 必填项是否已经补齐
- 远端命名空间、provider root、endpoint 是否填写正确
查看最近发生了什么看工作区的 **云同步** 面板,改配置回设置页。
:::tip 使用建议
- 首次接入新 provider 时,先“测试连接”,再启用自动策略。
- 做较大范围的连接、OTP、快捷命令调整前,如果需要可回退点,请先使用本地 `.nya` 导出。
- 在多台设备之间切换时,统一远程命名空间规则,并给每台设备设置可区分的设备名称。
:::