NSN · 架构与功能设计
本页从纯架构视角描述 NSN(Network Site Node) 的功能划分与设计特点。改造路线见 roadmap.md。
1. 角色定位
NSN 是 NSIO 生态在站点侧的运行时进程,担任"被访问端"的角色。它把 NSD 下发的策略落地为本机可执行的 WireGuard 隧道、本地路由 / NAT、Proxy / ACL 与监控接口,把对端(NSC 或远端 NSN)的流量代理到本地或远程服务。NSN 与用户侧的 NSC 在协议栈上对称,但流量方向相反。
NSN 的"价值锚点":
- 本地白名单是权威:能代理什么由站点侧自己声明,而不是由控制中心强制下发。
- 代理即 NAT:站点侧不重写 IP 头,只做端口到服务的查找,语义简单、合规友好。
- 三种数据面同栈:同一份业务逻辑在 TUN / 用户态网络栈 / WSS 三种数据面下复用,运维侧的"模式选择"不会影响功能契约。
2. 功能模块划分
NSN 内部按职责切分为若干相对独立的功能层,各层之间通过明确的状态对象与异步通道连接。
2.1 注册与身份
- 机器身份:基于 Ed25519(签名身份)+ X25519(WireGuard 对等身份)的双密钥模型,私钥永不出节点。
- 首次注册:支持一次性 authkey、按 realm 区分的 authkey、以及 OAuth2 device flow 三类入口。
- 多 realm 注册:同一台 NSN 可同时向多个 NSD 注册,每个 realm 拥有独立的注册状态与会话凭证,但共享同一份机器身份。
- 续签与心跳:运行期通过签名换取短期 JWT,并以固定周期向 NSD 上报心跳维持存活,同时在 SSE 通道接收凭证刷新事件。
2.2 控制面接入
- 协议可插拔:同一套事件解析器同时支持 SSE(默认)、Noise IK、QUIC 三种传输,业务上层无需感知传输差异。
- 多控制面聚合:对多个 NSD 并发订阅,按资源维度合并去重,屏蔽控制中心数量与拓扑差异。
- 配置类型分流:把 NSD 推送的配置流按用途解复用为 WireGuard 配置、代理规则、ACL、网关拓扑、路由、DNS、控制面状态、凭证刷新等独立通道,各自驱动对应子模块的热替换。
- 合并语义:WireGuard / 代理 / 网关 / 路由 / DNS 取并集;ACL 取并集并叠加本地 services 白名单作为兜底层,以防止任一控制中心异常导致全局拒绝。
2.3 服务白名单与上报
- 本地权威:每台 NSN 必须显式声明可被代理的本地或远端服务清单,禁止 NSD 反向告诉 NSN 能代理什么。
- 严格闭合默认:无白名单或白名单为空时全部拒绝,管理员模式仅作开发与测试逃生舱。
- 服务回执三态:NSN 上报后由 NSD 回应"已匹配 / 上报但未绑定 / 拒绝(策略指错节点)",运维侧据此辨别配置错位。
- FQID 命名约定:每个本地服务获得
<service>.<machine>.n.ns 的稳定全限定名,被 NSC 通过本地 DNS 解析为虚拟 IP。
2.4 数据面终结
NSN 的数据面有三种可选实现,但对上层呈现统一的"解密包流入 → 服务路由 → 后端连接"语义。
- 内核 TUN 模式:由内核 WireGuard 交付明文 IP 包,适合高吞吐固定环境,需要管理员权限。
- 用户态网络栈模式:由用户态 WireGuard 实现解密,smoltcp 完成 TCP/UDP 状态机,可在无 root 的容器、CI runner、企业笔记本中运行,这是默认形态。
- 纯 WSS 中继模式:不建立 WireGuard,所有数据帧通过 WebSocket 多路复用送达,用于 UDP 被严格阻断的网络环境。
三种模式共享同一套服务路由、ACL 评估、连接代理逻辑,差异收敛在数据面入口的"封包解封装"层。
2.5 服务路由与代理
- 服务路由器:以"目的端口"为查表键,把入站流量路由到本地服务或远端服务。
- 代理引擎:对 TCP / UDP 流分别执行字节级双向中继,中间不缓存载荷、不解析应用层。
- 远程服务回包:支持配置专用源地址,确保跨 LAN 路径的回包能正确返回 NSN。
- 连接追踪:维护反向 NAT 映射以支持回包匹配,具备 TTL、软容量上限与后台 LRU 清理。
2.6 访问控制(ACL)
- 仅允许语义:ACL 是白名单模型,默认拒绝,不存在与拒绝规则叠加的复杂语义。
- 入站维度:基于"主体 × 资源 × 动作"三元组的求值,主体由对端身份(NSC machine_id 或远端 NSN)决定,资源由本地服务标识符决定。
- 两层信任:NSGW 在
/client 入口做保守预拒过滤(快速反馈、可偏宽);NSN 终决并对所有路径同样的策略求值(不可偏宽)。
- 失败语义对称化:演进目标是把入站 WSS 与本地路由两条评估路径合并到单一 ACL 引用,统一 fail-closed 默认。
2.7 监控与可观测
- 只读 HTTP 端点集:对外提供存活、节点身份、网关、控制面、隧道、服务、ACL、NAT、连接、指标等多个只读视图,默认绑定回环、不开启鉴权,便于本地运维与编排系统拉取。
- 健康探针分层:
/healthz 用于编排系统快速就绪检测;详细状态接口供运维深查。
- 指标暴露:同时输出 Prometheus 文本与 OpenTelemetry 指标,允许复用既有可观测设施。
- 审计与拒绝事件:近期被 ACL 拒绝的连接以环形缓冲形式暴露,便于排查策略错位。
2.8 生命周期与启动顺序
NSN 的启动顺序被明确编排,以保证关键不变式:
- 先监控后控制面:健康端点早于业务模块就绪,使外部编排系统能够立即探测节点存在。
- 先 WireGuard 配置后网关配置:WireGuard 配置是阻塞前置条件,网关配置是 best-effort,超时后允许回退到默认接入点。
- 先 ACL 后传输:初始 ACL 必须在 WSS 入站打开之前装载,在等待超时后默认拒绝,避免空策略导致的越权窗口。
- 优雅退出:接收到终止信号后,按"停止接受 → 排空在途流量 → 释放资源"的次序收敛。
2.9 配置分层
NSN 采用"默认值 → 配置文件 → 环境变量 → 命令行"的递进覆盖模型,允许同一份镜像在容器、systemd、本地调试三种部署形态下使用同一套二进制,只通过分层来差异化配置。
3. 设计特点
3.1 多 NSD 并行
NSN 是 NSIO 的"多控制面"产品差异点的最直接体现:可同时归属于客户的私有 NSD 与云端共享 NSD,策略合并发生在 NSN 内部,NSD 之间互不感知。这既支持企业混合控制面,也避免了 NSD 联邦的工程复杂度。
3.2 协议可插拔的控制面
控制面在节点侧通过统一的事件解析层屏蔽了三种传输协议的差异。在严格 DPI 网络环境下可直接选择 Noise 或 QUIC,无需在 SSE 上做引导切换,降低运营态切换成本。
3.3 数据面三模式共享上层
无论数据面采用 TUN、用户态网络栈还是纯 WSS,服务路由、ACL 评估、代理转发、监控接口都不变。这是 NSN 之所以可以同时跑在数据中心服务器、企业笔记本、CI runner、Android 沙箱等多形态宿主上的关键。
3.4 私钥不出节点
机器身份与 WireGuard 对等身份的私钥都仅落盘到节点本地,控制面接收的配置中故意不包含私钥字段。该约束是协议级的,不依赖运维流程。
3.5 异步通道驱动的热更新
控制面下发的所有配置都通过独立 mpsc 通道触达对应消费者,业务子模块在不停机的前提下原子替换内部状态,运维变更不会引发节点重启。
3.6 背压而非丢弃为主
绝大多数内部通道使用有界缓冲 + 阻塞投递,通过自然反压保护下游;仅在网关事件这一类"可丢弃通知"上选择 try-send 静默丢弃。设计目标是让系统在过载时优先保持正确性,而非吞吐。
3.7 严格闭合的本地白名单
服务白名单是 NSN 不可绕过的最终防线。即便 NSD 误下发了指向本节点的代理规则,只要服务名不在本地白名单中,NSN 就会拒绝并把"配置错位"事实通过回执反馈给上游。
4. 与其他模块的边界
NSN 不做的事情:
- 不充当控制中心:不签发身份、不下发策略、不维护其他节点的状态。
- 不做权威认证:JWT 颁发、用户身份提供、设备态势采集都属 NSD 职责。
- 不做合并联邦:多 NSD 合并是 NSN 自己内部的逻辑,但 NSD 之间不通过 NSN 间接同步。
- 不重写应用层:对 HTTP / TLS 内容透明,只做 L4 字节级中继。
- 不分配虚拟 IP:
.n.ns 命名与 127.127.x.x 虚拟 IP 是 NSC 视角的概念。
5. 演进方向
NSN 的演进围绕三种形态展开:
- 数据中心 NSN:补齐多路径传输、可选拥塞控制算法、跨云互联、硬件加速等高吞吐能力。
- 边缘 NSN:支持无头 provisioning(以 provisioning key 自动注册)、边缘缓存与策略本地求值、离线缓冲。
- 移动 / 嵌入式 NSN:动态 keepalive、断点续连、低功耗唤醒、移动 App 沙箱内运行,把"NSN 不需要 root"这一点做成移动端的差异化优势。
跨形态的共同改造方向包括:连接级 trace 串联、per-service 时延 / 吞吐 / 错误率直方图、独立审计事件流、ACL 版本号与一键回滚、设备态势上报对接条件策略。
6. 协议层组件清单
按协议层把 NSN 内部的组件做一次扁平汇总,详细职责见上文 §2。
6.1 控制面接入(客户端方向)
- SSE 长连客户端(默认):订阅控制中心的事件流。
- Noise IK 客户端(可选):静态密钥握手,无 SNI、无 TLS 指纹,适合规避深包检测。
- QUIC 客户端(可选):基于对端公钥的鉴权,UDP 友好,适合 HTTPS 被干扰的环境。
- 多控制面聚合层:对多个控制中心并发订阅,按资源维度合并去重。
- 事件签名校验器:对每条配置事件校验签名,与外层传输是否被中间人无关。
6.2 数据面终结(服务端方向)
- WireGuard 用户态终结(默认形态,无需特权)。
- WireGuard 内核终结(可选 TUN 模式,由内核协议栈处理)。
- 用户态网络栈:在用户态完成 TCP / UDP 状态机,与内核 TUN 互为替代。
- WSS 中继接收端:承载多路复用的二进制帧协议,作为 UDP 受阻时的备选数据通道。
- 反向 NAT 与连接追踪:回包反向匹配,支持远端服务的回程路径。
6.3 应用层处理
- ACL 引擎:仅允许语义,作为入站权威终决点。
- 服务路由器:以目的端口为键查找本地或远端服务,作为 ACL 的入口点。
- 代理引擎:TCP / UDP 字节级双向中继,中间不缓存载荷、不解析应用层。
- 服务对账子系统:把下发的代理规则与本地服务白名单对账,产出三态回执。
6.4 身份与凭证
- 签名身份:用于注册、签名换 token、对端事件签名校验。
- 对等身份:用于 WireGuard 与 Noise IK,与签名身份共用同一份私钥文件,均不出节点。
- 会话凭证:由控制中心签发,通过 SSE 通道按需刷新,不需要重新签名。
6.5 监控与遥测
- 只读状态端点集:健康、身份、网关、控制面、隧道、服务、ACL、NAT、连接、指标多个视角。
- 双通道指标输出:Prometheus 文本与 OpenTelemetry 指标同时暴露。
- 拒绝事件环形缓冲:近期被 ACL 拒绝的连接以滚动队列形式可见,辅助策略排错。