Files
proxy-station/docs/SURGE-FIX-2026-10-03.md

55 lines
6.1 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.

# Surge 订阅修复与验证:2026-10-03
本次完成 [体检报告](SURGE-AUDIT-2026-10-03.md) 中已确认缺陷的代码修复和生产定向调整。原体检报告保留为修复前证据,本文数量与验收属于修复当日;最新盘点见 [当前生产状态](CURRENT-STATE.md),后续变更流程见 [Surge 变更验证](SURGE-CHANGES.md)。
## 修复结果
| 原问题 | 已实施的处理 |
|---|---|
| C1 重置丢失规则 | 事务内恢复模板,更新保留自定义规则的顺序,不重新 INSERT 原主键;自定义 FINAL 不与模板重复;故障注入证明失败整体回滚 |
| C2 FINAL 缺乏保护 | API 拒绝停用、删除、改类型、重复创建、缺失/重复/不完整排序;IR 防御性保证唯一末尾 FINAL;页面关闭无效操作 |
| C3 配置字段编码 | 节点/组名称与控制字符校验,导入预览和写入一致;Surge 值、规则参数转义;逻辑表达式校验结构、无策略子规则和嵌套深度 |
| C4 组循环引用 | 写入前验证完整图、引用存在性与成员类型;组与成员替换、改名级联使用事务;节点/组/内置策略禁止名称冲突 |
| C5 丢成员及单来源 | 保留显式节点和内置成员;包含全部成员组来源;全节点展开去重且显式成员先于自动补充成员 |
| C6 VMess 映射 | 输出 TLS skip-cert-verify 与受支持 cipher;Surge 排除非零 alterId 和不支持 cipher 的 VMess,回报原因;当前生产节点不受额外排除 |
| D1 业务例外遮蔽 | 将 AppsFlyer/Amplitude 既有例外放到广告集合之前,保留原策略 |
| D2 视频 UDP 遮蔽 | googlevideo UDP 拦截移到 STUN 后、业务域名集合前,未扩大为全局 UDP 阻断 |
| D3 DNS 例外冲突 | 手写 Host 优先;按规则顺序保留 AI 之前的非 AI 域名/规则集 DNS 例外;update.googleapis.com 的原精确 DNS 映射不再被覆盖 |
| D4 提前主动解析 | 生产 IP reject RULE-SET 加 no-resolve;对尚未解析域名不再主动查 IP,已解析/IP 字面量仍可按黑名单处理 |
| D5 测速地址无效 | 删除 Surge 无效组级 url=;生产 General 的 proxy-test-url 改为 Cloudflare 204;UI 标明组级地址仅用于 Clash/ShadowRocket;fallback 不输出 tolerance |
| D6 默认控制口令 | 生产与初始化模板移除默认控制接口、Dashboard 及相关 TLS 参数;API/CLI 检查拒绝公开默认口令(包括带引号的写法);恢复 LAN 访问限制 |
| D7 MITM 上游验证 | 生产与模板改为 skip-server-cert-verify=false;API/CLI 检查阻止重新关闭上游验证 |
`scripts/check-surge.py` 是新增的只读本地验证入口:官方 Surge CLI、FINAL、测速与安全参数、当前规则集快照,以及静态域名遮蔽提示。update-db helper 新增 `--body-file`,敏感 JSON 不进入命令参数,并校验/引用请求路径。它通过 mock SSH 验证 stdin 正文、URL 引用及危险路径拒绝。
## 生产变更
在线备份:`/opt/proxy-station/data/backups/before-surge-audit-fix-20261003-223218.db`,SQLite `PRAGMA quick_check` 返回 `ok`,备份含 116 条规则。
在最新快照上预演三项管理 API 操作,执行前再次确认节点、组、规则、规则集与设置未被其他修改。三个 PUT 均返回 200:IP 黑名单参数、完整规则排序、Surge 设置。没有调用生产 reset、直接写 SQLite 或改动节点凭据、组成员和订阅范围。
变更后盘点保持:30 个节点、14 个组、32 个成员、116 条规则(115 启用)、62 个规则集、1 个订阅、6 个设置。Surge 仍输出 22 个节点,8 个 SS over WS 按能力排除。
前后端已部署;前端/源码指纹、systemd active、公网健康和无 token 管理接口 401 均通过。工作区尚未提交,没有创建 git 提交或推送。
## 验证证据
- 全量类型检查通过,44 项 Vitest 通过;隔离 SQLite 验证真实 API、事务回滚、重置与 FINAL/循环/非法输入保护。
- 本机 Surge Mac 6.9.1(12290)实际校验六组占位配置,覆盖带逗号正则与密码、引号/反斜线、动态成员、TLS 与 cipher、逻辑规则及通知参数、缺失 FINAL 防御。
- 前端 production build 通过。
- 生产 API 快照中的 160 个节点/组/规则对象通过新 schema;候选操作在隔离数据库通过实际 API 路由执行。
- 真实 HTTPS 的 Surge、Clash 和 ShadowRocket conf 均返回 200,并与已验证候选逐字节一致。
- Surge 实际配置官方 CLI:OK;60/60 当前远程资源下载成功,替换为本地快照后官方 CLI:OK,静态域名遮蔽提示 0。
- Clash 实际配置在独立临时目录下 `mihomo -t` 通过;没有启动代理或覆盖活动配置。
- 技能 frontmatter、相对引用、符号链接、脚本语法及 git diff 空白检查通过。技能校验器缺少 PyYAML,使用项目现有 YAML 库适配其解析接口运行原校验规则,没有安装全局依赖。
Surge HTTPS 正文 SHA-256:`0c12a56f72bbc0e1b116570bbcccd2208cdd1ca06568391a7769728ae5499caf`。脱敏校验结果见 [验证数据](SURGE-FIX-2026-10-03.verification.json)。原始 API 快照和含凭据配置仅在权限受限的临时目录,不进入仓库或报告。
## 保留的业务选择与验收边界
Automatic 仍为手动 select,Bybit 与 FINAL 的原默认直连语义、googleapis 的 AI 路由范围、Direct/Warp 混合候选、FFSB 和 SMTP 相关规则未擅自改成其他业务策略。googleapis 范围若要缩小,应另以业务域名范围为依据调整;本次修复其 DNS 例外优先级。
no-resolve 会降低对未解析域名的 IP 黑名单覆盖,这是避免提前主动 DNS 的明确取舍。控制接口默认移除;需要远程控制的设备应在设备侧配置独立凭据与访问限制。设备需更新订阅后应用配置;托管订阅并非即时推送。
本次没有切换设备活动配置、改变保存的组选择、测速连接、导入 CA 或抓取业务流量。CLI 成功不证明实际节点连通、测速结果、业务解锁、MITM 开关/CA 或 DNS/WebRTC 无泄漏;这些仍属于设备侧验收。