Files
proxy-station/docs/design/wireguard-devices/HANDOFF.md
YANG JIANKUAN a5d980a5e9 feat: 添加 WireGuard 设备管理并完善客户端分流
实现独立加密设备身份、网关 agent、持久生命周期任务和 Surge/FlClash 专属订阅凭证。

完善 Shadowrocket 规则转换与 Clash AI DNS,增加 Surge FFSB 适配、规则快照、运维工具及验收文档。
2026-11-02 22:44:23 +08:00

10 KiB
Raw Blame History

WireGuard 设备管理实现交接

更新:2026-11-02。下述最初缺口已完成本地实现,包含设备加密存储/旧库迁移、网关 agent/回执、设备 UI 和订阅绑定。当前接续请先读 实现与上线验收。已部署 LA 应用与 njcq agent,原有两台设备只读纳管已完成;未刷新活动客户端;下方“已有能力与实现缺口”保留为实施前基线。

开始实现前先读

  1. 完整产品与技术设计:最新需求与验收标准的唯一方案入口。
  2. 可点击原型:设备列表、详情、独立导出,以及订阅页选择设备。可直接用浏览器打开;在对话内也可交互。数据、链接、二维码与握手均为演示。
  3. 既有 WG 实现与验证记录:2026-11-01 已落地的设备专用 token 模型、njcq 配置和历史验收,不代表新设备管理功能已实现。
  4. 根目录 AGENTS.md:仓库修改、验证、凭据、部署与线上数据操作约定。

用户最终确认的交互

  • 个人 macOS、iPadOS、iOS 设备统一使用支持 WireGuard 与入站的 Surge。用户同日随后已在三端全面实测 Surge + WireGuard 可工作,并要求停止 Shadowrocket WG 下发兼容;实际网络/版本/生命周期的具体证据范围仍以用户回报和实现记录为准。
  • 保留设备列表、私网 IP、状态、最后活动、上下行、管理操作及独立 WireGuard .conf / 二维码导出。
  • 去掉“使用客户端”,不按 Surge / Shadowrocket / 原生 WG 分支创建不同设备身份。
  • 在订阅页选 Surge 后,增加可清除的设备下拉框,来源为设备列表。
  • 未选设备:原默认 Surge URL 不变,配置只含原节点、策略组和规则,无 WG 配置项。
  • 选中设备:基于同一订阅入口生成带设备分发凭证的派生 URL,原代理内容加该设备的 WG 配置。不同设备完整 URL 可以不同;它们共享节点与规则来源。
  • 清除选择:恢复原默认纯代理 URL。只影响当前导出的链接,不修改其他设备的既有链接,不撤销 peer。
  • 新方案不安装身份模块,也不再靠新建一条独立订阅卡片表达设备。初次迁移保留旧设备专用 token;用户同日后续要求仅保留一个订阅,生产已退休两条旧设备卡片,设备通过原主订阅附加。详见实现记录。

选择某设备不能修改服务端全局状态或覆盖共享 token 的 wireguard 字段。 已生成的 A 设备 URL 必须继续获取 A 身份,不能随另一个浏览器选择 B 而变化。

已有能力与实现缺口(实施前基线)

部分 当前代码 后续工作
身份存储 sub_tokens.wireguard 可空 JSON,真实密钥由当前管理员 DTO 返回 建立独立设备实体、加密密钥存储和不含私钥的列表 DTO;迁移兼容旧 token
订阅生成 irFor() 附加当前 token 的身份,Surge/WG 序列化器已可用 将身份来源改为经过授权的设备绑定;无选择保持纯代理
自更新地址 Surge 路由的 selfUrl 当前没有查询参数 保留经过验证的设备凭证参数,否则下一次自动刷新丢 WG
独立导出 标准 .conf 与 Shadowrocket WG YAML 已有生成器 标准导出改为设备授权入口,复用同一身份,不再额外创建 peer
设备 UI 当前只有订阅卡片附带 WG 地址/链接 新增设备页、详情、状态与接入流程;订阅页新增设备下拉框
网关生命周期 一次性安装脚本预置两台设备 独立网关采集、幂等 peer 应用/撤销、运行与持久配置回执;不是只操作下载 token
?wg=... 当前订阅路由尚未解析这一参数 实现高熵、不可枚举、可撤销、绑定订阅和设备的分发凭证

上述表格为实施前的代码基线,已由本地新实现补齐;最新路径和行为见实现记录。原“当前代码”来自本地源码核对,不是本次重新读取生产 API 或远端配置的结果。工作区有其他未提交的 FFSB、规则、生成器等变更,需保留并按文件审阅,不用整目录覆盖或回滚。

代码定位

路径 作用
shared/src/wireguard.ts WireguardProfile、私网/密钥/MTU 校验;当前 MTU 默认 1280、上限 1420
shared/src/dto.ts 当前 TokenDto 与导出 URL,后续拆分设备元数据和私密领取
server/src/db/schema.ts、server/src/db/index.ts 当前 token 身份字段与旧库补列;新增表和迁移同时更新
server/src/routes/tokens.ts 当前 /api/tokens CRUD、重复身份检查、URL 和 DTO
server/src/routes/sub.ts token 校验、irFor()、标准 WG 导出、Surge 路由与 selfUrl;新增绑定鉴权的关键位置
server/src/services/ir.ts 原代理 IR 与可选 WG 身份类型,保留节点权限范围
server/src/services/generators/wireguard.ts 标准 WG、Shadowrocket WG、Surge WireGuard 段落生成
server/src/services/generators/surge.ts WG 代理声明、私网规则、自地址 DIRECT、托管 header 与公网组排除
server/src/routes/wireguard.test.ts 当前 WG token、迁移、隔离与配置行为测试,可扩展新绑定测试
web/src/pages/SubscriptionsPage.vue 当前 WG 仍作为 token 卡片额外导出;实现设备下拉与清除操作
web/src/App.vue、web/src/router.ts 增加“设备”导航和受鉴权页面
.claude/skills/edge-node-multi-protocol/scripts/17-install-wireguard.sh 既有 njcq 安装编排;目前不是通用设备地址分配器或网关 agent

