2026-08-19 · vpn-guard 出口归属门槛与四处假绿修复 · 迭代复盘
入档:2026-08-19 来源:一次从「我从没被封、同事却反复被封,为什么」起步的会话,一路做成 vpn-guard 的一轮加固 状态:已落地,分支
feat/exit-provenance-gate6 个 commit,CI 硬闸门 48 项全绿;app-vpn.*待作者自行提交 环境:Windows 10 Pro + Clash Verge Rev(verge-mihomo,TUN 模式),机场「国外默认」组 41 节点
事实记录(不可修改区)
实测数据(2026-08-19,auto-select-node.ps1 -DryRun)
Top10 低延迟节点里 9 个是机房出口,其中 6 个直接租自公有云:
| 节点 | 出口 ISP | ASN | ip-api hosting |
|---|---|---|---|
| 🇹🇼 台湾07 | Chunghwa Telecom | AS3462(16 位) | false —— 唯一真住宅 |
| 🇯🇵 日本01 | IPS INC | AS131939(32 位) | false |
| 🇹🇼 台湾01 | Pittqiao Network Information | AS131642(32 位) | false |
| 🇭🇰 香港03 | Mejiro Network Limited | AS209642(32 位) | false |
| 🇸🇬 新加坡01 | DigitalOcean | AS14061 | true |
| 🇯🇵 日本03 / 🇰🇷 韩国01 / 🇮🇳 印度01 | Amazon | AS16509 | true |
| 🇰🇷 韩国03 / 🇦🇺 澳洲02 | Oracle | AS31898 | true |
- 作者长期使用的节点是新加坡01 = DigitalOcean,而其账号从未被封。
- 出口轮换检测(同节点连探多次)零命中:该机场不是负载均衡池。
- 四个 ASN 值均向 live ip-api 逐一核对过。
commit
6036d0d 轮换检测 + ASN 归属门槛 + 两个评分 bug · 355cd54 互补性文档 · b63d9d8 审计器三态判定 + 两处假 FAIL · c04b571 回归测试挂 CI · b907d8e README 定位重写 + 14 处文档订正 · bdb2a58 Unix 系统代理假绿
弧线:问题不在工具里
起点是一个归因问题,不是功能需求。答案落在工具碰不到的那一层——账号出身,已抽成 ⭐ 信任资产保得住造不出_账号基线vs人群先验_v1。
但归因过程反过来暴露了工具的一串真问题:代码量集中在最低权重的那一层(技术指纹几百行),而最高权重的 IP 信誉只有两个布尔值。
工具侧的四个发现
1. hosting=false 不等于住宅(判据要找结构性事实)
ip-api 的 hosting 标记漏报了三家小主机商。有效的判据不是名字长相,而是ASN 分配年代:16 位 ASN 空间(1–65535)在 2014 年前后被各注册局分配殆尽,而做大众家宽需要巨量地址和多年运营史,所以在位运营商全持低号段;32 位 ASN 绝大多数是之后注册的小主机商。IPv4 与 16 位 ASN 双双耗尽,这条分界线不会再移动。
两个机制沿号段年代互补,覆盖不重叠(实测验证,不是巧合):
| 机制 | 覆盖 | 本次命中 |
|---|---|---|
ip-api hosting=true | 老牌大云(16 位老号段) | AWS / DO / Oracle,6/6 |
| ASN 年代规则 | 新小主机商(32 位) | IPS / Pittqiao / Mejiro,3/3,ip-api 全部漏报 |
关键不变量:6 个大云无一被 ASN 规则误判为住宅——那是唯一不可接受的方向。
2. 四处「假绿 / 假红」,全是既有代码
| 位置 | 症状 |
|---|---|
| 评分公式的延迟项 | delay 存 hashtable 键,Measure-Object 只认 PSObject 属性 → 取不到极值 → 归一化退化成常数,实际生效的是「带宽 80% + TLS 20%」而非文档写的 60/25/15。错误被脚本头部 SilentlyContinue 吞掉 |
| 单节点池 | Sort-Object 返回标量 Hashtable,$ranked[0] 退化成按键取值返回 $null(部署目标为空),.Count 返回键数 → 结果表打十几行空行。新门槛的本职就是造出单节点池,@() 包裹是必需的 |
| 第 2 项(Unix) | 两侧都是 curl,而 curl 不读 scutil/gsettings → 系统代理下两侧都直连、拿到同一 IP → 打绿「不认代理的程序也被隧道接管」。影响面覆盖第 3/4/5 项(都拿第 1 项当基准) |
| 第 2 项(两版) | 轮换池下两个探测都走隧道却拿到不同 IP → 报了个不存在的「真实 IP 正在泄露」 |
「延迟项失效」的证明方式值得记:用坏公式重算,精确复现了实跑打印的全部四个分数(100 / 98.2 / 49.4 / 35.7)。能复现输出的模型才是被证明的模型,比读代码下结论硬。
3. 有一条结构性论断可以不测就确信
TAKEOVER="sysproxy" 只在 case "$route_if" 的 *) 分支设置,TUN_ROUTED=1 只在 TUN 分支设置——二者互斥。于是「不认代理的程序也被隧道接管」这句话在非 TUN 下恒为假,与两侧 IP 是否相同无关。这条修复不需要取任何代理地址,纯靠代码结构推理。
判据:先找能靠结构推出来的那部分,它不需要环境就能验证。 剩下需要环境的部分(取 scutil 地址)再单独处理,而且要能在取不到时诚实降级,绝不猜。
4. 内联三份拷贝反而是对的
ASN 名单要进 3 个脚本。共享库文件会让分类器的唯一正面判定依赖一个用户没有的文件——而这个仓库的分发方式就是「拷一个脚本走」。剥掉机构名后名单只是 93 个整数、26 行,且任何分歧都只影响召回:漏一条把「住宅」降级为「未识别」,永远不可能产出虚假的安全声明(两条会告警的判据根本不读这张表)。
判据:允许重复的前提,是重复的那部分「错了只会更保守」。 再由 CI 做机械比对兜住漂移。
方法论教训
测试不会失败,就等于没有测试
写完 30 条断言后先投毒证明它会挂:改判定阈值 → FAIL=2;往机房词表加裸词 data → 应 FAIL;只改一版措辞 → FAIL=1 带逐行 diff。
第二种投毒通过了 30/30——我自己的哨兵是坏的。 原因:哨兵样本的 ISP 写成 "Some Regional Telecom Co.",其中 Telecom 命中运营商词表 −3,正好抵消裸 data 的 +3,那条断言在任何情况下都触发不了。这是 全站文字截断体检_检测工具本身要先被证伪_v1 的新变体:
那篇是工具的判据不可信,本篇是哨兵被自己的样本中和——断言写对了、样本选错了,症状是永远绿。 对口手法:投毒。不投毒就永远发现不了,因为它和「真的没问题」表现完全一致。
顺带纠正了主脚本里一条说过头的注释(称裸 data 会「误杀唯一一个真住宅节点」——实际中华电信被名单在第 1 步短路,根本走不到词表)。
文档会从代码上漂走,而且双语同漂时 diff 查不出来
三路核查文档 vs 代码,33 条原始发现确认 18 条。其中若干是我自己刚写的:
- 引用的实测数字没标出处,而仓库里的运行产物是另一次运行、结论相反;
- 把归属判据吹成「单一结构性规则、不像词表会腐坏」,而分类器本身就带两张词表,机房词单条就够到阈值;
- 「判据与选点器同源」是错的——审计器是 5 分支阶梯,选点器是加权评分,两个方向都能实测出分歧;
- 「第 7 项看握手耗时」off-by-one(第 7 是 WebRTC,链路质量是第 8)——两版同错,双语 diff 查不出来,还传染到了 CI 注释;
- 局限里写「账号出身权重最高」,而同一篇的表把它排在第 2。
判据:自己写的两份平行文档不能互为校验,必须拿代码当第三方。
会用工作流,也要会怀疑工作流
两次多路设计工作流里,第二次 3 个设计 agent 挂了 2 个(StructuredOutput 重试超限),产出实质是「单一方案 + 自评」,对抗性并没拿到。此时不能按「三路综合」的信任度采纳:13 个 block 只取骨架,每条 premise 独立复核,状态机自己写。
判据:读工作流结果前先读它的失败计数。
用户漏掉的操作风险,可能就在工具自己身上
两版 README 都没提:扫描过程本身会把全局出口逐个切过每个候选节点(默认最多十余次,含随后才被淘汰的)。开着 Claude 跑,会话几分钟内跨多国跳变——正是文档开头权重表里第 3 层的「国家跳变」。-DryRun 同样会切。
关联文档
- ⭐ 信任资产保得住造不出_账号基线vs人群先验_v1 —— 本次归因结论抽出的原子律
- 2026-07-14_vpn-guard从工具到宣传片_全链路复盘_v1 —— 同一工具的上一段弧线(需求→开源→宣传片);本篇是它之后的加固轮
- ⚠️ ping通不等于路通_fake-ip假信号与节点带宽实测选型_v1 —— 直接续篇:那篇立「别看延迟选节点」,本篇发现选点脚本里延迟项本身就是死代码,实际权重与文档不符
- ⭐ 全站文字截断体检_检测工具本身要先被证伪_v1 —— 本篇「哨兵被自己的样本中和」是它的新变体(工具判据 → 哨兵样本)
- ⭐ 交付前实测证伪律_v1 —— 全程按它执行;本篇新增变体:能复现既有输出的模型才算被证明
- ChatGPT_Windows桌面版安装排障与账号合规边界_v1 —— 同域,那篇校正封号相关的过度推断
- 复盘事实先行原则 —— 本篇顶部事实冻结区按它执行
- 09_平台工程索引 —— 平台工程区入口;本文归入「账号与访问」