Files
proxy-station/docs/FFSB-SURGE-AUDIT-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

147 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 / Claude Code 网络审计
审计日期:2026-10-19。只读采集和无凭据网络探测;本轮未修改生产数据、客户端配置、DNS、路由或开关,未重启服务。用户已明确不关闭增强模式,故未执行启动顺序切换实验。
## 范围与结论
以 FFSB 当前下发的 **25 项域名规则**为唯一业务边界,不要求缩减其中的查 IP 和 FFSB 网站;其余流量继续遵循 Surge。Claude Code 的官方业务流量属于 FFSB 范围,GitHub、npm、第三方 MCP 与工具目标继续按 Surge 规则。用户已说明会将 Claude Code 的 Base URL 恢复官方,本报告不展开现有本机 API 网关。
**稳态下分流已基本成立;“所有启动顺序、断线与恢复阶段都只经 FFSB”尚未具备充分保障,不能宣称完成。** 现有配置有可复现的另一条出口路径:将 Anthropic 请求显式交给 Surge,会匹配 AI 组并通过其远端代理;直接 DNS 查询也可能绕过 FFSB 分域解析而得到 fake-IP。
| 用户要求 | 证据与判定 |
| --- | --- |
| FFSB 接管维护的 25 项 | 25/25 均有对应系统分域 DNS 范围;18 个精确域名中 16 个有地址且实际走 utun100、完成 HTTPS;2 个无 A 记录。通配规则不能靠根域探测宣称所有动态子域已验收 |
| Claude Code 官方业务只走 FFSB | 系统解析及本机独立 Bun 默认解析/HTTPS 路径成功;尚未恢复官方 Base URL 后进行真实 Claude Code 登录、模型生成或流式请求验收 |
| Surge 保留其他分流,不将 FFSB 套进远端代理 | FFSB 服务真实请求命中进程 DIRECT;GitHub 实际请求通过 Surge 原代理成功。但外层加密隧道仍由 Surge VIF 接管再 DIRECT 转发,并非完全绕过 Surge |
| 启动顺序无关、断线不串线、长期稳定 | 两端自动启动/连接配置存在,但没有就绪协调或本次查验可确认的专属出口约束;没有进行双启动顺序、睡眠唤醒或长连接测试。当前不能保证 |
## 本机状态及配置来源
- Surge 6.10.0,活动配置 Proxy Station,rule 模式;增强模式开启,系统代理关闭。`scutil --proxy` 也未显示 HTTP/HTTPS 系统代理启用。
- Claude Code 2.1.292,通过 Homebrew 安装;本次主要证据采集时未发现正在运行的 Claude Code 主进程。独立 Bun 1.4.2 探测不等于已测试 Claude Code 内嵌运行时及实际认证业务。
- FFSB daemon 0.1.25;有效设置为 `interfaceName=utun100`、MTU 1280、`disableAutoConnect=false`、`networkMonitor=true`、`disableDns=false`、`disableClientRoutes=false`、`disableIpv6=true`。状态中的 lazy connection 与有效配置读数曾有差异,不将其作为就绪保证。
- FFSB 服务与 GUI、Surge 均有 enabled/allowed 的系统后台/登录项。FFSB launchd 配置 `KeepAlive=true`、`RunAtLoad=false`;不应只看后者便断言不自启,也不能由 KeepAlive 推出业务已就绪。
- 已检查用户及本项目 Claude 设置、常用 shell 配置和 launchctl 网络环境;过滤本次 Codex 会话注入变量后,新 fish/zsh 交互 shell 未发现显式 HTTP/HTTPS/ALL/NO_PROXY。不能将此推广为所有已打开终端、IDE、任意项目或后续进程环境。
- 生产 API 重读:272 条规则,FFSB 服务真实路径的进程例外、3 个服务器 IP 例外及 bootstrap 域名直连均在现有配置;本轮未增删。`link.fufeishangban.com` 在 always-real-ip 中。
- Tailscale 同时 Running;FFSB 的 `100.70.0.0/16` 落在 Tailscale 常用的 `100.64.0.0/10` 内。当前已知 Tailscale peer 未落入该 /16,因此未发现现有 peer 冲突;未来新增 peer/路由仍需检查。
- 当前 en0/en1 未发现全局 IPv6 地址,FFSB 禁用 IPv6,Surge `ipv6=false`、`ipv6-vif=auto`。这仅是当前网络状态,不能替代以后在有公网 IPv6 网络上的验收。
## 当前链路及其边界
使用系统解析器访问清单内可解析域名时:
```text
应用 → macOS 分域 DNS → FFSB 本地 DNS 100.70.255.254
→ 按解析结果建立/使用 utun100 目标路由
→ FFSB 加密隧道 → 专线出口 → 目标服务
FFSB 加密隧道的外层连接
→ Surge utun5 → PROCESS-NAME /Applications/FFSB.app/Contents/MacOS/ffsb-service
→ DIRECT → 物理网络 → FFSB 服务器
清单外普通目标 → Surge DNS/utun5 → 原有规则与策略
```
`DIRECT`、系统代理绕过、VIF 路由排除是三件不同的事。当前 DIRECT 已证明避免 FFSB 外层走 Surge 远端节点,但 Surge 仍处理其包转发;所以不能说 Surge 完全不影响 FFSB。`utun5` 出现在外层服务器路由中,也不能单独证明隧道被远端代理。
macOS 的 `resolver(5)` 规定分域解析选择最长匹配后缀。系统查询正常时,FFSB 的 specific resolver 胜过 Surge 默认 DNS。NetBird 官方说明域名路由使用本地 DNS forwarder,并按查询结果增加目标路由;本机现象与之相符。但 FFSB 是定制客户端,不能把所有上游 NetBird 功能当作其已支持的功能。
证据:[NetBird DNS](https://docs.netbird.io/manage/dns)、[域名路由](https://docs.netbird.io/manage/networks/how-routing-peers-work)、[DNS 排查](https://docs.netbird.io/manage/dns/troubleshooting)、本机 `man 5 resolver`。
## 域名清单与实际检查
7 项通配规则:`*.anthropic.com`、`*.clau.de`、`*.claude.com`、`*.claudemcpclient.com`、`*.claudemcpcontent.com`、`*.claudeusercontent.com`、`*.ffsb.sg`。全部存在对应根域的系统分域 resolver。
以下为 18 个精确域名的无凭据 HTTPS 根路径探测。HTTP 403/404 只能证明 TLS/HTTP 可达,不代表登录、模型调用、内容权限或完整业务通过。
| 域名 | 解析/路由 | HTTPS 状态 |
| --- | --- | --- |
| a.claude.ai | utun100 | 404 |
| anthropic.com | utun100 | 301 |
| api.anthropic.com | utun100 | 404 |
| api.ipify.org | utun100 | 200 |
| assets.claude.ai | utun100 | 403 |
| clau.de | utun100 | 302 |
| claude.ai | utun100 | 403 |
| claude.com | utun100 | 200 |
| claudemcpclient.com | 无 A 地址 | 未执行 HTTPS |
| claudemcpcontent.com | 无 A 地址 | 未执行 HTTPS |
| claudeusercontent.com | utun100 | 301 |
| ffsb.sg | utun100 | 200 |
| icanhazip.com | utun100 | 200 |
| ifconfig.me | utun100 | 200 |
| ip.net.coffee | utun100 | 200 |
| join.fufeishangban.com | utun100 | 302 |
| pivot.claude.ai | utun100 | 200 |
| www.claude.ai | utun100 | 301 |
两个无地址 MCP 根域:FFSB DNS 返回 NXDOMAIN,公共 DNS 返回 NOERROR/空 A 回答。二者响应语义不同,不能声称 DNS 答案完全一致;但两边都无 A 地址,不能将根域 HTTPS 无法探测认定为隧道故障。仍需有效的动态子域样本验收,未通过猜测或采集用户会话内容来制造样本。
已另行核对 `platform.claude.com`、`mcp-proxy.anthropic.com`、`bridge.claudeusercontent.com` 的系统解析及路由,均为真实 IPv4/utun100,验证了相应通配域的一部分范围。
`downloads.claude.ai` 不在这 25 项内,实测为 fake-IP/utun5,符合 FFSB 客户端界面的安装包/更新例外。此处不扩展 FFSB 清单。域名相同 IP 时,系统 IP 路由可能一并覆盖该 IP 上的其他域名,因此这种模式并非逐 HTTP Host 的严格隔离。
## 已证实的旁路与尚缺的保障
### 1. DNS 路径不同会改变结果
同一时段、同一域名 `api.anthropic.com`:
- Python/system getaddrinfo、Node `dns.lookup`、独立 Bun 默认/system backend:真实 IP,目标路由 utun100。
- Node `dns.resolve4`、Bun c-ares backend:Surge `198.18.*` fake-IP。
- 独立 Bun 默认 fetch 两次均完成 HTTPS,约 488/370 ms。
这不是断言当前 Claude Code 默认使用 c-ares;它说明现有分域接管依赖解析路径,不能凭规则列表保证所有调用方式。Node 与 Bun 官方文档明确区分系统解析器和直接 DNS 后端。浏览器 Secure DNS、显式代理和其他运行时也应分别验证。
参考:[Node DNS](https://nodejs.org/api/dns.html)、[Bun DNS](https://bun.sh/docs/runtime/networking/dns)。
### 2. 显式代理可实际绕过 FFSB
本次只对单次无凭据 curl 请求指定已有 `127.0.0.1:6152`,未修改任何系统或应用代理配置。实际 Surge 请求 `#51640` 的 `api.anthropic.com:443` 命中 `RULE-SET ai.conf`,通过 AI 组的美国 Trojan 节点,完成 HTTP 请求。不是仅靠 rule match 推测。
因此,如果 Claude Code 后续继承 HTTP/HTTPS_PROXY,或其他客户端使用 Surge 系统/显式代理,当前配置允许清单内目标改走 Surge。新 shell 当前没有这些变量,并不构成禁止以后使用其他出口的机制。Claude Code 官方文档确认读取代理环境变量,并支持 NO_PROXY;既有进程不会随 shell 后续修改自动更新。
参考:[Claude Code 网络配置](https://code.claude.com/docs/en/network-config)。
### 3. 没有完整的启动/断线闭锁
自动启动不等于以下步骤已完成:管理连接、peer 握手、分域 DNS 注册、域名路由建立、真实 HTTPS 可用。FFSB 未就绪或退出时,Surge 的 AI 域名规则仍在;缺少 FFSB 路由/解析条件时,存在切换出口的配置路径。未实际关闭 FFSB 或 Surge 来验证该场景,不能将推断写成已实测断线结果。
本轮没有验证“Surge 先启动”和“FFSB 先启动”的完整矩阵,也没有运行 Claude Code 真实登录/流式业务、长时负载、网络切换或睡眠唤醒。此前反复出现超时后重新检测成功,根因没有被严格隔离;不能以成功重测认定已经永久修复。
### 4. 其他分流及服务自身流量正常
FFSB 服务真实请求的完整路径与生产进程规则一致,STUN 有响应;通过相同 STUN 目标、不同进程路径模拟,Chrome 仍为 REJECT。普通 GitHub 请求 `#51650` 命中 GitHub 规则集并通过 Surge 原代理,HTTP 200。Tailscale 的既有规则和本机选择未修改。
## 建议实施方向:不是继续扩大服务器网段
以下为待实施/待验收方案,不是本次已经部署的结果。
1. 保留已验证的 FFSB 服务进程 DIRECT、bootstrap 域名真实解析和已有服务器例外。服务器地址变化应主要由进程匹配覆盖,不靠放行宽网段。不要把 Claude Code 全进程设置为裸 DIRECT,这既不能强制使用 FFSB,还会改变清单外工具流量。
2. 以这 25 项维护单一清单,核对系统分域 DNS 与 Surge 内部 DNS 的一致性。若需要覆盖被 Surge 捕获的路径,候选做法是为该清单明确配置 FFSB DNS,并配合 always-real-ip;不把全局 DNS 改成 FFSB,不将 FFSB 控制服务器解析交回依赖自身隧道的 DNS。需验证解析失败时不自动落到公共 DNS。
3. 对已进入 Surge 的清单内请求,增加“只交给 FFSB 接口、不可回落”的策略,而非普通 DIRECT。例如官方支持 `direct, interface=utun100, allow-other-interface=false`。**这是候选机制,未在本机启用或通过启动矩阵验证**;必须先保证目标路由由 FFSB DNS 建立,核对接口实际存在及路由有效。仅靠这一项不保护 Surge 自身也未启动的阶段。
4. 若需求是“任何时刻都不可从别的出口发送”,还需要独立于应用启动顺序的约束:FFSB 未就绪则等待/拒绝,断开后停止新请求,并验证既有连接。启动前一次探测或普通脚本包装不能提供持续保障。应选择并验证本机持久流量限制或仅能通过 FFSB 出站的专用入口,而不是只依赖自动启动顺序。
5. 该类接口/DNS 绑定属于这台 Mac 的配置,应使用本机专用配置/模块,不能未经评估就向所有共享订阅设备下发 `utun100` 和该机的 FFSB DNS 地址。
Surge 官方依据:[VIF 排除与系统代理](https://manual.nssurge.com/profile/general.html)、[Host 首条匹配/分域 DNS](https://manual.nssurge.com/dns/local-dns-mapping.html)、[真实 IP 例外](https://manual.nssurge.com/dns/advanced.html)、[指定接口与禁止其他接口回落](https://manual.nssurge.com/policies/parameters.html)。这些说明验证机制存在,不能代替本机端到端测试。
切勿向 `tun-excluded-routes` 机械添加 Claude 目标公网 IP 或整个 `100.64.0.0/10`:本项目已有物理网关排除覆盖 VPN 路由的实测教训,见 [Surge/Tailscale 共存](SURGE-TAILSCALE.md)。FFSB 外层公网服务器和 FFSB 内层业务目标必须分开处理。
## 完整验收矩阵
| 场景 | 必须核对 |
| --- | --- |
| Surge → FFSB → Claude Code | 25 项 DNS/路由就绪,真实官方认证与模型请求走 FFSB;清单外仍按 Surge |
| FFSB → Surge → Claude Code | Surge 上线不改写/绕过已建立的 FFSB 业务路径;同上 |
| Claude Code 先启动、FFSB 后上线 | 上线前等待或明确失败;不得先走 Surge/ISP,恢复后使用 FFSB |
| FFSB 断开或 daemon 崩溃 | 新请求不换出口;既有连接的行为有记录;恢复后的连接重新校验 |
| Surge 重载托管配置/重启 | 本机覆盖仍存在,FFSB DNS/路由正常、控制与 STUN 不被拦截 |
| 睡眠唤醒、切换网络、有公网 IPv6 | 无 DNS/路由残留和其他出口回落,第三方流量仍正常 |
| 长时间 Claude 流式请求 | 不仅根路径 HTTP 成功;验证实际流、持续连接、重试和出口 |
## 证据保存与限制
敏感快照仅位于本机私有目录 `/private/tmp/network-audit-20261019/`,不提交 Git。这里仅记录脱敏结论及公开域名。运行时路由与 IP 可变化,后续实施前应重新采集。
本轮没有改网络,因此不存在本轮生产变更备份或“已部署修复”声明。先前进程路径修复与备份见 [FFSB 直连记录](FFSB-DIRECT-2026-10-19.md)。