迁移计划:ns 与 nsgw
状态:计划已批准(2026-10-02),D1–D5 已决定;NSD 的配套工作在本计划完善后派发。进度见 §4.1(2026-10-13:M1、M4 完成,M5 与 M6 的 ns 侧完成,M3 待 QA,M2 与 NSD / nsgw 的 M6 配套未开始;D3 有一条待确认的修订,见 §6)。 本页把新架构、Quick 协议 v2 与会合协议 落到 ns 与 nsgw 两个仓库的具体工作上:每个现有 crate 去哪里、按什么顺序做、哪两次切换不兼容、各阶段怎么验证。依据 2026-10-02 的代码:ns
refactor/nsshared-git-deps(1a160365)、nsgwmain(aa94aa5)、nsshared(7c8214d)、nsplane(5578a90,改名已完成,第 2 阶段已批准)。
| 原则 | 做法 |
|---|---|
| 旁路构建,一次切换,切换后删除 | 新实现与旧实现并存于 main,由 cargo feature 或独立二进制隔离;每种协议只有一个切换版本;切换后的下一个版本删除旧代码 |
| 账户模式先换引擎,再换协议 | 先在协议不变的前提下把 tunnel-wg 换成 nsplane 引擎(可用现有回归与 live e2e 验证),再做地址与 relay 的不兼容切换。M4 实际按 ns 的决策 2026-10-03-account-mode-engine-only 直接删除了旧路径,没有保留运行时开关:产品尚未发布,两条路径只会让测试矩阵翻倍 |
| Quick 直接上 v2 | v1 的 quick-runtime 不移植到引擎上(那是一次性代码);Quick 在引擎上直接实现 v2,切换时整体替换 |
| 协议只定义一次 | 线上类型先进 nsshared,ns 与 nsgw 都从它引入,用同一组测试向量 |
| 每一步可发布 | 每个里程碑结束时两个仓库的 main 都能通过各自的质量门并发布;没有长期分支 |
| 不保留兼容 | 按已有决定:Quick v1 状态只保留身份键,NSD 分配的 IPv4 直接废弃 |
2. 现状要点
Section titled “2. 现状要点”| 事实 | 影响 |
|---|---|
ns 仍用仓库内的 control、common、acl、tunnel-ws、telemetry 副本,与 nsshared 已分叉(nsshared §3:这些控制面 crate 随 M6 重新设计) | v2 协议 crate 已在 nsshared,ns 自 2026-10-04 起依赖它;这些 v1 控制面副本留在 ns,随 M6 由新的契约(nsshared 的 L8、L11)取代 |
ns 有两套数据面:tunnel-wg(18.5k 行)与 quick-runtime(31.6k 行),都基于 crates.io boringtun 0.7 | 两套都迁到 nsplane 引擎(M4、M5) |
nsgw 有两套 relay:nsgw-wg::relay(7.2k 行,mac1 分流 + NSD 配对表)加 nsgw-wss 的不透明 WSS 中继;以及 nsgw-quick-relay(34k 行,KNR1、/keynet/v1、/quick/v1、标记库、区域) | 新架构只有一个 relay 协议(v2 §8):两套都换成 relay v2(D1) |
nsgw-wg::gateway_exit、gateway_egress 与 nsgw-routing 只处理 IPv4(代码里没有任何 Ipv6) | 网关侧直接改为 IPv6:wg0、ACL、路由、出口、Egress 与公网入口后端都按 node6 处理,不保留 IPv4 覆盖地址,也不做逐配对的 IPv4 分配(M6,D3) |
nsplane 第 1–5 阶段(packet、core、驱动、TUN、多传输与 PathPolicy、netstack、ACL、翻译)及其后续修复已于 2026-10-03 全部合入 | ns 的引擎迁移不再等待 nsplane(§4 依赖列中的 nsplane 阶段均已满足) |
libns(ns-ffi,20.6k 行)对外有 ABI 与 JSON schema 契约;Windows 原生 TUN 是发布门 | 引擎与地址切换都要走 just ns-ffi-contracts 与原生 smoke |
3. 每个 crate 去哪里
Section titled “3. 每个 crate 去哪里”3.1 ns
Section titled “3.1 ns”| 现有 | 去向 | 里程碑 |
|---|---|---|
control、common、acl、tunnel-ws、telemetry(仓库内副本) | 留在 ns,直到 M6 换成重新设计的控制契约(nsshared 的 L8、L11);只属于节点的部分一直留在 ns。telemetry 中的 tracing 初始化可以先换成 nsshared-telemetry | M6 |
quick-wire(4.8k) | 由 nsshared 的 v2 协议 crate 取代(记录、派生、relay 报文 v2) | M1 建、M5 删 |
quick-pairing(0.6k) | 由 ns 的应用通道(配对是其上的应用)取代;nsshared 只提供 /rendezvous/v1 的信箱消息类型 | M1 建、M5 删 |
quick-runtime(31.6k) | 报文、分片、校验和、翻译、MTU、数据面 → nsplane(过滤器与引擎);relay_client、transport → overlay 的 RelayClient 与路径阶梯;配对与持久化 → overlay 的 quick 来源;KeyBinding、轮换预约、续期 → 被 NodeRecord 取代,删除 | M3、M5 |
tunnel-wg(18.5k) | 设备循环、peer 表、UDP 批处理 → nsplane 引擎;relay、p2p、candidate_report、recovery_probe → overlay 的路径阶梯规则(实现 nsplane 的 PathPolicy);node_l3 → nsplane ACL 过滤器的规则来源 | M4 |
netstack(3.0k) | nsplane-netstack | M4 |
nat(6.4k) | subnet_route、packet_nat 的翻译 → nsplane 翻译过滤器;router(服务解析)→ features/services;conntrack → nsplane 第 5 阶段 | M4(按原协议接入)、M6(v2 地址) |
proxy(0.8k) | edge(呈现层的 L4 转发辅助) | M7 |
ns:engine/、link_ladder、pair_transport、gateway_rtt | overlay(来源、合并对端表、阶梯规则)与 edge(TUN、DNS、代理的启动) | M3、M4 |
ns:addressing、dns/、short_dns | overlay 的地址派生 v2 与名字表(n.ns.io) | M6、M8 |
ns:config_store(单 active NSD)、current_context、space_* | 多来源配置:每个 NSD 的每个 Network 一个 nsd:<uuid>/<network> membership,同时运行(2026-10-12 已完成:engine::memberships,manifest schema v3,无 active NSD) | M6 |
ns:quick.rs、quick_ipc/、cli/quick/ | quick 来源与 v2 命令(v2 §13) | M5 |
ns:socks5_proxy、http_proxy、pac、engine/startup_{tun,dns,proxy} | edge,对所有来源可用 | M7 |
ns:subnet/、exit_*、provider_runtime、服务发布 | features/*,各自一个开关 | M7 |
ns-ffi | 保留;启动参数、状态与事件 schema 随 M5、M6 升版本 | M5、M6 |
secure-storage、posture、updater、privdrop、certstore、平台 crate | 不变 | — |
新增:crates/overlay(M3)、crates/edge(M7)、crates/ns/src/features/*(M7)。
3.2 nsgw
Section titled “3.2 nsgw”nsgw 的细化设计见 NSGW · 新架构设计(草案)。它在若干处与下表不同(差异一览);在相应决定获批之前,下表仍是已批准的版本。
| 现有 | 去向 | 里程碑 |
|---|---|---|
nsgw-quick-relay:core.rs、carrier.rs、service.rs | relay 报文 v2:NSR2、29 字节头、节点 ID 作 slot、删除 INTRO、/ns/v2 WSS 载体、能力宣告 | M2 |
nsgw-quick-relay:quick.rs(/quick/v1) | /rendezvous/v1(原草案 /quick/v2):会合信箱 + 登记表(publish、lookup_node)+ 目录 v2 | M2 |
nsgw-quick-relay:store.rs(标记库) | v2 标记库(以 I 为键、记录标记)+ 登记表 + 信箱持久化;v1 库在切换时丢弃 | M2、M5 |
nsgw-quick-relay:region/ | 同一套 mesh、复制与 owner 栅栏,把 16 字节 slot 换成 12 字节、KeyBinding 标记换成记录标记;登记记录纳入复制 | M2 |
| relay 核心(上面四项中与进程无关的部分) | 抽成库 crate nsgw-relay,由 relay 二进制使用;账户 relay 是同一个二进制按 NSD 投影的名单准入,独立成进程,nsgw-server 不内嵌它(D1) | M2 抽取、M6 部署 |
nsgw-wg::relay(mac1 中继)与 register_source、探测集合 | 被 relay v2 取代后删除 | M6 切换、M9 删 |
nsgw-wss:不透明中继(/client?mode=wss-relay、/wss-relay、pending) | 被 relay v2 的 WSS 载体取代后删除 | M6 切换、M9 删 |
nsgw-wss:Exit 的 WSS 承载(/exit-wss/v1)及 gateway-exit-wss 令牌 | 被 relay v2 的 WSS 载体取代后删除:网关是一个节点,UDP 被阻断的节点经 relay 到达它(D1、D4);节点侧的承载客户端(ns 的 exit_wss)与 NSD 的 exit_wss_token 签发一并删除 | M6 切换、M9 删 |
nsgw-wss:/relay connector(公网入口的 WSS 传输) | 不进入新线:公网入口到发布端只走 WireGuard,UDP 被阻断的发布端经 relay v2 的 WSS 载体到达;公网服务 tunnel 字段的 ws、wss、prefer_wss 取值在 M6 契约中重新定义或废弃;节点侧的 connector 客户端一并删除 | M6 切换、M9 删 |
nsgw-wss:节点侧 terminate(/client)、acl_gate、registry | /client 不保留(D4);公网入口的 ACL 门移到 nsgw-routing,规则的主体与目的地改为节点 ID / node6;nsgw-wss 不再作为 crate 存在 | M6 |
nsgw-wg:kernel、userspace、reconciler、routes(wg0) | 保留;wg0 只配 IPv6,peer 的 AllowedIPs 改为 node6 / node4 /128;网关自己的覆盖地址同样由其身份键派生 | M6 |
nsgw-wg::gateway_exit、gateway_egress、nsgw-gateway-egress | 保留,改为 IPv6:nft 表与 TPROXY 拦截按 node6 源匹配,出口对公网做 NAT66;IPv4 目的地见 §6.1 | M6 |
nsgw-envoy、nsgw-api、nsgw-routing | 保留;后端寻址从 Node IPv4 改为 node6 | M6 |
nsgw-control | 保留;删除中继配对表(gateway_wg_relay / gateway_wss_relay)与探测集合的消费,新增 relay 注册名单的消费 | M6 |
| 用量计量 | relay 路径按节点身份计量,由 NSD 归到账户 | M6 |
nsshared 依赖 keynet-proto、keynet-quick | 换成 v2 协议 crate | M2、M5 |
4. 里程碑
Section titled “4. 里程碑”| # | 交付 | 仓库 | 依赖 | 验证门 |
|---|---|---|---|---|
| M0 前置收敛 | ns 改为依赖 nsshared 的 v2 协议 crate(v1 控制面副本留到 M6);nsgw 完成 rustls → aws-lc-rs 与 /relay connector 路径删除;ns 把 boringtun 0.7 换成 nsplane-noise(decapsulate 源地址改为 SocketAddr);nsshared 的 keynet-* 改名 | ns、nsgw、nsshared | — | 各仓库 just qa;行为不变 |
| M1 协议 crate | nsshared 新增 v2 协议 crate:NodeRecord 与派生(标签、节点 ID、node6 / node4;lan6 与 IPv4 别名属于 ns)、relay 报文 v2、会合 v2(信箱、登记表、目录、能力)的消息类型;测试向量取自 v2 §2.3 | nsshared | M0 | 向量在 ns 与 nsgw 的测试里都通过;属性测试覆盖编解码与 §3.3 的顺序规则 |
| M2 relay v2 服务端 | nsgw-relay 库与 nsgw-quick-relay 的 v2 实现(§3.2 前五行),作为独立 feature / 二进制目标与 v1 并存;部署到 DEV 的独立端口 | nsgw | M1 | just qa;两实例 + 区域三成员的集成测试;登记冲突、限速与容量测试;DEV 上的端到端冒烟 |
| M3 覆盖网核心 | ns crates/overlay:身份与派生 v2、RelayClient(按能力选 UDP / WSS)、登记客户端、PeerSource trait、合并对端表、来源策略命名空间、路径阶梯(实现 nsplane 的 PathPolicy)。以库形式存在,尚未接入运行时 | ns | M1;nsplane 2 | 单元测试 + 对 M2 的 DEV relay 的集成测试;just dev-check |
| M4 账户模式换引擎 | nsd 来源运行在 nsplane 引擎上,协议与地址不变:tunnel-wg、netstack 的职责移到引擎,nat 的翻译按现有地址计划接成过滤器,阶梯走 overlay。由 feature 切换,默认仍为旧路径,回归通过后翻转默认 | ns | M3;nsplane 2、3、4 | 账户模式全部现有测试;tests/live-e2e;Windows / macOS 原生 TUN smoke;吞吐不低于旧实现;just ns-ffi-contracts |
| M5 Quick v2 切换(切换一) | quick 来源在引擎上直接实现 v2:记录、信箱配对、按 ID 放行、登记表发布与重新同步、隧道内控制通道、v2 命令;nsgw-quick-relay v2 上 PROD;目录换成 relay.ns.io 名字 + IP。两边同一版本发布,随后删除 v1 | ns、nsgw | M2、M3、M4;nsplane 5(翻译) | Quick 全部用例重写为 v2;两节点 + 区域 relay 的 live e2e;v1 状态迁移测试(只保留 I);发布说明写明”需要重新配对” |
| M6 账户地址与 relay 切换(切换二) | NSD 停止分配 Node IPv4,投影节点 ID / node6;ns 的 nsd 来源改用派生 v2,多个 NSD 与 Quick 同时运行,跨来源策略生效;账户 relay 以独立进程部署(relay 二进制按 NSD 名单准入),nsgw-server 作为节点接入它,wg0、ACL、路由、出口、Egress、公网入口后端改为 IPv6(node6);mac1 中继、不透明 WSS 中继与节点侧的逐路由 terminate 回退停用 | ns、nsgw、nsd | M4、M5;NSD 的配套工作(§5) | 三仓库同一发布窗口;账户模式 live e2e 全量;Quick ↔ 账户互通用例;多 NSD 并存用例;出口、Egress、公网入口回归 |
| M7 呈现统一与功能模块 | edge:TUN、netstack、DNS-VIP、SOCKS5 / HTTP / PAC 对所有来源可用;features/*:服务发布、公网入口、子网、出口、本地代理各自一个开关 | ns | M6 | 呈现 × 传输矩阵(新架构 §6)逐格测试;逐个禁用模块的回归 |
| M8 应用与名字 | ns send / ns receive(文件发送);应用会话接口;自研权威 DNS 服务(读取 relay 登记表,发布 n.ns.io)与短名分配;本地 resolver 的名字表统一 | ns、nsgw | M5、M7 | 文件发送设计用例;DNS 示例记录的校验测试;无 DNS 时的全部路径(新架构 §5.5) |
| M9 清理与转正 | 删除 ns 的 tunnel-wg、quick-runtime、quick-wire、quick-pairing、netstack、nat 的残余;删除 nsgw 的 mac1 中继、不透明 WSS 中继与 v1 代码;本站把设计页转为现状页 | ns、nsgw、docs | M6–M8 | cargo shear 无残留依赖;各仓库 just qa;文档链接检查 |
依赖关系:
M0 ─► M1 ─┬─► M2 ─────────────┐ └─► M3 ─► M4 ─► M5 ─┴─► M6 ─► M7 ─► M8 ─► M9nsplane: 2 ──────►3、4 ──►5M2 与 M3 可以并行;M4 不依赖 M2。nsplane 的第 2 阶段是 M3 的前置,第 3、4 阶段是 M4 的前置,第 5 阶段(翻译过滤器)是 M5 的前置。
4.1 进度
Section titled “4.1 进度”截至 2026-10-13:
| 里程碑 | 状态 | 说明 |
|---|---|---|
| M0 | 部分完成 | ns 以发布 tag 依赖 nsplane(v0.14.0,2026-10-13;0.11 于 2026-10-10 采用,见 0.11 迁移说明,0.12–0.14 都是 ns 请求的冻结例外)与 nsshared(v0.5.0,公开仓库 github.com/dotns/nsshared,CI 不再需要令牌);tunnel-ws 已删除;control、common、acl(只剩策略编译)、telemetry 的仓库内副本仍在。nsgw 的两项未开始 |
| M1 | 完成 | nsshared v0.1.0–v0.6.0:nsshared-proto(身份与派生、NodeRecord、relay 报文 v2、/rendezvous/v1、公网 DNS 发现与三档发布、登记表状态持久化与合并)、nsshared-telemetry、三个模拟服务;独立生成的测试向量;just semver 门。ns 用 v0.5.0,v0.6.0 已评估、暂不采用(nsshared) |
| M2 | 未开始 | nsgw 的新架构设计草案在推进(nsgw 新架构);它阻塞 Quick v2 的生产可用 |
| M3 | 实现完成,待最终 QA | ns crates/overlay(约 17k 行):身份、来源、nsd 与 quick 来源、合并对端表、策略、阶梯、relay / 登记表 / 信箱客户端、隧道内控制通道、自身记录;账户模式与 Quick 都在运行时使用它 |
| M4 | 完成 | 账户模式只在 nsplane 引擎上运行,旧数据路径删除(2026-10-03,ns 决策 2026-10-03-account-mode-engine-only);后续三轮(10-04 / 05 / 06)补上直连 P2P 阶梯、nsplane-wss 载体、netstack 反压与出口客户端栈,删除 tunnel-wg、netstack、tunnel-ws、ns-engine。剩余:几处待 nsplane MG 事项的循环、Windows tun crate(MT-3) |
| M5(切换一) | ns 侧完成,relay 侧待 M2 | Quick 自 2026-10-04 起只实现 v2(Quick 协议 v2),quick-runtime / quick-wire / quick-pairing 已删除,v1 状态只保留 I;开发与测试对接 nsshared 的 nsshared-mock-server。nsgw-quick-relay 仍是 v1,没有内置 v2 relay 目录,所以 Quick v2 对用户还不可用 |
| M6(切换二) | ns 侧完成(2026-10-13);NSD、nsgw 未开始 | ns 分支 refactor/nsplane 按决策 2026-10-11-node-memberships 实现了 M6 的节点侧(campaign l1-l3b1lesb-20261012,2026-10-12 至 13):设备密钥链与按 NSD 加盐的身份;平等的 membership 运行时(每个 NSD 的每个 Network 与 Quick 各为 nsplane v0.12.0 的一个本地身份,同一引擎,没有 active NSD,账户 / Quick 互斥取消);账户 Node 成为身份对端(node_identity.identity),WgConfig.ip_address 与 tunnel_ip 从线上删除,本机 IPv4 只是 ns 分配的 alias4;上报隔离与节点策略权威(ns policy);ns network join / leave / list 与 --network 选择器、按 membership 的出口(设备级出口连接器 EXIT4)、命名空间与名字、重叠 LAN 的本地虚拟网段(nsplane 0.14)、Quick 并入节点守护进程、新的状态 / libns schema(ABI 3);多节点互通套件(两个模拟 NSD + Quick + 模拟 nsgw,进程内、mock 二进制与 Docker 真实 ns 三层)通过。剩余一项:同一 Node 身份出现在两个 NSD 时只有先绑定者可达(nsplane 0.14 的按本地身份密钥路由尚未接入)。这条分支的账户模式与当前 NSD(6bce2220,仍投影 tunnel_ip 与 /32)和 nsgw(aa94aa5)不兼容,只对 ns 自带的模拟 NSD / 模拟网关运行:§5 的 NSD 工作包与 nsgw 的 M6 现在是阻塞项。另见 §6 D3 的 2026-10-12 修订与 D7 |
| M7–M9 | 未开始 | — |
5. 两次切换
Section titled “5. 两次切换”| 切换一:Quick v2(M5) | 切换二:账户地址与 relay(M6) | |
|---|---|---|
| 同时发布 | ns、nsgw-quick-relay | ns、nsgw-server、nsd |
| 用户可见的变化 | Quick 对端全部需要重新配对;地址与名字改变;ns quick 命令按 v2 调整 | 节点地址从 NSD 分配的 IPv4 变为 node6;应用里写死的 100.64.x.x 失效(名字不受影响);可以同时连接多个 NSD 与 Quick;每台设备重新登记(ns 不读取旧状态与身份) |
| 状态处理 | 备份状态目录,只保留 I;relay 以空的 v2 库启动 | 不迁移:身份改由设备密钥链派生(按 NSD 加盐),旧状态与身份不读取,每台设备在每个 NSD 重新登记(ns 决策 2026-10-11-node-memberships 第 9 条,2026-10-12 修订);NSD 侧 Node 记录改为身份键;本机 IPv4 别名由 ns 分配 |
| 回退 | 回退到上一个版本并恢复备份;v2 期间新建的配对丢失 | 三个组件一起回退;NSD 保留 IPv4 分配数据直到 M9 |
| 不受影响 | 账户模式(M4 之后已在引擎上,协议未变) | Quick(已是 v2) |
切换二需要 NSD 的配套工作。按决定 D6,现在不处理:本计划完善后把下面的清单作为一个工作包派发给 nsd 仓库实现;它阻塞 M6,不阻塞 M0–M5:停止分配并投影 Node IPv4(ns 侧已经要求:WgConfig 没有 ip_address,node_identity 携带 Node 的 Ed25519 身份键 identity 而不是 tunnel_ip,allowed_ips 为 N6 / N4 的 /128,withdrawn 是唯一的撤回方式);接受同一台设备在不同 NSD 使用不同的身份;wg_config、routing_config、acl_config 等事件改用节点 ID 与 node6;按节点 ID 查找 relay 登记表;向网关投影 relay 注册名单;Short DNS 名字迁到 zone 之下;出口与 Egress 的投影改为 IPv6;用量按节点身份归账。
| # | 问题 | 决定(2026-10-02) |
|---|---|---|
| D1 | 账户网关的中继是否换成 relay v2 | 换,全部基于 relay v2。 relay 核心抽成 nsgw-relay 库;公共 Quick relay 接受任意身份注册,账户 relay 只接受 NSD 投影的名单内身份。2026-10-07 修订:账户 relay 是 relay 二进制按名单准入的独立进程,nsgw-server 不内嵌 relay,像其他节点一样接入它(NSGW 新架构设计 的 G21)。节点侧只有一个 RelayClient,NSD 不再投影逐对的中继表;mac1 中继与不透明 WSS 中继在 M6 停用、M9 删除 |
| D2 | Quick v2 与 Quick 换引擎是否合并成一次切换 | 合并(M5)。 v1 不移植到引擎上,用户只重新配对一次 |
| D3 | 覆盖网只有 IPv6 后,网关侧怎么处理 | 网关直接用 IPv6,不做 IPv4 转换。 网关由我们控制:wg0、ACL、路由、出口、Egress 与公网入口后端都按 node6 处理,不给节点分配任何网关侧的 IPv4。唯一仍涉及 IPv4 的情形见 §6.1。2026-10-12 修订(ns 侧决定 B5b,待所有者确认):ns 的 membership 运行时保留了一条 IPv4 路径——到网关载体(terminate 服务、出口默认路由)的 IPv4 从 membership 的本机 carrier4 不经翻译在 WireGuard 内发出,地址不上报;因此 nsgw 需要接受已准入客户端的任意 IPv4 源并按 WireGuard 对端伪装回包,nsplane 不需要 NAT64(ns 否决了保留 NSD IPv4 与在 ns 内逐报文翻译两个方案)。这与“网关不做任何 IPv4”不同,也会取代 §6.1 的 NAT64 方案;确认前 §6.1 保留原文 |
| D4 | 节点侧是否保留”逐路由 terminate”这一级回退 | 不保留。 relay v2 的 WSS 载体覆盖 UDP 被阻断的情形。2026-10-06 修订:公网入口也不保留流代理,网关到发布端只走 WireGuard(NSGW 新架构设计 的 G20)。M6 一并删除节点侧的第三级 |
| D5 | n.ns.io 的权威 DNS 由谁提供 | 自研 DNS 服务器。 relay 把已校验的 NodeRecord 交给它发布,relay 进程自己不应答 DNS;在 M8 立项 |
| D6 | NSD 配套工作的归属与时间 | 现在不处理。 本计划完善后把 §5 的清单派发给 nsd 实现;它只阻塞 M6。2026-10-12:ns 侧已按新线上格式实现,工作包现在是阻塞项 |
| D7 | 多 NSD 并存的模型(2026-10-11,ns 决策 2026-10-11-node-memberships,本计划之外) | 平等的 membership,节点决定。 一个 NSD 的一个 Network、Quick、应用会话各是一个 membership,没有主 NSD,不按排序解决冲突;NSD 只提议,生效配置按受管配置 → 所有者决定 → 提议由节点决定,节点不在 membership 之间转发,也不向 NSD 上报其他 membership;每个 membership 的身份由一条设备密钥链按 NSD 规范 URL 加盐派生,运营方无法关联;不与旧 ns 兼容。M6 的节点侧按此实现 |
6.1 出口上的 IPv4 目的地
Section titled “6.1 出口上的 IPv4 目的地”2026-10-12:ns 的实现(D3 修订)改为从本机
carrier4不经翻译发出 IPv4,由网关按对端伪装;本节的 NAT64 方案在所有者确认 D3 修订后删除。
D3 之后,节点与网关之间只有 IPv6,这对公网入口、Egress、中继、IPv6 出口都没有问题。剩下一种情形绕不开 IPv4:节点经出口访问 IPv4 公网地址,目的地本身是 IPv4。这不需要给节点分配 IPv4,也不需要新机制,沿用节点已有的 4↔6 翻译过滤器即可:
| 位置 | 做法 |
|---|---|
| 节点 | 发往出口的 IPv4 报文由翻译过滤器映射为 IPv6:源为本机 node6,目的为 64:ff9b::/96 内嵌 IPv4 目的地(RFC 6052)。与 alias4 ↔ node6 是同一个过滤器的另一条规则 |
| 隧道内 | 只有 IPv6 |
| 网关 | 对 64:ff9b::/96 的目的地做 NAT64 后发往公网;其余 IPv6 目的地做 NAT66 |
网关侧的 NAT64 是这次迁移中 nsgw 唯一新增的翻译点,放在出口路径上:内核 WireGuard 没有原生 NAT64,实现上有两个选择——用户态路径直接复用 nsplane 的翻译过滤器,或内核路径配合独立的 NAT64 组件。这一点在 M6 的 nsgw 计划里确定,不影响前面的里程碑。只走 IPv6 出口的部署不需要它。
| 风险 | 缓解 |
|---|---|
| nsplane 阶段延迟拖住 ns | M0–M3 不依赖 nsplane 2 之后的阶段;M2(nsgw)完全不依赖 nsplane |
| M4 换引擎引入性能或平台回归 | feature 切换、默认不变;吞吐基准与原生 TUN smoke 是翻转默认的条件 |
| 切换二跨三个仓库 | 在 DEV / TEST 用同一组 live e2e 预演;NSD 保留旧分配数据到 M9 以便回退 |
libns 宿主(移动端)跟不上 schema 变化 | schema 升版本并保留旧版本一个发布周期;just ns-ffi-contracts 进入 M5、M6 的门 |
| 多个会话同时修改同一仓库 | 每个里程碑拆成各仓库自己的任务与计划,按 crate 划分工作流,避免跨工作流改同一文件 |
| 文档与实现脱节 | 每个里程碑的完成条件包含更新本站对应页面;M9 把设计页转为现状页 |
8. 下一步
Section titled “8. 下一步”- 派发 §5 的 NSD 工作包:ns 侧已按新的线上格式实现,NSD 不改则账户模式无法对接真实 NSD(2026-10-12 起阻塞)。
- 所有者确认 D3 的 2026-10-12 修订(网关按对端伪装 IPv4)与 §6.1 的去留;nsgw 的新架构草案据此补上网关 IPv4 契约。
- nsgw:M2 relay v2 服务端(阻塞 Quick v2 的生产可用)。
- ns 接入 nsplane
v0.14.0的按本地身份密钥路由,让同一 Node 身份在两个 NSD 里同时可达(其余 nsplane 等待项已随 0.13 / 0.14 关闭)。