NS 是 NSIO 的端侧运行时:一个 ns 二进制(另有嵌入库 libns 与 Docker 镜像),运行在需要接入网络的任何机器上 —— 开发者笔记本、服务器、容器 sidecar、CI runner、桌面 / 移动 App。本节以 ns 仓库分支 refactor/nsplane(fbc8ded8,2026-10-13) 为准。
| 部分 | 入口 | 适合 | 状态 |
|---|
| 账户模式(NSD) | ns up --server <URL> 登记(未指定时用内置默认 NSD https://nsd.dev.ns.io),之后 ns up / ns down / ns status | 团队、长期共享、策略与运维:Service 发布、子网、出口、访问授权 | 已实现,默认模式;2026-10-12 起以 membership 形式运行,线上格式改为身份对端,需要 NSD 的配套(见下) |
| Quick 模式 | ns quick up --relay <host:port>,ns quick invite / ns quick join <短码>,ns quick allow add <节点 ID> | 免账户:任意两台设备凭一次性短码配对、或互相按节点 ID 放行后直接互联 | ns 侧已实现 v2(2026-10-04);relay 侧的 v2 服务端待 nsgw M2,目前只能对接显式指定的 v2 relay |
| 应用模式 | ns send / ns receive <票据>(文件发送);第三方应用 | 在节点的隧道之上运行的应用:文件发送是第一个,之后的功能与第三方应用都以应用形式提供 | 设计,未实现 |
每个节点只有一个 nsplane 数据面引擎,账户模式、Quick 模式、ns send 与第三方应用全部基于它;应用不是第三种连接模式,而是运行在节点已有的对端与路径之上。账户模式(2026-10-03,M4)与 Quick 模式(2026-10-04,M5)都已只运行在这一个引擎上,旧数据面 crate 已删除,ns 只保留业务逻辑与控制面。
自 2026-10-12 起(ns 决策 2026-10-11-node-memberships)节点以 membership 模型运行:引擎本身没有密钥,每个已连接的 NSD Network(nsd:<uuid>/<network>)与 Quick 各自作为一个 nsplane 本地身份加入同一个引擎,地位平等、同时运行、互不影响,没有 active NSD,也不再有账户 / Quick 互斥。每个 membership 的身份由设备密钥链按 NSD 的规范 URL 加盐派生(ns key),所以不同 NSD 无法通过比对密钥关联同一台设备;NSD 只提议规则、对端、路由与名字,生效的配置由节点决定(ns policy)。用户面随之改变:ns network join / leave / list 增减 membership(守护进程运行时即时生效),作用于单个 membership 的命令用 --network <选择器>,出口、子网、名字、状态都按 membership 处理;Quick 也运行在同一个节点守护进程上。这一版不兼容旧的 ns:不读取旧状态与身份,每台设备重新登记,libns 的 ABI 升到 3。ns 侧的工作(工作流 A–E)已于 2026-10-13 全部合入并通过多节点互通套件;账户模式的线上格式随之改变(Node 以身份键投影,不再有 NSD 分配的 IPv4),当前 NSD 与 nsgw 还没有配套,进度与跨仓库依赖见迁移计划 §4.1。
| 文档 | 内容 |
|---|
| account.md | 账户模式:身份与登记、控制面接入、tun / dns-vip / proxy 数据面、链路阶梯、Service 发布、Short DNS、Gateway Exit、子网路由、Node L3 访问控制、观测、发布与运维、libns、容器 |
| quick.md | Quick 模式:ns quick 命令、/quick/v1 短码配对会合、relay 目录与短码、节点 relay 选择与 relay 区域、平台集成、运行与失败规则、输出格式 |
| quick-protocol.md | Quick 协议:身份键与 WireGuard 键绑定、由身份派生的 IPv6 地址与本地 IPv4 别名、配对令牌与配对流程、relay 报文与区域成员协议、隧道内控制记录、本地运行时接口 |
| quick-v2.md | Quick 协议 v2 设计:只由身份派生的 /127 地址组、一份签名 NodeRecord(relay 注册、登记表、DNS、隧道内更新共用)、立即切换的密钥轮换、客户端分片的登记表、NSR2 relay 报文、所有来源共用的隧道内控制通道、经应用通道配对与按节点 ID 放行 |
| rendezvous.md | 会合协议设计:relay 上与应用无关的 /rendezvous/v1(会合信箱、登记表、relay 目录、参与方密钥、接纳、双向不透明消息、上限),relay、nsplane 与 ns 的分工 |
| app-channel.md | 应用通道设计:ns 内的通用应用层,应用以 profile 声明 kind、鉴权(confirm / pake / peer)与对端生命周期;引入、身份交换、密钥派生、对端安装与隧道内入口;配对与文件发送是首批应用 |
| apps.md | 应用模式设计:单一 nsplane 引擎上的应用分层、应用的构成(kind、会合、仅限本次会话的对端、隧道内端口)、与两种连接模式的关系、应用清单 |
| file-send.md | 文件发送(应用)设计:票据、经应用通道 pake 与 /rendezvous/v1 信箱会合、已配对走现有隧道 / 未配对建立仅限本次传输的临时 peer、会话协议与文件安全规则 |
| next.md | 新架构设计:单一 nsplane 引擎上的四层结构,身份派生的全局 IPv6 地址与本地 IPv4 别名,可插拔的对端来源(多 NSD、Quick、应用)与跨来源策略,呈现方式与传输正交,功能模块开关,迁移阶段 |
| roadmap.md | 进行中的计划、已知差距与边界 |
| 维度 | 现状 |
|---|
| 登记与状态 | ns up --server 浏览器 / 设备授权、invite;未指定 NSD 时使用内置默认 https://nsd.dev.ns.io(2026-10-10);state/manifest.json(schema v3)记录已连接的 membership 集合(NSD、Network、Space),全部平等、没有 active 指针;ns network join <NETWORK_ID> [--server <URL>] / leave <选择器> / list 增减 membership(ns nsd switch 已删除);每个 NSD 在 state/nsds/<uuid>/ 下有自己的命名空间;设备密钥链(ns key)派生每个 NSD 的身份 |
| 控制面 | 只配 HTTPS origin,WebPKI 发现 control_trust.v1;auto 优先 SSE、可切 Noise / QUIC;Envelope v1 签名;60 s 心跳 |
| 数据面 | tun(默认,L3 + L4)/ dns-vip(免 root L4)/ proxy(SOCKS5 / HTTP / PAC),共享路由、DNS、ACL 上层 |
| 链路 | 每个 pair 走 direct → wg-relay → wss-relay 阶梯;direct 需双端三轮无损验证后切流;网关 RTT 分档上报 NSD |
| 发布 | services.toml 热更新发布 Service;ns subnet 发布 IPv4 LAN 为 ULA 映射前缀;不同 membership 的 LAN 网段重叠时经本地虚拟网段(100.98.0.2 – 100.126.255.255)同时可达;发布端 Service PEP、Node L3 ACL、子网策略全部 fail-closed |
| 命名 | Short DNS v2:canonical FQDN + 短名;每个 membership 一个命名空间,查询按后缀路由,名字还可按 <name>.<network><后缀> 限定;Gateway Egress 短名 <service>.<gateway-label>.svc |
| 出口 | ns exit set <网关> --network <M> 按 membership 选择 Gateway Exit:每个 membership 至多一个,默认路由只有一个持有者,各 membership 的 CIDR 出口不重叠,全部经设备级出口连接器 EXIT4(100.98.0.1)同时运行;WG 或 WSS 承载 |
| 嵌入 | libns(xcframework / .so / .dll),JSON schema 化的启动参数、状态、事件与注册;2026-10-12 起 ABI 3:启动参数 v12 列出要运行的 membership,status.v13 / local-state.v3 按 membership 输出 |
| 维度 | 现状 |
|---|
| 协议 | Quick 协议 v2:一份签名的 NodeRecord 说明身份用哪把 WireGuard 键;relay 报文 NSR2;会合与登记表在 relay 的 /rendezvous/v1 上。没有 v1 的线上、存储或 JSON 兼容 |
| 配对 | 短码经会合信箱完成(应用通道 confirm 模式,kind = "pairing"),双方核对身份后派生 PSK;也可以不会合,双方各自 allow add <节点 ID>,记录从登记表取得(无 PSK) |
| 地址与名字 | 身份键派生的 N6 / N4(/127 地址组);每个对端一个本地 IPv4 别名 alias4(来自引擎与账户 membership 共用的别名表);n.ns.io 由节点守护进程的 DNS 权威应答:<节点 ID>.n.ns.io、<昵称>.n.ns.io 与 .v4. 视图,Quick 运行时加入系统 resolver zone;quick.internal 已删除 |
| relay | up --relay host:port 显式指定(还没有内置的 v2 relay 目录);UDP 载体,3 s 无应答回退到 /ns/v2 WSS;登记表按节点 ID 分片到两个 relay |
| 路径 | 阶梯:经 relay 起步,隧道内控制通道交换端点后探测直连,含 peer-reflexive 候选;经 relay 收到握手即结束直连路径 |
| 存储 | <state>/quick/state.v2 单个 CBOR 快照;不读取 v1 状态或身份(2026-10-12 起 Quick 身份与 WireGuard 键由设备密钥链派生,每个记录代际一把键) |
| 守护进程 | Quick 是节点守护进程上的一个 membership:ns quick up 经私有 IPC 把 Quick 加到运行中的守护进程,没有时先只带 Quick 启动一个;ns quick down 只摘掉 Quick,NSD membership 不受影响;ns up / ns network join 可以在只跑 Quick 的守护进程上即时加入 NSD membership;独立的 Quick worker 已删除 |
| 平台 | Linux(TUN)、macOS(utun)、Windows(Wintun + NRPT);TUN MTU 默认 1420(1280–1420),经 relay 的内层 MTU 1376;Windows 上 quick0 暂为 65535(nsplane MT-3) |
| 输出 | JSON schema v3(quick-json-v3.schema.json),错误带 details.cause |
| 维度 | 现状 |
|---|
| 发布产物 | 六端二进制、两种安装器、双架构 Docker 离线包;签名 releases.jws;ns update 防回滚;YYYYMMDD-g<commit> 版本;Windows 附带 Wintun |
| 观测 | ns status / health / info / doctor;结构化 JSON 日志 |
| 本地化 | CLI en-US / zh-Hans 编译期嵌入 |
| 层 | crate | 职责 |
|---|
| 运行时与 CLI | ns | 命令(up / down / status / network / nsd / space / key / policy / exit / subnet / quick …)、节点守护进程、membership 运行时(engine::memberships)、平台集成 |
| 账户模式控制面 | control(仓库内副本,与 common 一样留到 M6,届时换成 nsshared 中重新设计的控制契约;telemetry 的 tracing 初始化可换成 nsshared-telemetry) | 信任发现、SSE / Noise / QUIC 客户端、Envelope v1、签名校验 |
| 数据面引擎 | nsplane v0.14.0(nsplane、nsplane-core、nsplane-noise、nsplane-packet、nsplane-tun、nsplane-netstack、nsplane-acl、nsplane-nat、nsplane-wss) | 每个进程一个引擎:WireGuard、本地多身份(每个 membership 一把密钥)、UDP 与 relay 传输、WSS 载体、TUN、用户态协议栈、过滤链、通用流网关、翻译、分片。ns 不再有逐报文代码(少量待 nsplane MG 事项的循环除外) |
| 引擎宿主 | ns::node_engine | EngineHost(PacketIo::Tun / NetStack / Channel)与 NodeEngine(进程唯一的引擎,自身无密钥;add_membership / remove_membership 把每个 membership 作为 nsplane 本地身份加入,各有自己的 UDP 传输、relay 传输槽、对端表、阶梯、控制通道、ACL 作用域与翻译器) |
| 覆盖网核心 | overlay(约 17k 行) | 身份与派生(N6 / N4、alias4、lan6)、PeerSource 与合并对端表、来源策略(nsplane-acl 命名空间,跨来源默认拒绝)、路径阶梯(nsplane PathPolicy)、relay v2 客户端、登记表客户端、会合信箱客户端、隧道内控制通道、Quick 来源与自身记录 |
| 账户模式接入 | ns::account_engine | AccountMembership / NsdPlane(每个 NSD 一个:合并其各 Network 的配置、relay WG 运行时、载体安装)、wg 控制代码(Node L3 模型 node_l3 及其到 nsplane 流网关的编译、租约、反射发现、relay 登记类型)、LinkFilter + nsplane-acl 过滤器、用户态栈、直连探测 |
| Quick 模式 | ns::quick(v2 运行时与存储、别名、worker IPC)、ns::app_channel(配对,confirm 模式)、ns::quick_json | Quick v2 运行时与命令;Quick 是节点守护进程上的一个 membership(Memberships::start_quick),与 NSD membership 共用引擎、别名表与 DNS |
| 设备密钥链 | ns::key_chain | 口令包裹的随机根密钥 R,derive(R, path) 派生每个 NSD 的 membership 身份(按规范 NSD URL 加盐)、Quick 身份与本地状态密钥;ns key init / unlock / passphrase / status |
| 节点策略权威 | ns::policy | 每个 membership 的提议 → 受管配置(managed.json)锁定 → 所有者决定(ns policy list / accept / reject / set);内置不跨 membership 转发;决定存在密钥链加密的 policy/ 下 |
| 控制面协议库 | nsshared-proto v0.5.0(github.com/dotns/nsshared) | 身份与派生、NodeRecord、relay 报文 v2、/rendezvous/v1 消息、公网 DNS 发现、编码 |
| 控制与路由残余 | nat(ServiceRouter、SubnetRoute)、proxy、acl(策略编译与按流 AclEngine,不再有逐报文代码) | 控制侧模型 |
| 平台 | ns-macos-platform、ns-windows-platform | 原生 TUN、路由、resolver、系统代理 |
| 身份与状态 | common(含 engine_addrs 引擎地址登记与 snapshot 快照单元)、secure-storage、privdrop、certstore | 状态目录、密钥、保险库、权限降级、证书 |
| 观测与发布 | telemetry、posture、eventbus、updater、build-version | 指标、态势、事件、更新、构建溯源 |
| 嵌入 | ns-ffi | libns C ABI |