管理资源沿用 /api/tokens。本地已实现 POST /api/tokens/:id/wg-bindings,其余设备、任务、网关与导出 API 见 实现记录,已发布到生产,设备侧新导入/入站仍须验收。

njcq 与设备身份基线

最后记录的服务为 Linux 内核 WireGuard,接口 wg-njcq,UDP 51820,网关 10.203.0.1/24。正式登记为 iPad Pro 10.203.0.2、Mac Studio 10.203.0.3,独立 keypair/PSK,MTU 已从临时测试恢复 1280。只提供 10.203.0.0/24 设备互访,不做 Internet NAT。

原型中 MacBook Air、iPhone、Windows/Linux 等额外设备、速率、状态、最后活动以及示例地址均不是正式登记清单,不能拿去初始化生产。iPhone 是否已有独立 peer 须在实施前核对,不能复用 iPad 身份。

2026-11-01 已验证:Mac Surge 6.11 入站及经 hub 访问本机 VNC;iPad 官方 WG → njcq → Mac Surge 的 Apple VNC 成功。Shadowrocket 普通 VNC 可用但 Apple VNC 黑屏,具体实现根因尚未确认。MTU 1420 不是已证实修复,临时修改与监测已恢复/结束。

用户后来统一三端为 Surge,因此 Shadowrocket 后续 TUN-only 等排查留作历史材料,不是本次设备管理的实现前提。Surge 三端安装后的自动更新、入站与 Apple VNC 仍需单独记录实际验收,不能用普通握手代替媒体可用性验证。

私有资料在哪里

仅列路径,不复制凭据。真实内容仍留在本机 Git 忽略的 edge-nodes/private/njcq-edge-node-docs/:

  • README.md:真实交付入口、订阅地址和备份说明。
  • subscriptions.json:既有两个设备 token、WG 身份与 URL 的交付记录,实施迁移前应与线上重新比对。
  • import/njcq-ipad.conf、import/njcq-ipad-qr.png:原生客户端的成功对照产物。
  • import/export-summary.json:导出摘要。

上述真实配置/订阅文件已核对存在、权限 600;父目录应维持 700。不得把真实订阅 URL、私钥、PSK、二维码或完整配置放入公共设计文档、普通日志或 Git。新克隆只携带公共源码和方案,不会自动携带这些私有交付记录。

njcq 远端配置在 /etc/wireguard/,备份索引见 WG 记录。需要操作生产时按仓库技能重新读取、备份和验证,不以历史交付数据覆盖最新配置。

实现时必须守住的边界

  1. 设备凭证不能是裸 ID/IP;普通共享订阅 token 不得通过枚举设备获得私钥。绑定校验订阅、设备、用途和撤销状态,密钥响应 no-store,日志与缓存按敏感数据处理。
  2. #!MANAGED-CONFIG 使用完整带设备参数的自身 URL,仅保留受支持且已验证的参数。无设备时继续原 URL。
  3. 公网节点、策略组、DNS、FFSB 手动分流和其他组选择保持原范围;WG 不被 Automatic/All Nodes 等选成 Internet 出口。
  4. 首次握手是连接证据,点击生成/复制/导入不是在线证据。采集过期显示未知,不使用缓存速率冒充实时值。
  5. 暂停必须真正移除网关 peer 并持久化;停用分发凭证不能撤销已下载的配置。移除后旧链接拒绝,不静默降级或换身份,设备 ID/IP 不立即复用。
  6. 幂等任务确认前不报成功;采用原子配置合并,保留非受管 peer 和现有 Tailscale、Docker 等共机服务。
  7. 本仓库另有 FFSB 原生 WG 试验,是第三方服务的不同身份/网段,不能合并进 njcq 私网设备或自动激活试验配置。其当前恢复状态以该文档与 AGENTS.md 为准。

实施与验收顺序

先纳管现有两台设备并只读采集;再做新增/暂停/恢复和独立导出;最后实现订阅设备绑定、Surge 配置生成与三端实际导入。迁移保留现有 key、PSK、IP 和旧链接兼容,不为了新 UI 重建所有 peer。

测试应覆盖默认无 WG、各设备私钥隔离、非法/跨订阅凭证、selfUrl 保留设备参数、设备暂停/归档、旧库迁移、失败幂等重试、采集失联、真实撤销以及节点范围/FINAL 不变。含密钥的 fixture 使用占位值,数据库验证在模块加载前设置隔离 DATA_DIR,不能测试真实 server/data。

验证命令依改动执行根目录 AGENTS.md 的 typecheck、相关 Vitest 与前端构建。Surge 产物先核对下载成功/结构,再用官方 CLI;CLI 通过仍需 macOS、iPadOS、iOS 的真实连接验收。生产部署和远端写入按后续用户授权执行。

本次交接保留了上一轮原型验证记录:设备选择/清除与配置结构、自更新 URL、独立导出、新增/暂停/移除、320–1024 宽度和深色外观。它们是原型验收,不是待实现功能的生产验收。