NSD · 架构与功能设计
本页从纯架构视角描述 NSD(Network Service Director) 的功能划分与设计特点。改造路线见 roadmap.md。
1. 角色定位
NSD 是 NSIO 生态中唯一有状态的强一致组件,担任身份签发者、策略编排者与配置分发者三重角色,但不承载任何业务流量。一切"谁是谁、谁能访问什么、网关拓扑长什么样"的知识由 NSD 集中维护,再以单向推送的形式下发到 NSN / NSGW / NSC。
NSD 与数据面节点之间是"1 个 NSD × N 个数据面节点"的星型拓扑,但 NSIO 进一步允许"M 个 NSD × 1 个数据面节点":一台数据面节点可以同时归属多个 NSD,这使 NSD 既能以 SaaS 共享形态运行,也能以企业自托管形态运行,二者并存对节点是透明的。
NSD 的核心不变式:
- 永不持有私钥:节点身份与对等加密的私钥都不进入 NSD 的存储与传输;下发的 WireGuard 配置故意不含私钥字段,这是一个协议级硬约束而非约定。
- 数据面无应用层依赖:即使 NSD 整体不可达,已建立的数据面隧道仍按现有策略继续工作,只是失去了热更新能力。
2. 功能模块划分
NSD 按职责切分为五条相对独立的功能线,构成"NSD 五大职责":
2.1 设备注册表(Registry)
- 登记两类机器:Connector(NSN / NSC)与 Gateway(NSGW),分别承载"被访问端 / 访问端"与"数据面网关"语义。
- 幂等注册:客户端可在首次注册时携带或预派 machine_id,后续即便重复请求也不会产生重复实体,允许节点状态丢失后无副作用恢复。
- 公钥即身份:Registry 只保存公钥(签名公钥与对等公钥),从不持有私钥。
- 多 realm 切片:同一台机器在不同 realm 中可拥有独立的 machine_id 与注册状态,但底层机器身份只有一份。
- 生命周期事件:登记与注销引发依赖侧(策略、SSE 订阅)的级联更新。
2.2 认证服务(Auth)
NSD 维护三类首次入口与一类续签入口:
- authkey 注册:一次性预共享字符串入口,常用于受控批量部署;生产化要求支持限用次数、过期、撤销、绑组织 / 站点。
- device flow 注册(RFC 8628):无 authkey 时的"设备代码 + 用户批准"入口,用于桌面端无侧信道场景。
- 签名认证:每次启动以机器签名换取短期 JWT,要求时钟漂移不超过预设窗口,验证机器身份与请求一致性。
- token refresh:运行期通过 SSE 推送"凭证刷新"事件,使会话凭证可滚动而无需重新签名。
生产形态下要求 JWT 使用真实公私钥算法(RS256 / ES256)、暴露 JWKS、支持吊销;MVP 仅做契约打通。
2.3 策略引擎(Policy)
- 职责对齐:策略最终落地在 NSN(权威决策)与 NSGW(预过滤),NSD 只做"编辑、版本化、推送";NSD 不在路径上做实时鉴权。
- 配置面六类:WireGuard 拓扑、代理规则、ACL、网关拓扑、路由表、DNS 记录,六类配置共用一套版本与下发管道。
- 服务自动合成:NSN 上报本地服务白名单后,NSD 据此自动合成代理规则、路由、DNS,使"管理员只编辑高层意图,系统自动展开为低层配置"。
- ACL 编辑模型:NSIO 选择"仅允许"语义(不与拒绝叠加),配合"主体 × 资源 × 动作"三元组模型,支持基于角色与用户-资源映射的高层抽象。
- 演进维度:版本号 + 一键回滚、灰度发布、定时窗口、设备态势条件、双人审批、策略 DSL(类 Rego / CEL / HuJSON)、策略仿真与回放、策略测试工具。
2.4 配置分发(SSE)
- 单向推送通道:每个订阅者建立长连 SSE,NSD 按订阅者类型(NSN / NSGW / NSC)推送其关心的事件子集。
- 事件分类:WireGuard 配置、代理规则、ACL、ACL 投影(下发给 NSGW 的预过滤副本)、网关拓扑、路由表、DNS 记录、服务回执、凭证刷新、空闲心跳等多类。
- 触发模型:订阅建立、上报触发(services / gateway)、管理员变更、JWT 过期均可成为推送源。
- 协议可插拔:同一套事件解析器服务于 SSE / Noise IK / QUIC 三种传输层,选择哪种由客户端自决,NSD 端只需在边界处把握身份与会话生命周期。
- 多实例广播:生产形态下需要 Redis pub/sub 或同等机制把订阅广播跨多个 NSD 实例,以支持负载均衡、滚动升级、跨区。
2.5 管理面(Admin / Web UI / API)
- 唯一写入路径:所有变更最终经管理面写入 Registry 与 Policy 存储,SSE 自动级联推送。
- 多形态消费者:Web UI(管理员)、CLI(运维)、SDK(自动化)、Webhook(集成)、Terraform Provider(IaC)、k8s Operator(容器化)。
- 多租户与权限:行级组织隔离(MVP)、独立 schema / DB(企业);API Key 三层(用户 / 组织 / 管理员)、Service Account、邀请、审批、2FA / WebAuthn。
- 生态对接:OIDC(MVP)、SAML 2.0(GA)、SCIM 用户同步(GA)、HSM(企业);审计日志结构化输出与 SIEM 对接(Splunk HEC / Sentinel)。
3. NSD 与三类数据面节点的契约
NSD 是控制面唯一来源,其 API 表面被严格限制:
3.1 发现与健康
- NSD 自描述:类型(cloud / selfhosted)、所属 realm、支持的认证方法、版本、可选的 Noise / QUIC 公钥;客户端依此判定使用哪种传输与认证路径。
- 就绪探针:轻量端点供编排系统检测进程存活。
3.2 注册与认证(REST)
- 首次注册:authkey 或 device flow Bearer token 二选一。
- 签名换 JWT:每次启动一次。
- device 双步:获取设备代码 → 用户批准后获取 token。
- 心跳:数据面节点定时上报存活,以 60 秒级心跳维持租约。
3.3 数据面上报(REST)
- NSN 上报本地服务:NSD 据此合成代理规则、路由、DNS,并把回执反馈给上报方;同时 broadcast 给非 gateway 订阅者。
- NSGW 上报端点:NSD 据此把网关拓扑广播给所有 NSN(用于 WireGuard peer 配置)与 NSC(用于选路)。
3.4 配置流(SSE 长连)
订阅建立后,NSD 按订阅者身份推送对应事件子集,事件触发可以是订阅建立、上报触发、管理员变更或凭证刷新。
4. 设计特点
4.1 控制面与数据面解耦
NSD 不在请求路径上,数据面是否经过策略求值与 NSD 是否在线无关。NSD 故障域被压缩到"无法变更策略 / 无法新建注册"的范围,既有连接继续工作。
4.2 多控制面共生
NSIO 接受"一台节点同时归属多个 NSD"作为一等公民设计,而不是把它当作降级形态。合并发生在节点侧,NSD 之间互不感知。这降低了 NSD 联邦的工程复杂度,也保留了"客户私有 NSD + 云端共享 NSD"混合部署的可能。
4.3 协议可插拔的控制面传输
SSE 是默认的控制面长连,但 Noise IK 与 QUIC 共用同一事件解析器与同一身份模型。客户端可在严格 DPI 网络下直接选择 Noise / QUIC,不需要在 SSE 上做引导切换。NSD 提供这三种传输的对接面,但其状态表对消费协议无感。
4.4 上报驱动的策略合成
NSD 不要求管理员手工维护"代理规则 / 路由 / DNS"等低层配置,而是在 NSN 上报本地服务白名单后自动展开为这些低层配置。管理员的编辑面集中在 ACL / 角色 / 用户-资源映射等高层概念上,降低运营心智负担。
4.5 单一权威数据 + 单一推送通道
NSD 把"配置真相"集中在单一数据库,通过单一 SSE 推送通道下发,避免了"多源 / 多通道导致的状态不一致"风险。多 NSD 并行场景下,合并语义被定义在节点侧,而不是在 NSD 之间互相同步。
4.6 严格的私钥不可见性
NSD 的所有 API 与所有持久化结构都不接受私钥。即便客户端实现错误地把私钥提交上来,NSD 的契约也不会接收;WgConfig 故意没有私钥字段,使得"不含私钥"成为协议级而非流程级的承诺。
5. 与其他模块的边界
NSD 不做的事情:
- 不承载业务流量、不参与数据面包转发。
- 不持有私钥、不替任何一方签名业务报文。
- 不做策略合并:多 NSD 并行时,合并发生在节点侧。
- 不参与连接级 ACL 求值:NSGW 做预拒、NSN 做终决,NSD 只编辑与下发。
- 不做实时连接计费:计量埋点在 NSGW,NSD 接收聚合后的事件流。
6. 演进方向
NSD 生产化沿"六大能力轴"展开:
- 身份与组织:OIDC / SAML / SCIM、2FA / WebAuthn、API Key 分层、Service Account、邀请审批、Machine PKI。
- 策略与编排:版本号、一键回滚、灰度、定时窗口、Posture 条件、双人审批、策略 DSL、仿真与回放、策略测试工具。
- 网络编排:站点分组、用户分组、跨站点直连、Exit Node、Subnet Router、可视化拓扑编辑器、流量工程、Site Provisioning Key、Blueprint、ACME、Resource 管理、Share Link。
- 可观测与审计:结构化审计日志、SIEM 对接、连接日志、SLA 月报、异常检测。
- 运营与生态:CLI、Web UI、i18n、SDK(TS / Python / Go / Rust)、Terraform Provider、Webhook、k8s Operator、插件系统、air-gap license。
- 高可用与扩展:active-active 部署、Postgres + Redis、跨区 NSD、SSE CDN 化、多 NSD 联邦只读视图与冲突检测。
整体目标是建成一套生产级控制中心,对标 tailscale 控制中心 / headscale / zerotier controller / cloudflare WARP。NSIO 的不可放弃差异点(多 NSD 并行、协议可插拔、.ns + 环回 VIP 不需要 TUN、ACL 仅允许语义)在演进过程中必须保留。
7. 协议层组件清单
按协议层把 NSD 内部的组件做一次扁平汇总,详细职责见上文 §2 与 §3。
7.1 入站协议监听器
- HTTP REST API 服务器:发现、注册、签名认证、设备流双步、心跳、数据面上报六类入口。
- SSE 长连服务器:单向推送通道,按订阅者类型选择事件子集,逐事件签名。
- Noise IK 监听器:作为 SSE 的"无指纹外壳",握手成功后透明代理到内部 HTTP 后端。
- QUIC 监听器:作为 SSE 的"UDP 友好外壳",同进程或独立子进程承载。
7.2 身份与认证
- 设备注册表:登记 Connector 与 Gateway 两类机器,只持公钥。
- 认证服务:authkey、device flow、签名换 JWT、token 刷新四种入口。
- JWT 签发器:生产形态使用真实非对称签名算法,暴露 JWKS,支持吊销与黑名单。
- 协议级私钥不可见性:下发结构故意不含私钥字段,使"不持私钥"成为协议而非流程承诺。
7.3 策略与配置分发
- 策略合成器:由站点节点的服务上报触发,自动展开为代理规则、路由、DNS。
- ACL 编辑模型:仅允许语义,基于"主体 × 资源 × 动作"的三元组,支持角色与用户-资源映射的高层抽象。
- 配置分发器:按订阅者身份选择事件子集推送,触发源包括订阅建立、上报、管理员变更与凭证刷新。
- 事件签名器:对每条下发事件做签名,使外层传输被中间人时也无法静默篡改配置。
- 多实例广播桥接:生产形态下使用 pub/sub 中间件跨多个 NSD 实例分发订阅。
7.4 SSE 事件字典
- 数据面配置类:WireGuard 拓扑、代理规则、ACL、ACL 投影、网关拓扑、路由表、DNS 记录。
- 业务回执类:服务上报回执的三态(已匹配 / 上报但未绑定 / 拒绝)。
- 会话维护类:凭证刷新、空闲心跳。
7.5 管理面
- Web UI:管理员主入口,集中处理身份、ACL、网关、路由、DNS、审计等编辑面。
- 管理 CLI:运维入口,支持脚本化与排障(规划)。
- 自动化生态:多语言 SDK、Webhook、Terraform Provider、k8s Operator(规划)。
- 多租户与权限层:行级或独立 schema 隔离,API Key 三层、Service Account、邀请审批、2FA / WebAuthn、HSM。
- 审计与合规:结构化审计日志、SIEM 对接(Splunk HEC / Sentinel 等)、敏感操作告警。