原生节点、路由与文件同步

两种权威模式使用相同工具。server 是 ssh_list_servers 的名字;@local 是正在执行工具的伴随器电脑。deviceId 是原生身份的稳定 UUID,中心中的另一个 @local 不代表当前电脑。地址必须注明所在设备,不能把多台机器的 127.0.0.1 混为一处。

节点和连接

  1. 用 ssh_node_manage install 安装被授权的服务器节点,或用 server=@local 初始化本机内嵌身份。包内已带两平台程序,无需安装 FRP 或完整 EasyTier。
  2. configure 使用 inspect 返回的 revision 和公钥,只授权所需目标、反向监听、发现对等点或短期文件根。P2P 配置支持 UDP/QUIC、TCP 及 auto。公网协助者只发布候选地址,除非另有明确转发授权,不承担业务数据转发。
  3. start 启用该节点,pair 配对已有节点;双方 connectivity 必须启用。若用协助者,其 coordinate 能力、互相发现权限和可达地址均需具备。pair 的 forwards 可省略,文件同步仅需要身份和原生链路。
  4. inspect 检查 loaded revision、实际 transport/peer、错误和时间戳,再通过普通 SSH 或文件操作验收。revoke 撤回某 peer 并持久化拒绝记录;后续路由重编译不会擅自恢复权限。用户显式配对/配置才可重新授权。
  5. upgrade 切换已安装节点版本,保持身份;停止的节点保持停止。Windows 服务升级会确认旧服务已停止,再启动替代程序;超时失败时检查回执中的恢复状态。uninstall 退役该实例的服务和目录登记,保留身份/不可变发布文件以供恢复;仍被共享资源引用时拒绝。本机启动项见 INSTALL.md。伴随器版本交接会重建内嵌节点传输;进行中的原生流可能中断,命令不自动重放,已验证文件块可继续复用。

NAT 规则会影响穿透;TCP/QUIC 都不能保证所有网络可达。自动协议选择和允许 SSH 回退是不同选项,结果会标出实际采用的路径。

节点安装、配置、升级、撤权和资源探测沿目录中管理 profile 的原 SSH/ProxyJump 路径执行,使用独立连接池;普通命令和文件继续沿所选数据路由执行。管理 profile 必须具备可用的独立 SSH 通路,数据路由退役不会撤掉该管理访问。ssh_connection_status 分别列出普通连接和 management_connections。

路由与共享资源

ssh_node_manage discover 先登记已有机器身份;它可用于没有原生节点的历史 SSH 隧道设备。ssh_route_inspect 返回目录中的设备、期望路由、资源及时间戳观测;probe=true 增加当前设备的 SSH 认证和所选资源的服务/监听检查。大量资源用 resourceIds 分批选择。监听可达不是目标 SSH 身份验收。

ssh_route_plan 支持 create/update/adopt/repair/disable/remove/rollback。完整 SSH 跳板链使用 via;原生入口额外指定 sourceDevice、sourceInstance 与 ingress。resourceIds 把路由与资源关联,resources 提交节点、反向通道、转发或历史 SSH 服务的结构化变更。资源有独立 owner、revision、dependencies、enabled 和 persistent。精确对象字段见 tools.json。

plan 只保存五分钟方案,不改变网络;检查方案后用其 planId 和 expectedRevision 调用 ssh_route_apply。apply 记录运行意图,应用节点权限、验证原始目标 SSH 身份后提交。旧命令不重放;共享节点/权限只在最后一项相关资源退役时清除。外部服务接管需匹配现有可执行文件、启动配置与真实 SSH -R 映射,不按备注猜测。共享映射、孤立进程或会切断管理通路的停止操作会被拒绝。手动启动且没有监督者的 SSH 反向进程使用 external 的 backend=process、persistent=false 登记;service 此时是观测标签。它只记录进程和地址关系,不允许 start/stop/repair,移除记录不会结束原进程。

发生失败时看 apply 收据。只有仍持有有效执行租约、且节点没有独立修改时才能自动恢复;超时或部分恢复会标为 recovery_required。依据实时 inspect 建立新 repair 方案,不能盲目重放旧方案。

单源多端分发

