让被测网关保留在 macOS 上
网关运行在 Mac 上,由 OpenSurge 管理 dnsmasq、mihomo、pf 和转发状态;两台 Lima Ubuntu 虚拟机扮演独立下游设备。这样的布局可以直接测试产品实际使用的操作系统组件与网络行为。
客户端通过关闭平台 DHCP 的 socket_vmnet 主机网络接入,由 OpenSurge 的 dnsmasq 提供测试租约。地址分配、网关选择和 DNS 因此都成为场景的一部分。切换配置和测试服务后,同一环境就能承载不同的路由与策略测试。
分开管理路径与测试流量
每台客户端都有两个接口。Lima 自带的控制接口负责安装依赖与检查状态,第二个接口 omg0 承载被测流量。OpenSurge 改变测试网络时,客户端仍然可以通过管理路径接受控制。
受控服务让路由选择可以被观察。不同场景按需加入 HTTP Provider、CONNECT 代理、TCP/UDP 或 HTTP/3 服务、SOCKS5 UDP 出口,以及 Tailnet peer。这些服务提供已知的应答,也提供检查请求实际到达位置的观察点。
受控 CONNECT 代理会把自身的上游 DNS 与 TCP 连接绑定到物理上游接口,避免代理自己的流量重新进入正在测试的 TUN 路径。
从基础联网走到透明代理
基础场景沿着客户端接入网络的过程展开:申请租约,检查默认路由与 DNS,解析域名,再通过 Mac 发出请求。ICMP/NAT、直连 HTTPS 和经 mihomo mixed-port 的显式代理 HTTPS 分别使用对应探针。
TUN 场景保持客户端不配置显式代理,让 HTTPS 请求通过设置的网关发出,并在 mihomo 日志中查找对应客户端流量。请求应答和实际路由相互对应,才能把应用行为与透明代理路径联系起来。
DNS 与直连能力需要分开测试。网关 DNS 有意返回 fake-IP 时,直连 NAT 探针会另行解析真实公网地址,并把 HTTPS 请求固定到该地址,避免一个断言依赖另一种路由模式。
沿着配置进入真实流量
导入配置场景加载已知 profile,再加入受控 HTTP Provider 和 CONNECT 代理。测试在 DIRECT 与代理出口之间切换选择,发送新请求,并检查流量到达哪个服务,把配置合成、策略选择与实际出口连接起来。
策略工作区场景从网关停止态开始:预览合成后的策略,选择节点,再通过 App 共用的候选启动路径接管网络。场景检查预览过程是否保持期望配置与基础恢复记录,以及选中的策略能否延续到运行中的网关。
- 导入配置:让生成的配置交给实际代理内核运行。
- 受控出口:通过客户端请求和代理服务观察策略切换。
- 策略准备态:串起预览、选择、启动、进程交接和清理。
为设备与本机隔离设置独立场景
两台下游客户端可以拥有不同身份和策略。DHCP reservation 将客户端绑定到稳定地址,测试比较跟随网关规则与使用专属策略的设备,再切换出口、重载网关。
Mac 本机路由场景改变本机的规则、全局和直连模式,同时检查下游设备继续遵循自己的策略。设备场景还会分别建立持久连接,在切换选择后刷新其中一台设备的连接,并检查另一台设备的连接仍然保留。
拒绝路径也是设计的一部分。设备专属规则需要阻止对应请求;选择 HTTP-only 出口时,UDP 请求应在该策略边界被拒绝,避免继续落入通用 DIRECT 规则。
按拓扑组织 IPv6 测试
实验性下游 IPv6 分别为独立 LAN、整网 DHCP 接管和同 LAN 选择性接入设置场景。自动接入场景测试 RA、SLAAC 和 RDNSS;选择性接入则使用手工 ULA 地址与 Mac 的链路本地网关,不发布 RA。
这些场景运行 macOS BPF broker 和补丁版 mihomo 用户态数据包路径,同时检查设备身份与策略选择。受控 TCP 和 UDP 服务提供请求应答探针;HTTP/3-only 客户端专门测试 QUIC 与 HTTP/3,避免回退到 TCP 或 HTTP/2,并分别使用 DIRECT 和 SOCKS5 UDP 出口。
停止网关同样属于 IPv6 场景:测试检查路由撤销,以及网关地址、broker 进程、socket 和运行状态的清理。环境具备原生 IPv6 上游时,还可以通过独立的导入出口场景,加入明确提供的 profile。
把 Tailscale 作为一种场景扩展
Tailscale 场景在共享环境上增加第三台持久化 Lima 虚拟机。这个 peer 运行独立 tailscaled,将 TCP/UDP 服务绑定到 tailscale0,并保持在下游 omg0 网络之外。OpenSurge 托管 tsnet、peer 和 Mac 原生 Tailscale App 各自拥有独立身份。
两台下游客户端分别设置为允许与拒绝。测试向精确 peer IPv4 发送 TCP 和 UDP 请求,再通过完整 MagicDNS 名称发送 TCP 请求,同时检查应答、对应的托管出站或 REJECT action,以及 peer 实际收到的请求。
Mac 原生 App 提供发现信息,并在启动前建立可观察的原生 peer 路由。peer 收到的成功请求必须来自同一个、区别于原生 App 的来源身份,未授权请求则不能到达服务,以排除借用现成原生路由产生的假阳性。peer 的互联网底层连接仍经过 Lima NAT 和 Mac 上游;测试会拒绝原生 App 正在使用 Exit Node 的环境。
让环境能够复用,也能完成恢复
Lab 安装器固定依赖版本并校验下载。日常停止保留 Lima 磁盘,后续运行继续复用客户端。网关尚未启动时,provisioning 先恢复客户端控制 DNS,依赖齐全时跳过重复安装。
每个场景都有对应收尾路径:恢复控制 DNS,停止网关与辅助服务,再检查相应运行资源是否清理。lab-down 负责停止虚拟机和隔离的主机实验网络,让恢复成为测试生命周期的一部分。
使用 profile 或 Tailnet 凭据的场景也管理敏感输入:通过受保护文件读取密钥,复用节点 state 减少重复注册,并让脱敏输出支持检查,避免将凭据复制到测试产物。
根据行为变化选择场景
共享环境让贡献者可以把改动映射到具体测试。DHCP 或生命周期改动从基础联网场景开始,路由改动进入对应 TUN 与策略场景,IPv6 和 Tailscale 则使用各自的网络扩展。
仓库中的验证地图把这些行为与命令、断言对应起来。结合 Agent Wiki 和结构化 CLI 诊断,人类与 AI 贡献者都能沿着一致的路径,从理解改动走到实际测试。
FAQ
改变网络前常见的问题
Virtual Lab 中哪些部分是虚拟的?
下游设备是 Lima 虚拟机,测试 LAN 由 socket_vmnet 提供;OpenSurge 和网关依赖的 macOS 网络组件运行在宿主 Mac 上。
为什么需要两台下游客户端?
两台客户端可以拥有不同身份、策略和活动连接,让场景能够检查修改一台设备的路由或授权时,另一台设备仍然保持独立行为。
Tailscale 和整个 Lab 是什么关系?
Tailscale 是其中一种场景。它复用 macOS 网关和下游客户端,增加独立 Tailnet peer,再测试私有目标访问、来源授权和原生路由旁路。
贡献者如何选择要运行的测试?
验证地图按基础联网、TUN、配置、设备策略、本机路由、IPv6 和 Tailscale 等行为组织场景,贡献者根据改动涉及的路径选择对应测试。