NS · Quick 模式
状态:v1,已被取代。 自 2026-10-04 起 ns 只实现 Quick 协议 v2(分支
refactor/nsplane),v1 的quick-runtime、配对令牌、/quick/v1会合与quick.internal名字已从 ns 删除;本页描述的是nsmaina05b6f55与nsgwmain3d31b5f上的 v1 实现,其中 relay 侧(nsgw-quick-relay)至今仍是 v1,v2 服务端是迁移里程碑 M2。v2 的命令见 Quick 协议 v2 §13。原文: Quick 模式是不需要账户的 NS 使用方式:两台设备用一次性短码配对,之后直接通过 WireGuard 通信。本页规定
ns quick命令、relay 上的/quick/v1配对会合、relay 目录与短码、节点如何选择 relay、平台集成,以及运行与运维规则。底层协议(身份与地址、配对令牌、relay 报文、隧道内记录)见 Quick 协议,其不兼容的下一版见 Quick 协议 v2;本页不新增任何 relay 报文或隧道内记录。
| 方面 | Quick 模式 |
|---|---|
| 权威 | 每台设备自己:身份键 I、准入策略、允许与移除记录。没有账户、NSD 或登记表。 |
| 配对 | 一次性短码在 relay 上定位邀请;双方核对对方设备的完整身份指纹;随后邀请方通过加密投递把一个限定接收方的 PairingToken(Quick 协议 §7.4)交给加入方,加入方按普通配对流程(§7.5)导入。 |
| 配对范围 | 只授权这一对设备。A–B 与 A–C 配对不让 B 与 C 互通。 |
| 数据路径 | 两台设备之间的 WireGuard,能直连就直连,否则经 relay 转发;relay 只在 WireGuard 之下转发密文。 |
| 上下文 | 所有安装都使用固定的公开默认上下文(Quick 协议 §2.7);用户不创建也不选择网络。 |
| 能力 | 设备之间 L3:身份 IPv6 地址、节点本地 IPv4 别名、quick.internal 下的名字。不发布 Service、不做子网路由、不提供出口。 |
| 与账户模式的关系 | 同一个 ns 二进制,按状态目录互斥。任一模式都不会停止或重置另一种;启动 Quick 模式前必须先断开账户模式。 |
2.1 公开命令
Section titled “2.1 公开命令”| 命令 | 作用 |
|---|---|
ns quick up [RELAY 选项] [--detach | --watch | --foreground] | 确保节点在运行。默认(--detach)启动后台 worker,本地就绪后返回(最多 30 s)。--watch 保持一个状态视图;中断视图不会停止节点。--foreground 在前台监管一个新 worker,供容器与服务管理器使用,收到 SIGTERM、中断或挂断时停止它;它从不接管已在运行的 worker。 |
ns quick down | 停止节点,保留身份、配对与配置(§6.4)。 |
ns quick status | 本机身份与节点 ID、生效的 relay 列表及其来源、已注册的 relay、已连接的对端。缺失的观测报告为未知,而不是零。 |
ns quick invite [RELAY 选项] [--recipient 指纹] [--ttl 时长] [--wait 秒] [--name 文本] [--qr] | 创建邀请并确认加入的设备(§3.5)。 |
ns quick join [CODE | --stdin] [--peer 指纹] [RELAY 选项] [--wait 秒] | 使用邀请加入(§3.5)。不给 CODE 也不用 --stdin 时,在隐藏输入提示中读取。 |
ns quick peers | 已配置的对端及其流量实际走的路径。 |
ns quick peer show | name | remove PEER [昵称] | 查看对端、设置本地昵称,或移除对端(持久的本地阻断)。 |
ns quick policy set --join auto|confirm|recipient-only | 可复用令牌的准入策略(Quick 协议 §13.3)。Quick 邀请总是使用限定接收方的令牌,任何策略都会接纳。 |
ns quick pending list | approve ID | deny ID | 签发方的待批准队列(Quick 协议 §13.3)。 |
ns quick allow list | remove PEER | restore PEER | 准入与移除记录。 |
ns quick upgrade [--yes] | --restore BACKUP --yes | 转换早期版本按设备划分的网络状态(§6.4)。 |
所有命令都接受 --json 与 --config FILE。
2.2 隐藏命令
Section titled “2.2 隐藏命令”以下底层命令不在帮助中显示,供测试与自动化使用:token issue|list|revoke、pair(及其 status、cancel)、peer alias、peer binding import、key rotate、key binding export、aliases export|import、bridge add|list|remove、recovery set-root 与 recover。它们的行为见 Quick 协议 §13.2;aliases、recovery 与 recover 仍返回 feature_deferred。
2.3 Relay 选项
Section titled “2.3 Relay 选项”up、invite、join(以及隐藏的 pair)接受:
| 选项 | 含义 |
|---|---|
--relay RELAY | 选择并记住恰好一个 relay 或 relay 区域条目(§5)。重复给出或用逗号分隔的值会被拒绝。只写 DNS 主机名时使用端口 51822。 |
--reset-relays | 选择并记住内置列表。与 --relay 冲突。 |
--switch-relay | 允许为改变 relay 选择而重启正在运行的节点。它与 --yes 分开,--yes 从不授权重启。 |
2.4 选择对端
Section titled “2.4 选择对端”PEER 接受完整的 64 字符身份键、20 字符节点 ID(Quick 协议 §12.4 的身份标签)、至少 8 个字符且唯一的节点 ID 前缀,或唯一的本地昵称。前缀或昵称有歧义时报错。批准与确认始终显示并绑定完整密钥;昵称或前缀只用于选择。
昵称由小写字母、数字和连字符组成,大写输入会转为小写。交互式配对成功后,invite 与 join 会提示设置昵称;跳过则保留身份标签。配对日期记录在本地,用于显示。
2.5 权限与归属
Section titled “2.5 权限与归属”- 首次启动需要 TUN 权限:Linux 需要
CAP_NET_ADMIN与iproute2(由拥有状态目录的登录用户使用sudo);macOS 需要 root 才能创建 utun;Windows 需要管理员终端,并在ns.exe旁放置wintun.dll。NS 从不弹出 UAC 提示或启动提权助手;需要启动节点的命令会退出并给出操作说明。 - 节点运行后,同一用户可在普通终端通过经所有者认证的 IPC 控制它(
status、peers、down、invite、join)。管理员权限不等于归属:从不接管或停止其他用户的节点。 - 隐式配置是状态目录中的
quick.toml(Linux 上为~/.nsio),可以不存在。--config FILE必须存在且仅所有者可访问(Unix 上chmod 600;Windows 上使用私有 ACL);格式错误或不安全的文件是错误,从不静默回退。
3. 配对会合(/quick/v1)
Section titled “3. 配对会合(/quick/v1)”本节描述现有实现。会合协议 将以与应用无关的
/rendezvous/v1会合服务取代它,配对改为应用通道上的应用(Quick 协议 v2 §10.2),不保留 v1 兼容。
3.1 角色
Section titled “3.1 角色”- 邀请方:创建邀请,确认加入方,签发并封装凭据。
- 加入方:查找邀请,确认邀请方,打开凭据并导入。
- 会合服务(broker):relay 上的
/quick/v1服务。它在有限时间内保存公开的身份证明与密文,不能批准对端、读取凭据或派生连接密钥。承担会合的 relay 与节点注册通信的 relay 是相互独立的角色。
3.2 传输
Section titled “3.2 传输”- 在 relay 现有 TLS 监听上的 WebSocket:
wss://{authority}/quick/v1,子协议ns-quick-v1,与/keynet/v1数据载体分开。 - TLS 按所拨的 authority 校验;对已配置的 relay 使用该条目的 trust store,否则使用系统根证书。邀请从不安装 CA,也从不放宽校验。
- 每个 WebSocket 消息承载一条 JSON 消息,最大 16 KiB,在解析前检查。客户端连接超时 8 s、每次响应超时 8 s,每 0.7 s 轮询一次。
- 连接建立后,broker 先发送
Challenge {nonce, authority}。nonce是不全为零的 32 字节随机值;authority必须等于客户端期望的身份(relay authority,或 §5.4 的区域身份)。不一致时断开该连接。
3.3 消息
Section titled “3.3 消息”请求格式为 {"operation": <名称>, "value": <载荷>},响应格式为 {"result": <名称>, "value": <载荷>};名称使用 snake_case,未知字段一律拒绝。
| 请求 | 载荷 | 发送方 | 用途 |
|---|---|---|---|
directory | — | 任意 | 获取 relay 目录(§4) |
create | Proof | 邀请方 | 创建邀请 |
lookup | 数字码 | 加入方 | 查找邀请;以 offer 应答 |
join | Proof | 加入方 | 成为候选 |
resume | Proof | 任一方 | 连接丢失后以同一身份重新认证 |
poll | — | 任一方 | 读取会话 state |
select | 身份 | 邀请方 | 选中一个候选 |
reject | 身份 | 邀请方 | 拒绝一个候选 |
deliver | SealedToken | 邀请方 | 交付封装后的凭据 |
cancel | — | 任一方 | 撤回(§3.7) |
complete | — | 加入方 | 报告本地已就绪 |
| 响应 | 载荷 |
|---|---|
challenge | {nonce, authority} |
directory | Directory |
created | {digits, expires};expires 必须等于邀请方 Hello.expires |
offer | 邀请方的 Proof |
state | Observation {stage: waiting|selected|delivered|completed, candidates: Proof[], selected: Proof?, sealed: SealedToken?} |
ok | — |
error | invalid_code、unknown_relay、invalid_directory、invalid_message、invalid_proof、unavailable、not_selected、capacity、rate_limited、conflict、randomness、encryption、storage 之一 |
错误中从不包含短码、令牌、密钥或其他不可信输入。relay 返回的错误是最终结果;只有传输故障才会转到区域的下一个成员(§5.4)。
3.4 身份证明
Section titled “3.4 身份证明”Hello { version = 1 session 16 字节随机值,非零;由邀请方选定,加入方照抄 role invite | join identity 32 字节 Ed25519 身份键 I ephemeral 32 字节 X25519 公钥,每次尝试新生成 authority relay 或区域身份,host:port expires Unix 秒;now < expires <= now + 900}Proof { hello, challenge(32 字节), signature }signature = Ed25519_I( "ns-quick-identity-v1\0" || challenge || JSON(hello) )签名由节点运行时经所有者认证的 IPC 完成;身份私钥从不进入 CLI 进程。校验使用严格模式的 Ed25519。一个 Hello 在整个会话中固定不变,因此以新挑战重新连接也不能更换密钥、接收方或过期时间。设备不能与自己配对。
3.5 流程
Section titled “3.5 流程”- 创建。 必要时启动邀请方节点。会合服务取当前已注册的第一个已配置 relay,没有则取第一个已配置 relay。邀请方发送
create;broker 返回 8 位随机数字(在 00000000–99999999 中均匀选取,冲突由 broker 重试)与过期时间。 - 显示。 当 broker 是目录中的 relay 时,短码为目录前缀加数字(
KT58307264);否则为 8 位数字加显式 relay(ns quick join 58307264 --relay host)。--qr显示短码;自定义 relay 时显示完整的加入命令。 - 查找。 加入方解析短码(§4.2)、确定 relay 并发送
lookup。它校验offer:证明有效、角色为invite、authority等于确定的 relay 身份;使用--peer时还要求等于固定的身份。 - 加入。 必要时启动加入方节点(不重启正在运行的节点,也不触碰账户模式),加入方用自己的
Hello(session、authority、expires相同)发送join。 - 确认。 双方通过可信渠道比对对方设备显示的完整指纹并回答
y。非交互使用必须固定对方身份:invite --recipient 指纹、join --peer 指纹。持有短码、显示名或--yes都不能确认身份。 - 选择。 邀请方对拒绝的候选发送
reject并继续等待,对确认的候选发送select。选中后数字码从查找中移除,其他候选被丢弃。 - 签发与封装。 至少还要剩 5 s。邀请方运行时为加入方的
I签发限定接收方的 PairingToken,not_after不晚于邀请过期时间减 5 s,然后封装(§3.6)并发送deliver。若没有已注册的通信 relay,返回relay_unavailable,邀请失败。 - 打开与导入。 加入方等待
state.selected等于自己的Hello且出现sealed,打开后检查令牌的签发方是邀请方、接收方是自己、not_after不超过邀请过期时间。随后以令牌的 home relay 启动或复用节点,通过隐藏的pair操作导入令牌(Quick 协议 §7.5)。 - 完成。 加入方配对达到
ready后发送complete。邀请方等到阶段completed,再确认本地已接纳这个确切身份。以本地就绪为准:complete丢失从不撤销已建立的配对。 - 清理。 邀请方事后总是撤销临时令牌,这会停止后续准入但保留已接纳的对端(Quick 协议 §7.4)。未完成的流程发送
cancel;加入方会取消未完成的本地配对,但从不取消已就绪的配对。
--wait(默认值与最大值均为 900 s)从第一次连接 relay 起限制整条命令;--ttl(1 s 到 15 min)限制邀请本身。Ctrl-C 取消并以 130 退出。
3.6 加密投递
Section titled “3.6 加密投递”shared = X25519(ephemeral_inviter, ephemeral_joiner) // 必须是 contributorykey = HKDF-SHA256(salt = "ns-quick-token-v1", ikm = shared, info = JSON([inviter_hello, joiner_hello]))sealed = XChaCha20-Poly1305(key, nonce = 24 字节随机值, aad = JSON([inviter_hello, joiner_hello]), token)封装要求角色为 invite / join、session、authority 与 expires 相同、身份不同。令牌最大 2 048 字节。broker 只持有两份公开证明与密文,从不接触令牌或任一方的临时私钥。这是绑定了双方签名身份的认证密钥交换,而不是 PAKE:认证依赖用户比对指纹,而不是数字码。
3.7 会合状态与清理
Section titled “3.7 会合状态与清理”| 事件 | broker 的处理 |
|---|---|
| 选中接收方 | 移除查找码与其他候选 |
| 拒绝 | 移除该请求;保留有界的拒绝标记直到过期 |
| 邀请方或被选中的加入方取消 | 移除会话 |
| 未被选中的候选取消 | 只移除它自己的请求 |
| 加入方完成 | 移除密文;保留幂等回执最多 30 s |
| 邀请方观察到完成 | 移除回执 |
| 传输中断 | 同一签名身份可在剩余租期内 resume |
| 邀请方或被选中的加入方 180 s 无活动 | 移除会话(每 10 s 检查一次) |
| 绝对过期 | 10 s 内移除;生命周期从不超过 15 分钟,重启也不会延长 |
查找与未被选中的候选不能让被放弃的会话继续存活。会合状态保存在私有存储中,与 relay 的永久安全标记分开;丢失它从不影响数据载体。
3.8 会合服务上限
Section titled “3.8 会合服务上限”| 上限 | 值 |
|---|---|
| 保存的邀请 | 10 000 |
| 每个身份的有效邀请 | 3 |
| 每个邀请的候选 | 4 |
| 被拒绝的身份 | 16 |
| 消息大小 | 16 KiB |
| 查找 | 每个源 IP 每分钟 12 次,全局每秒 100 次 |
| 创建 | 每个源 IP 每分钟 30 次,全局每秒 100 次;重试同一个有效邀请不计次 |
| 每个连接的请求 | 每秒 10 次 |
被拒绝的猜测从不让其他邀请失效。保存邀请的上限并不代表并发能力;relay 的连接与组帧内存预算同样适用。
4. Relay 目录与短码
Section titled “4. Relay 目录与短码”4.1 目录
Section titled “4.1 目录”Directory { version u64 >= 1, relays: RelayEntry[] } // 最多 576 条RelayEntry { id u16 != 0, code: 两个字母, authority: host:port }- 短码字母取自
ABCDEFGHJKLMNPQRSTUVWXYZ(不含I与O)。id、code、authority各自唯一。 id及其code永久不变:更新可以增加条目或修改 authority,但从不删除id、重新分配短码或复用已退役的短码。任何变更都需要更高的版本;同一版本必须完全相同。- 内置版本 1:
KT(id 1)hkg-a1.43.159.53.106.sslip.io:51822、KM(id 2)hkg-a2.124.156.159.181.sslip.io:51822、SG(id 3)sin-a1.43.133.56.69.sslip.io:51822。这些是协议分配,不代表部署状态。 - 未知前缀会触发一次刷新:通过校验过的 TLS 向第一个内置 relay 发送
directory请求,只有当结果是内置目录的合法更新时才接受。刷新从不是邀请搜索。
4.2 短码语法
Section titled “4.2 短码语法”| 输入 | 含义 |
|---|---|
两个字母 + 8 位数字(KT58307264,不区分大小写) | 按前缀定位目录中的 relay;与之冲突的 --relay 会被拒绝 |
| 8 位数字 | PIN;必须恰好配一个显式 --relay,从不使用记住的或默认的 relay |
忽略首尾空白。前缀是公开的路由信息,不提供熵;数字只用于定位,从不用于授权。
5. 节点的 relay 选择
Section titled “5. 节点的 relay 选择”5.1 来源与优先级
Section titled “5.1 来源与优先级”不使用 --config | 使用 --config FILE |
|---|---|
1. 本次命令的 --relay / --reset-relays | 1. 本次命令的 --relay / --reset-relays |
| 2. 保存的偏好 | 2. 该文件(即使只写了部分内容也以它为准) |
3. 隐式的 quick.toml | 3. 内置列表 |
| 4. 内置列表 |
成功的显式选择保存在状态目录专属的私有偏好中,从不改写 quick.toml、身份或配对。如果启动后保存失败,命令会报告失败,而不是声称已保存。
5.2 内置列表
Section titled “5.2 内置列表”按顺序使用目录中的三台 relay。DNS 只在启动时解析,每次最多 5 s;解析失败的条目会被报告,并在本次运行中省略,全部失败则报错。默认 UDP 绑定为 IPv4;仅有 IPv6 的主机需设置 transport.udp_bind。只有内置列表能同时注册到多台 relay 并在其间回退。
5.3 自定义 relay
Section titled “5.3 自定义 relay”自定义 relay 列表恰好一个条目:一台 relay 或一个 relay 区域。条目更多的列表在启动时被拒绝,除非它与内置列表相同。已知的 relay 短 ID 保留其显式的 UDP / WSS / 信任映射;新的 authority 对该 authority 使用系统根证书校验 TLS。WSS 回退始终是 wss://{trusted_authority}/keynet/v1。
5.4 Relay 区域
Section titled “5.4 Relay 区域”区域条目写明区域身份,并按就近顺序列出 1 到 8 个成员:
[[transport.relays]]identifier = "region.example:51822"
[[transport.relays.members]]udp = "m1.example:51822"trusted_authority = "m1.example:51822"
[[transport.relays.members]]udp = "m2.example:51822"trusted_authority = "m2.example:51822"trust_store = "/var/lib/ns/quick-node/region-roots.pem"- 区域条目没有顶层的
udp、wss、trusted_authority或trust_store。每个成员的 authority 是规范形式,在条目内唯一,其 UDP 端口等于 authority 的端口。标识不必与任何成员相同。配置 schema 版本为 2。 - 节点维护一个成员游标。一轮注册只发给当前成员;其 WSS 回退以该成员的 trust store 拨号该成员。一轮注册过期而未确认、会话到达存活期限或漏掉两次 presence 确认、以及 WSS 连接、注册或载体失败,都会让游标按正常退避移到下一个成员,到末尾后回到开头。已确认的成员在健康期间保持为当前成员。
- REGISTER、令牌与公布的 relay 列表都携带区域身份(Quick 协议 §12.8);配对介绍发往节点当前注册的成员。
- 通过区域进行 Quick 配对要求区域身份为
host:port。Hello.authority与期望的挑战 authority 都是区域身份;每个连接发往wss://{成员 authority}/quick/v1,按该成员的 TLS 信任校验。只在传输故障时按顺序尝试成员,每次尝试最多遍历一轮。加入方的连接与查找共用一轮;重新连接时在任一应答的成员上恢复。 - 在 relay 侧,一个区域在每个 owner epoch 内只有一个会合服务 owner;其他成员经区域控制链路把会合事务转发给它。owner 的选定、栅栏与重载由 NSGW 的 quick pairing 设计规定。
5.5 更换 relay
Section titled “5.5 更换 relay”不带 relay 选项的命令原样复用正在运行的节点;修改文件只在下次启动时生效。改变有序的 relay 映射需要重启:交互时命令显示当前与请求的 relay 并询问;非交互时需要 --switch-relay。选择相同则无需同意。替换启动失败时,尽可能恢复先前的配置并报告结果。已签发的令牌保持原来的 home relay。
6. 节点运行
Section titled “6. 节点运行”6.1 平台
Section titled “6.1 平台”| 平台 | TUN | 本地 DNS |
|---|---|---|
| Linux | 内核 TUN(默认名 quick0),配合 iproute2 | 在节点所在网络命名空间监听 127.0.0.54:53;默认与主机 DNS 接管一起关闭,因为可能与 systemd-resolved 冲突;开启后适用 Quick 协议 §7.8 |
| macOS | 原生 utun | 默认开启:在 /private/etc/resolver 下按 zone 写入文件,只在 root 拥有且受保护的目录中创建,从不跟随链接,down 时撤回 |
| Windows | Wintun(与架构匹配的 wintun.dll) | 默认开启:一条带标记的 NRPT 规则把 quick 命名空间指向 127.0.0.54;与之冲突的有效域策略会被报告,不会被覆盖 |
只有 quick 自己的命名空间路由到本地解析器;从不替换全局 DNS,私有名字从不回落公网 DNS。修改前先校验已有资源;冲突或已被替换的资源不会被接管。从不触碰账户模式的解析器资源。
6.2 对端状态与路径
Section titled “6.2 对端状态与路径”- 只要数据面持有与对端的当前 WireGuard 会话,且 transport 选定了直连路径,或选定的 relay 的确切载体是 relay 客户端的活动会话,对端即为
ready。relay 发送使用同一判定,因此peers报告的是流量实际走的路径。停止应答的 relay 成员会一直被报告,直到节点在别处完成注册。 - 直连路径遵循 Quick 协议 §12.7:探测回复只有来自确切元组时才能晋升;选定的路径在收到任意来源、与 nonce 相关联的健康回复时保持存活;连续三次挑战无应答则退回 relay。
- 已保存的对端不保证可达;配对完成与实时可达是两件不同的事。
6.3 上限与失败规则
Section titled “6.3 上限与失败规则”| 上限 | 值 |
|---|---|
| 每个网络的对端 | 1 024,即 transport 的容量;超出的配对被拒绝(Quick 协议 §1.1 的预算是设计上限) |
| TUN MTU | 至少 1 376,即直连路径必须承载的数据面路径上限 |
| 队列上限 | 每个都必须至少能容纳一个报文;更小的值在启动时被拒绝 |
只有致命情况才会停止节点:存储 I/O 失败或损坏、内部不变量被破坏、受监管的任务或内部通道死亡、运行时配置错误,或已记录的锁存条件(本地 relay 会话持久化失败或提供方失败)。其余情况都是本地背压或计数丢弃:
- transport 数据只把网络的 transport 队列填到一个上限,为一个对端最大的控制突发留出空间;其余数据在有界的数据面队列中等待,并抑制 TUN 读取。控制记录与握手可以使用整个队列。
- 放不下的控制工作、relay 输出与配对介绍等待下一个 tick;回复放不下的控制记录在任何状态变更之前被拒绝,并在发送方重试时应用。
- 仍找不到空间的报文被丢弃,由其协议的定时器恢复。对端或网络造成的失败(不可达路径、无法解析的配对端点、伪造的源地址、失败的桥接流、低阶 WireGuard 密钥)只影响该报文、路径或流。
丢弃按对端计入节点诊断中的 output_drops 与 input_drops。关闭时执行每一个清理步骤,并在全部执行后报告第一个失败。
6.4 状态、日志与升级
Section titled “6.4 状态、日志与升级”- 持久状态:
<state-dir>/quick(身份、配对、别名)。down会保留它。 - 日志:按
NS_LOG_LEVEL输出到 stderr,同时写入<state-dir>/quick-runtime.log(权限 0600,达到 4 MiB 时轮转为一个.1文件;不安全的文件会被拒绝,此时继续运行但不写文件日志)。不含秘密的路径诊断:<state-dir>/quick-node-diagnostics.json,正常关闭时删除。 - 运行时归属按网络命名空间划分;两个 Quick 节点不能共用一个命名空间。
- 在 macOS 与 Windows 上,只有运行时已停止、且主机路由与 split DNS 已验证恢复,停止才算成功(上限 60 s;Linux 为 10 s)。否则
down失败,并保留受保护的清理记录,下次up会先恢复它。 - 早期版本按设备划分的网络状态会被
up识别并报告upgrade_required。节点运行时upgrade --yes会拒绝执行;它写入并校验一个私有备份(从不覆盖已有备份),保留I,清除旧关系并安装默认上下文;对端需要重新配对,地址或名字可能变化。upgrade --restore BACKUP --yes只恢复同一设备的备份,供旧版二进制使用。
6.5 容器
Section titled “6.5 容器”NS Docker 镜像用各自的 Compose 模板运行两种模式。Quick 模式使用 ns quick up --foreground;它只监管自己启动的 worker,转发诊断,并在终止时等待有界清理。正式容器(NS_CONTAINER=1)在 Quick 模式运行期间持有账户模式租约作为互斥栅栏。ns health 在两种模式下都检查本地归属;--ready 还会检查运行时的 IPC。就绪从不要求对端可达。保留状态卷即可保留身份与配对。
7.1 邀请与加入事件
Section titled “7.1 邀请与加入事件”invite --json 与 join --json 向 stdout 写入按行分隔的事件对象:
{"schema_version":1,"operation":"quick.pairing","stage":"invitation_created","message":"…","details":{…}}| 阶段 | 详情 |
|---|---|
invitation_created | code、relay、join_command、expires、identity(包含短码:请保密 stdout) |
confirmation_required | identity(本机)、peer |
request_rejected | — |
connecting | — |
receipt_pending | —(配对已完成;broker 回执会自动过期) |
cleanup_pending | —(relay 或本地清理未确认;有界过期仍然生效) |
complete | — |
failed | 输入错误时带 code:invalid_arguments、confirmation_required |
cancelled | — |
退出码:0 表示完成;2 表示输入错误,此时尚未创建任何运行时状态;130 表示取消;其他情况非零,通常为 1。JSON 模式下失败不向 stderr 写入人类可读的错误。流程开始前的参数解析错误保持带版本的命令错误信封。人类可读的进度始终写入 stderr。
7.2 其他命令
Section titled “7.2 其他命令”其他命令使用 Quick 协议 §13.5 的单对象信封,schema_version:2。status 还会报告实际运行的 relay 配置(含各条目的 members 及其来源)与 connectivity.registered_relays。
8. 安全说明
Section titled “8. 安全说明”- 数字码与前缀只是定位符。授权只来自用户对完整指纹的确认(或固定的密钥),以及随后 Quick 协议对限定接收方令牌的准入。
- broker 能看到邀请时间、源地址、双方公开的身份证明与密文。它不能伪造证明(每份证明都由
I对一个写明 relay 的新挑战签名),不能在选中后替换候选(封装密钥绑定了双方的 hello),也不能读取凭据。 - 恶意的 broker 可以拒绝服务,或向用户展示错误的候选;防线是指纹比对。不要把它弱化为只比对名字。
- 短码从不出现在日志、调试输出、错误或命令行参数可见的状态中,除非用户自己输入;
join通过隐藏提示或--stdin读取短码。