{
  "source": {"id":"origin","server":"@local","root":"/home/me/data"},
  "targets": [
    {"id":"b","server":"device-b","root":"/srv/data"},
    {"id":"c","server":"device-c","root":"C:\\Data"}
  ],
  "options": {"dryRun":true,"delete":false,"compression":"auto","timeout":300000}
}

复制根目录中的内容,不额外套一层根目录名。先只读预览,再使用相同参数并把 dryRun 改为 false。远端需先安装 v6 原生节点/文件助手。delete=true 才删除目标多余文件;排除项保护匹配的子树。普通上传下载沿当前 SSH 路由执行;此工具为同步提供清单、内容哈希、块复用、断点续传、压缩和原子提交。

原生文件控制使用当前连接器的主 @local 节点(安装、启动时省略 instance),它需与每个远端配对;远端之间还需彼此配对。一项原生操作每台设备使用一个根目录。远端到远端优先由接收端拉取,A 端只协调。原生链路不可用时,默认不通过 A 端中继文件;仅在用户允许时传 allowRelay=true。中心始终不接收文件字节。transport=p2p 要求原生链路,ssh 使用各端 SSH 路由,auto 优先原生。回执记录来源/目标、实际数据路径、字节统计、失败项和清理结果。文件载荷统计不含协议头;失败传输的总字节数无法确认时,byteCountsComplete=false、filePayloadBytes=null,committedFilePayloadBytes 只计已确认提交的文件。

原生同步的主控和文件端点应使用配套候选程序;从早期 6.0 候选更新时,先用 ssh_node_manage upgrade 更新文件端点。同步会合并节点控制请求,并行扫描、授权和连接不同端点,逐文件提交与冲突顺序保持有序。

timingsMs 分别记录端点扫描、规划/租约、授权、建连、执行、收尾和撤权的墙钟耗时;它们与各端文件数据阶段的 transferMs 不同。scanMs 仅汇总端点本机扫描时间。工具返回的 elapsedMs 包含本次执行及授权清理;完整调用还可能包含入口的目录加载和 IPC 等待。持久收据的耗时截至最后一次收据写入之前。

双向同步集

先创建持久同步集:

{
  "action":"create",
  "name":"共享资料",
  "participants":[
    {"id":"a","server":"@local","root":"/home/me/shared"},
    {"id":"b","server":"device-b","root":"/srv/shared"}
  ],
  "propagateDeletes":true,
  "exclude":[".git","**/*.tmp"]
}

后续执行 {"syncSet":"返回的 UUID","options":{"dryRun":true}} 或去掉 dryRun 正式运行。list 查同步集,inspect 查策略、版本、墓碑和最近收据。参与设备、排除项与删除策略由同步集固定,不可在 run 中临时改写。

各端修改用因果版本比较。并发编辑保留确定命名的 .sshmcp-conflict-<内容哈希> 副本;删除与编辑并发时保留编辑。已观察到的删除保留版本墓碑,离线旧副本再次上线不会被误认为新修改。未能读取的端和缺少的内容会延期并报告;先保留冲突内容,再替换原路径。

同步集最多 8 个参与端、4096 个跟踪文件,组合清单最多 100000 项;大目录按独立职责拆分。双向集跟踪普通文件及其必要父目录,空目录不作为因果版本对象。同步按工具调用执行,没有默认持续监控。各文件原子提交,整批不是跨设备事务。

文件授权

原生文件能力绑定已认证身份、绝对根目录、操作权限和最长 24 小时的任务有效期。根目录身份固定;拒绝符号链接、硬链接、Windows 保留名与目录穿越。接收端只能向任务中声明的来源拉取。取消、超时和撤权阻止后续提交;已验证的临时块可用于恢复,正式文件只有完整哈希通过才替换。

所有工具 timeout 是毫秒;文件任务 expiresAt 是 Unix 秒时间戳。只读预览不会创建目标目录、临时文件、文件授权或同步基线。

失败回执中的 filePayloadBytes=null、byteCountsComplete=false 表示实际传输字节数不完整。dataPaths、remoteDataPath 和 committedFilePayloadBytes 只汇总已经完成的文件操作;发生中断时不能据此推断网络从未发送数据。