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

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

107 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# FFSB 手动选择与统一 Surge 订阅
本方案替代同日早先的 `Proxy Station Claude` 本机协调层。最终状态、验证结果见下文;旧实现文档保留为历史记录。
2026-11-02 本机后续已完成 [Surge 原生 WireGuard 独立验证](FFSB-WIREGUARD-SURGE-2026-11-02.md),并于同日 11:05 按用户要求回退本文的正式 `Proxy Station`+FFSB 组合,24/24 请求验收通过。原生 WG 试验配置与身份仅保留在本机私有归档,未改生产订阅。本文的 utun100/本机 DNS 前提描述组合方案,不代表原生 WG 必须运行 FFSB;两种方式复用同一身份,不可并行连接。
## 原理与前提
业务配置由正式订阅统一生成,本机仅使用 `Proxy Station`。可见的 `🦀 Claude` 为手动 select,原有国家和 AI Nodes 成员保持不变,新增 `🦁 FFSB`。不使用自动 fallback,不运行定时探测/配置重写脚本。FFSB 不可用时选中它应失败;用户自行改选 Surge 节点。
FFSB 0.1.25 的 Go 构建信息表明它基于 `github.com/netbirdio/netbird`,基线 `v0.75.1-0.20260920041446-3ee1e3889f9c+dirty`。依赖包括 WireGuard userspace 实现、Pion ICE/STUN/TURN、gRPC、QUIC。这证明其技术组成,不证明每种协议当前都在使用。实测状态中有 P2P 连接、host/srflx ICE 候选及 WireGuard 握手;本机使用 utun100,地址 100.70.160.98,本地 DNS 为 100.70.255.254。不能把它当成一个已有本地 SOCKS/HTTP 监听端口的普通代理。
原架构的问题是 FFSB 的系统分域 DNS 和真实 IP 主机路由可在 Surge 接管前接走流量。改动前,同一 api.ipify.org 请求,普通系统入口出口为 138.75.58.11,显式 Surge 入口为 179.253.249.56,即使 Claude 选择的是 Surge。单加一个选项不足以控制所有入口。
新的必要前提是本机 FFSB **持久设置 `disableDns=true`**,并重连一次使其生效。它停止修改系统 DNS,但仍提供内部 DNS 服务及客户端路由。只执行 up 修改设置而不重连,本机实测旧分域 resolver 仍存在;down/up 后才消失。没有关闭客户端路由,否则接口无法承接目标地址。
正常系统 DNS 由 Surge 增强模式返回 fake-IP,业务连接因此先进入 Surge;不为 25 项配置 always-real-ip。Surge 完成域名规则匹配后:
- 选 `🦁 FFSB`:direct 别名绑定 utun100,`allow-other-interface=false`;25 项的 Host 映射交给 100.70.255.254,`dns-follow-interface=true` 绑定查询接口。FFSB DNS 为域名资源解析并维护路由,随后连接走 WireGuard。
- 选国家或 AI Nodes:由远端代理解析目标域名,不依赖 FFSB DNS。即使 FFSB 已关闭,fake-IP 接管和远端解析仍可用。
- 25 项之外:所有原 Claude 分类规则(包括其 1.0.0.1 DoH 传输规则)转给隐藏 `Claude-Surge-Internal`,它只引用现有 `🧠 AI Nodes`。用户已明确要求这些地址始终走 Surge;这个内部组不能选择 FFSB。
- FFSB 外层:实际 daemon 进程的 DIRECT 规则在业务规则之前,避免再套远端代理。其他应用的 STUN 防护不删除。
因此,连接出口和 DNS 无需靠脚本同步切换;它依赖 Surge 的 fake-IP 与代理远端解析机制,以及 FFSB 的一次性客户端设置。不是“任意设备仅导入订阅、不配置客户端即可自动就绪”:其他 Mac 须确认接口/DNS 地址及 disableDns;iOS 共存、不同 FFSB 版本未验收。
## 官方依据
- [Surge direct 别名](https://manual.nssurge.com/policies/built-in.html):允许在 Proxy 中声明带接口绑定的 direct 策略。
- [Surge 参数](https://manual.nssurge.com/policies/parameters.html):接口须具备目标路由;不允许其他接口时不可用即失败;dns-follow-interface 只控制查询接口,不能等同于动态选择 DNS 服务器。
- [Surge DNS](https://manual.nssurge.com/dns/advanced.html):fake-IP 将客户端连接还原为域名,再匹配出站策略。
- [本地与远端解析](https://kb.nssurge.com/surge-knowledge-base/technotes/dns):代理请求默认交给远端解析。
- [Host 映射](https://manual.nssurge.com/dns/local-dns-mapping.html):本地查询按首条映射选服务器;不是按组选项动态修改 Host。
- [隐藏策略组](https://manual.nssurge.com/policy-groups/parameters.html):hidden=true 隐藏菜单中的内部组。
- [NetBird CLI](https://docs.netbird.io/get-started/cli):disable-dns 停止配置系统 DNS;本机 FFSB help 也提供该参数。
- [NetBird 域名资源](https://docs.netbird.io/manage/networks/how-routing-peers-work):本地 DNS 转发至路由节点,路由节点解析域名。FFSB 是修改版本,最终依据本机结果,不假定上游全部行为一致。
## 实现与部署
`server/src/services/generators/surge-ffsb.ts` 是 Surge 序列化适配,读取 IR 内生产 settings 的 `FFSB` 配置;不另行查库、不修改原 IR,也不影响 Clash/Shadowrocket。配置字段为 enabled、interface、dnsServer、extraPolicy。25 项唯一源为 `server/assets/ffsb-domains.json`;原 `rules/ffsb-domains.json` 为指向它的相对符号链接。
适配器保留原成员、只追加 🦁 FFSB;置顶精确 25 项规则,原合并范围继续隐藏分流;有名称冲突、无效接口或内部组循环依赖时拒绝生成。生产原有 14 组/277 规则不需要改写,适配规则由生成器下发。
生产写入前在线备份:`/opt/proxy-station/data/backups/before-manual-ffsb-selection-20261019-143021.db`。部署脚本会更改目录属主,因此部署完成后重新检查并恢复此备份 root:root、600。
本机已停用并移出 LaunchAgents 的 `com.proxystation.ffsb-overlay.plist`;`Default.conf` 和 `Proxy Station Claude.conf` 已移入私有归档,未删除。Surge 配置列表只保留 `Proxy Station`。归档位于 `~/Library/Application Support/ProxyStationFFSB/manual-migration-20261019-142442/`。
## 验证
迁移前两次可回滚试验已验证:
| 条件 | 普通系统入口 | 显式 Surge 入口 |
|---|---|---|
| FFSB 开启、DNS 接管关闭、选 FFSB | 138.75.58.11 | 138.75.58.11 |
| FFSB 开启、DNS 接管关闭、选 AI Nodes | 179.253.249.56 | 179.253.249.56 |
| FFSB 关闭、选 AI Nodes | 成功,179.253.249.56 | 成功,179.253.249.56 |
| FFSB 关闭、选 FFSB | 超时失败 | 超时失败 |
Surge 请求 #58762/#58763 显示两种入口绑定 utun100;#58765/#58766 显示两种入口经美国节点 en0。FFSB 关闭失败不自动改选,符合手动模式。
类型检查通过;全量 75 个测试通过、1 个原有用例跳过。新增 5 个测试验证精确范围、DNS/规则顺序、唯一可见组、IR 不变、其他客户端无变化、参数和循环保护、原生解析。正式候选与 HTTPS 产物均通过官方 CLI,49/49 规则集下载并通过快照校验。13 个域名遮蔽提示对应有意置顶的 25 项覆盖较宽 Claude 分类,保留集合外规则,不将它们扩进 FFSB。
最终正式订阅(🦁 FFSB 命名)已再次验证上述四种组合,并恢复至 FFSB 开启、🦀 Claude 选择 🦁 FFSB:
- 当前 FFSB CLI Selected 清单恰好 25 项,与源清单集合相等;25/25 原生规则解释都进入 🦁 FFSB(通配项用匹配样本验证规则,不等同于该样本有业务服务)。
- 18 个精确域名中 16 个完成 TLS/HTTP 传输;`claudemcpclient.com` 与 `claudemcpcontent.com` 请求 #59298/#59299 命中正确策略,但 FFSB DNS 返回空答案,未算连接通过。HTTP 403/404/426 只代表传输和根路径响应,不是登录或模型调用成功。
- 4 个真实通配样本 www.anthropic.com、platform.claude.com、bridge.claudeusercontent.com、c.ffsb.sg 完成传输;其余通配范围没有声称穷举验收。
- 官方 API #59292:🦁 FFSB、utun100。两种入口 #59287/#59289 均为 FFSB 出口。系统 lookup 返回 fake-IP 198.18.2.126,Surge DNS trace 则经 100.70.255.254 返回真实 160.79.104.10,说明应用接管与隧道解析分层生效。
- 集合外 #59315 downloads、#59316 Auth0、#59317 Datadog 均经隐藏策略走 Surge;#59318 GitHub 与 #59319 ChatGPT 保持各自 Proxy/AI 分流。
- 手动选美国、新加坡、日本,普通系统请求分别得到 179.253.249.56、54.254.42.195、104.28.243.105,全部成功;结束后恢复 🦁 FFSB。
- FFSB 外层 #59344 UDP/51820:DIRECT、en0,双向有字节;STUN 命中 DIRECT,未被全局 STUN 阻断。单条 STUN 样本无下行不据此声称该次 STUN 成功。
- 其他现有策略组选择与变更前一致,仅 🦀 Claude 改为 🦁 FFSB,新增隐藏内部组;FFSB 有效配置仅 disableDns 从 false 改为 true。系统代理仍关闭、增强模式仍开启,未重启 Surge 引擎。
- 最终 emoji 更新后的 HTTPS 订阅再次通过原生校验、49/49 规则集快照校验。一次规则集拉取失败后复测成功,不将失败结果当通过。
私有证据归档到 `~/Library/Application Support/ProxyStationFFSB/manual-migration-20261019-142442/evidence/`,含原生请求日志、DNS trace、四象限结果、生产前后快照和部署日志;文件权限 600、目录 700,不提交 Git。实际模型业务、启动顺序及长期场景未纳入本次完成声明。
## 边界与恢复
后续故障(同日约 14:46):用户报告 GUI 检测失败,实际 curl 对 API、join、ipify 也超时。前台 `ffsb` 的检测请求命中业务策略 🦁 FFSB/utun100,但只有上行;后台 `ffsb-service` 的控制、WireGuard 和 STUN 仍命中 DIRECT/en0。直接指定真实 IP 并绑定 utun100 的请求同样失败;Go 默认 TLS 与经典曲线对照均超时,不支持仅为大 TLS 握手问题的假设。绕过的是内层业务接管,外层 UDP 仍经 Surge,因此尚未定位是 FFSB 状态、远端还是外层转发问题。管理/信令 Connected 不等于业务可用,早先验收仅代表当时状态。此次未修改配置或重连,证据归档于上述私有迁移目录的 `failure-followup-1446/`。
### 追加故障排查:新连接 TLS 间歇性停顿
同日继续排查,**尚未完成根因修复**。不能把前述迁移验收或暂时恢复视为稳定性通过。服务为第三方运营,用户确认没有服务端权限。
| 对照 | 实测结果与结论边界 |
|---|---|
| 外层进程与业务进程 | `ffsb-service` 的管理连接、WireGuard UDP/51820 命中 DIRECT/en0;前台 `ffsb` 的官方地址检测命中 🦁 FFSB/utun100,属于预期内层流量,不是仅凭策略名称就能判定的回环 |
| 仅排除两台外层服务器的 TUN 路由 | 临时排除 185.180.19.201/32、147.93.172.146/32;实际路由为 en0,重连后 3 个 HTTPS 目标仍超时;已恢复正式配置,没有保留排除项 |
| 系统 DNS 管理开关 | 临时启用再关闭并重连曾恢复;随后的同条件对照不能复现,之后再次失败;故不能归因为 disableDns 或 DNS 缓存 |
| 故障时直接查询 FFSB DNS | 可返回真实地址,随后 TLS 仍失败;单纯刷新 DNS 不能修复 |
| 绕过 Surge 内层接管 | curl 指定真实目标 IP 并绑定 utun100,同样失败;这不代表绕过了外层 Surge 转发 |
| TCP 抓包 | 15:00:08 的 API 新连接完成 SYN/SYN-ACK/ACK,327 字节 ClientHello 获对端 ACK,此后未收到 TLS 响应;同时其他既有 API 连接仍收发数据。未解密 TLS,也未调用计费模型 API |
| MTU 对照 | utun100 从 1280 临时降为 1200,新 SYN 的 MSS 从 1240 降到 1160,HTTPS 仍失败;已恢复 1280,未持久修改 MTU |
| TLS 实现与版本 | Go 默认/经典曲线和 curl 均出现超时;TLS 1.2 也失败。不能认定仅为 Go 的后量子 ClientHello 大小问题 |
| HTTP/HTTPS 对照 | 同一阶段 HTTP 曾成功,而 API、ipify、assets、pivot、ifconfig 多个 HTTPS 超时;HTTP 随后也有超时,不能断言故障严格只限 HTTPS |
| 延长一次观测超时 | API 最终 18.53 秒完成 TLS、18.72 秒收到 HTTP 404,超过 GUI 的 10 秒预算;这是延迟证据,不是修复,也未修改客户端检测超时 |
| TCP ECN | 仅测试 socket 上分别默认、关闭和开启 ECN,后来均成功;随后原 Go 测试也自行恢复,不能据此更改全机 ECN 设置 |
本机证据将问题收窄到 FFSB 数据路径的新连接/TLS 响应阶段;尚不能进一步区分客户端实现、外层传输、路由节点转发或其上游。需要服务商在 `b5-primary.ffsb.internal`(100.70.254.2,对外 185.180.19.201:51820)侧关联同一时间的抓包与转发日志。TCP ACK 可能由中间转发组件生成,不能仅凭它认定最终官方服务器已收到 ClientHello。[NetBird 官方排障](https://docs.netbird.io/help/troubleshooting-resource-connectivity)同样要求把 peer 连通、资源 TCP 连接及应用响应分层检查。
恢复后的最后观测窗口为 15:07:54—15:09:42(UTC+8):6 轮 × 4 路径共 24/24 完成 HTTP 响应,其中 FFSB 系统入口、显式 Surge 入口、真实 IP 绑定接口各 6 次,GitHub 普通 Surge 对照 6 次。官方 API 的 404 仅证明传输成功。原生请求 #61197 为 API → 🦁 FFSB/utun100,#61196 为 ipify → 🦁 FFSB/utun100,#61198 为 GitHub → US LA VMess Direct/en0。此窗口不足两分钟,不构成长时间稳定性验收;故障窗口中的失败没有被后续成功覆盖。全部原始证据归档到上述迁移目录的 `failure-followup-1510/`,附 SHA-256 清单。
本轮不重启 Surge、不关闭增强模式、不改生产规则;临时 profile、路由排除、系统 DNS 试验与 MTU 都已恢复。最终 FFSB resolved config 与排查前逐字段一致,旧协调 LaunchAgent 未加载。抓包进程已停止。原始日志和诊断包只留本地,不上传第三方。GUI 自动化工具不可用,最后的界面检测状态未重新验收。
本机普通域名客户端和显式代理入口是验收范围。硬编码真实 IP、私有 DoH、先前缓存的真实地址或旧长连接可能绕过 fake-IP,选择不会迁移旧连接;必要时重新建立应用连接。未对真实计费模型流、全部通配子域、长期运行、睡眠换网、IPv6 数据路径或其他设备宣称验收完成。
恢复旧客户端 DNS 管理需 `ffsb-service down` 后 `ffsb-service up --disable-dns=false`,不能仅改配置就断言生效。恢复生产功能开关通过管理 API 将 FFSB.enabled 改为 false 并更新订阅;不能只恢复系统 DNS、却误以为仍有统一手动入口。旧脚本和配置仅用于调查/回滚,不重新自动启用。