上篇写完,我本来打算把 H3C 中继的问题放一放。TTL、TCP 重置、上游公网映射都查过了,原厂设备内部到底怎么处理这些流量,还是看不清。我想先把证据留着,等后面的模型能力上来了,再接着分析。
结果又折腾了几天,逃(
不过,这几天也没白折腾。对网络、协议,还有之前遇到的那些问题,我又多了一些理解。
N100 上的主 OpenWrt 加了广告过滤,代理也从 OpenClash 换成了 sing-box。H3C 刷了 OpenWrt,改作 AP,ETH2 还接出了一个独立网段。VPS 那边增加了 XHTTP 和 Hysteria2,电脑上的客户端从 Sparkle 换到了 v2rayN,接着又碰上订阅、DNS 和两个代理核心共存的问题。
这些事分别记在 Proxmox 和 VPS 两个项目里,乍看像是各忙各的。后来沿着一条连接的实际路径往下查,我才发现,项目可以分开记,流量却会一路经过它们。路由器怎么转发,电脑上的两个代理核心怎么接管流量,服务器用哪个入站,甚至下载下一份配置时用哪个 DNS,都会互相影响。
路由模式能上网,按设备分流却不好办
上篇里,H3C 改成路由模式以后,原来失败的连接恢复了,但用起来仍然不够稳定。等我开始往主 OpenWrt 上加功能,又遇到了一个麻烦。
我想用 AdGuard Home 过滤广告,也想单独指定哪些设备走代理。手机、电脑、Debian 和 Home Assistant,用途不同,最好能各设各的策略。
可当时手机和电脑都在 H3C 下游,地址属于 192.168.124.0/24;H3C 再通过 WAN 口接入主 OpenWrt 的 192.168.50.0/24。流量经过 H3C 的 NAT 后,主 OpenWrt 看到的源地址已经变成了 H3C,二层邻居里也只能看到 H3C 的上联身份。
这样一来,手机和电脑发出的请求,到了主网关眼里,都成了 H3C 发来的流量。主网关手里没有 H3C 的那份地址转换记录,单靠补几条源 IP 或 MAC 规则,也没法把下游的每台设备重新认出来。
后来我刷完H3C路由器,设成中继模式,终端直接回到主网段,这个问题才解决。
换成小米中继后,Codex 几乎不重连
换成小米中继后,日常使用 GPT 和 Codex,终于不反复显示重新连接了。我对照了调整前后的测试结果:节点和端口没变,脚本里的目标、请求方法、HTTP/1.1、超时、测试次数和间隔也保持一致。
| 测试路径 | 调整前失败/次数 | 调整后失败/次数 |
|---|---|---|
| 本机经 TUN → ChatGPT,HEAD 短请求 | 11/18 | 0/18 |
| 本机经显式 HTTP 代理 → ChatGPT,HEAD 短请求 | 11/18 | 1/18 |
| 本机经 TUN → ChatGPT,五分钟 GET 采样 | 5/30 | 0/30 |
| 本机经显式 HTTP 代理 → ChatGPT,五分钟 GET 采样 | 3/30 | 2/30 |
| VPS → 同一 ChatGPT 接口,GET | 0/30 | 0/30 |
| 本机绑定物理地址 → VPS 443,TCP 建连 | 0/30 | 0/30 |
| 本机 → VPS,八次独立 SSH 小文件传输 | 1/8 | 3/8 |
TUN 这条路径改善很明显,两组测试都没有再失败;显式 HTTP 代理仍有少量失败。SSH 小文件传输反而从八次完成七次,变成八次完成五次,失败出在连接或 banner 阶段。另一个持续六十秒的小流量 SSH 测试,两轮都成功了。国内多数目标本来就能稳定回应,调整后也基本如此。
原来的路由模式下,电脑发出的数据要先经过下挂路由器的三层转发和 NAT,再交给主 OpenWrt。换成桥接式 AP/中继以后,下挂设备主要负责无线接入和桥接,终端直接使用主网段,少过了一层地址转换。主网关和上游仍可能做 NAT,只是下挂设备不再做这一次转换。
少了下挂路由器这一层,可能避开了它原先的连接跟踪、防火墙策略,或者某条转发路径上的问题。主网关又能直接看到终端,也可能让源地址规则、DNS 下发和代理策略的匹配结果发生变化。这次连设备和工作模式都换了,还不能只凭这些结果,把改善归到其中某一项上。
给 H3C 刷 OpenWrt,重启报错也得分情况看
H3C 这边,我还是动手刷了机。
第一次恢复维护配置后,后台能打开,维护端口却没开始监听。模型先怀疑设备没有真正重启,我就断电重启了一次,还是没用。重新导出设备当前的配置,才发现维护脚本和 include 根本没保存进去。
备份闪存时,还有一组数字很容易看错:十个逻辑 MTD 文件加起来有 248MiB,但整片 NAND 只有 128MiB。因为备份里既有整片内容,也有其中的分区,同一部分数据被存了不止一遍,不能拿文件总大小当成设备的闪存容量。
这些文件都做了大小和摘要校验,至少能确认传输、落盘的内容一致。不过,逻辑 MTD 备份不包含 NAND OOB;设备还在运行,各个分区的备份也不是同一时刻取下来的原子快照。我没有实际演练恢复,因此目前只能说备份校验通过,还不能保证什么情况下都能恢复原厂。
写入引导程序后,回读的摘要已经匹配。可发送重启命令时,维护连接断开,脚本报了错。只盯着最后那个退出状态,很容易以为刷写失败了。随后设备实际发出了 TFTP 请求,恢复系统的 SSH 也出现了,才确认它已经走到了下一步。
能连上 SSH,也还没装完。当时启动的是 initramfs 恢复环境,后面还要执行 sysupgrade,再检查只读的 squashfs 和可写的 UBIFS overlay,确认持久化系统已经装好。
同一个 Wi-Fi,电脑能上网,手机却不行
刷完的 H3C 接回主网后,电脑能上网,手机却不行。一开始看着又像是手机或者新刷的 AP 出了问题。
我逐项补充手机的情况:拿到的地址是 192.168.50.101,网关是 .50.1,主 OpenWrt 和 H3C 的管理页都能打开。手机没开 VPN,没有网络描述文件,Wi-Fi 的 HTTP 代理也关着。
短时间抓包只看到了 ARP 和 ping,没有预期的网页请求。AI 一度建议继续查手机 DNS 和描述文件。这些可以查,但没抓到请求,还不能据此认定是手机设置错了。
最后查到的是 DHCP 漏发了 DNS。
AdGuard 接管 53 端口后,dnsmasq 的 DNS 服务挪到了 54,DHCP 仍由 dnsmasq 负责。可当时的配置没有显式向 LAN 客户端下发 DNS option 6。用 DHCPINFORM 获取实际回复,ACK 里有掩码、有网关,就是没有 DNS 地址。
那电脑为什么能用?它的 WLAN 其实也没正常拿到 DHCP 下发的 DNS,只是电脑上还跑着 sing-box TUN,可以通过自己的 172.18.0.2 DNS 路径继续解析。手机依赖 Wi-Fi 自动获取的网络参数,没有这条额外的路,问题才显出来。
手机:Wi-Fi → DHCP 获得地址和网关 → 未获得 DNS → 域名访问失败
电脑:Wi-Fi → 同样缺 DHCP DNS → 本机 TUN 提供另一条 DNS 路径 → 可访问
我之前拿“同一个 Wi-Fi、同一个网关”来比较两台设备,漏算了电脑上的 TUN。它让电脑正常上网,也把两台设备共同遇到的 DNS 配置问题藏住了。
修复是在 DHCP 里明确下发 .50.1 作为 DNS。重载 dnsmasq 后,我又检查了一次 ACK,确认 option 6 已经出现,手机的 DHCP DNS 问题也完成了验收。
从 Sparkle 换到 v2rayN
这几天我对 fake-IP 和 DNS 理解又深了一些,也重新看了之前使用 Sparkle 时碰到的各种问题,随后把客户端换成了 v2rayN。
用熟以后,我觉得 v2rayN 操作起来更顺手。对流量经过哪里、DNS 由谁处理理解得多了,之前在 Sparkle 里碰到的问题,也能从整条连接的路径去查,少一些对着单个设置来回试。
把规则整理进订阅
换客户端时,我不太想再手工补一遍内网、DNS 和校时的例外规则。于是整理了一组规则,希望 VPS 下发订阅时就能带上:本地网络、自用节点入口、国内 DNS、Windows 连通性检测,还有 Apple 和 Windows 的校时域名,后面再接国内分流和代理兜底。
做到这里,就得分清每份配置由谁执行。服务器上的 Xray 路由,处理的是已经到达服务器的流量;Clash 订阅里的规则,则由客户端加载,在本地生效。普通节点链接甚至不包含完整的分流规则。Xray JSON 和 sing-box 的配置结构、出站名称也各有各的写法。
比如 Clash 里的 DIRECT,不能原样塞进一份 Xray JSON 就指望它生效,那里必须引用这份 JSON 中实际存在的出站 tag。服务器上禁止访问私网的规则,也代替不了客户端的内网直连。如果客户端已经把访问家庭地址的请求送到了 VPS,VPS 本来就找不到我家那台设备。这部分模型也明确讲错过一个知识点,配置时还得自己分清客户端和服务端各自负责什么。
fake-IP 过滤和 DIRECT 也容易混在一起。前者决定 DNS 返回真实地址还是映射地址,后者决定连接交给哪个出站。域名拿到了真实 IP,连接仍可能走代理;设成 DIRECT,公共 DNS 也未必知道我家的内网名称。
我把 DNS 一起放进订阅:国内用阿里等普通 DNS,国外用 Google 等普通 DNS,不用 DoH;节点域名单独指定解析器。同时,不要统一拦截 UDP 443,也不要把我家的地址、网卡名写进通用订阅。节点域名需要单独考虑,是因为代理还没建立时,就得先解析出节点地址。如果这一步又依赖代理本身,第一次连接就卡住了。独立解析器可以拆开这层依赖,具体选哪些 DNS 地址,仍要放到实际网络里验证。
我希望订阅能省掉那些重复操作,但有些配置还是得留在本机处理。比如,固定绑定 WLAN 适合这次实验,换到别人的有线网卡就不合适了;我家的 .50.1 DNS,到了其他网络也没有意义。
事上炼
这一周又搭好了不少东西。好多事想起来简单,有AI动手也不难,真要做好,才发现还有一堆细节要处理。
H3C 的基本 AP 功能和手机 DHCP DNS 问题都已验收,电脑也完整迁移到了 v2rayN。给 Shadowrocket 用的订阅已经生成,并做了解码核对。修 bug、改错的过程中,我对 fake-IP 的理解具体了不少,分流协议 也比之前懂得更多。后面有时间,还想搭一套新的 L3 级别网络平台。
以后这些事我还是会让 AI 来做。有它帮忙,我能把想法变成实际配置,再跑实验看结果,不必每条命令都亲自查一遍。我更多要做的是把目标说清楚,把现场情况告诉它;碰到对不上的结果就提出来,弄明白手里的证据能不能支持下一步操作。