先区分:流量入口与代理规则
浏览器可以访问,终端却连接超时,通常先查流量有没有进入客户端,而不是立刻更换节点。系统代理和 TUN 是两种流量入口;规则模式、全局模式则决定流量进入内核之后走哪条出口。两组设置处理的是不同问题。
系统代理把本地代理地址登记到 macOS 网络设置。应用愿意读取并使用这些设置,才会把请求交给代理。TUN 则创建虚拟网络接口,配合路由把符合接管范围的 IP 数据包送入内核。mihomo 是兼容 Clash 配置生态的代理内核,客户端负责提供界面、配置管理和权限服务。
| 比较项 | 系统代理 | TUN 模式 |
|---|---|---|
| 接管入口 | 应用读取代理设置后主动连接本地端口 | 虚拟网卡与路由把 IP 数据包送入内核 |
| 常见适用对象 | 遵守系统设置的浏览器与桌面应用 | 不读取系统代理的程序、部分 UDP 应用 |
| 终端命令 | 通常需要代理参数或环境变量 | 路由覆盖时通常不必逐条设置 |
| 权限要求 | 通常不需要安装 TUN 辅助服务 | 通常需要授权辅助服务来配置接口和路由 |
| DNS 处理 | 取决于应用与代理协议 | 可结合 DNS 劫持与内核 DNS,但仍有覆盖边界 |
系统代理:检查设置与本地端口
在 macOS 中确认代理确实写入
以 macOS 13 及之后的系统设置界面为例,打开「系统设置」→「网络」→「Wi-Fi」→「详细信息」→「代理」。有线连接应查看正在使用的以太网服务。开启客户端的系统代理后,核对网页代理、安全网页代理或 SOCKS 代理中的地址与端口,具体写入哪些项目取决于客户端。
地址常见为 127.0.0.1,表示这台 Mac 自己;端口必须与客户端正在监听的端口相同。本文命令用 7890 演示 HTTP 与 SOCKS 共用的混合端口,不代表每个客户端的默认值。先在客户端端口设置中确认,再运行命令。
# 查看 macOS 当前汇总的代理设置
scutil --proxy
# 检查示例端口是否有 TCP 监听进程
lsof -nP -iTCP:7890 -sTCP:LISTEN
- 在
scutil --proxy中查看HTTPEnable、HTTPSEnable或SOCKSEnable,并核对对应端口。 - 如果
lsof没有输出,先检查端口是否写错、内核是否启动,以及端口是否改成了其他数值。 - 如果监听进程不是当前客户端,先排查端口占用,避免同时运行两个客户端争用同一个地址。
系统代理开启不等于所有应用立即切换。应用可能使用自己的网络栈、已有长连接或独立代理设置。修改后新建请求,必要时重启目标应用,再观察客户端的连接记录;不要只凭菜单栏开关判断成功。
终端命令:用显式代理验证入口
命令行工具是否读取 macOS 系统代理,取决于工具实现。常见的 curl 用法会读取代理环境变量,但不能据此推断它会自动跟随系统代理面板。先用显式参数测试,可以把“代理入口问题”和“站点连接问题”分开。
先指定 HTTP 代理,再测试 SOCKS
# 通过本地 HTTP 代理发起 HTTPS 请求,最多等待 15 秒
curl --proxy http://127.0.0.1:7890 \
--connect-timeout 10 --max-time 15 -I https://example.com
# 使用 SOCKS5,并把目标域名交给代理端解析
curl --proxy socks5h://127.0.0.1:7890 \
--connect-timeout 10 --max-time 15 -I https://example.com
第二条命令只有在该端口支持 SOCKS 时才适用。socks5h 中的 h 表示通过代理解析目标主机名;使用 socks5 时,curl 通常先在本机解析。两种写法的差别会直接影响 DNS 排查结果。
需要连续使用时设置临时变量
# 仅影响当前终端会话及其后续启动的子进程
export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
# 完成测试后清除,避免后续误用
unset http_proxy https_proxy
https_proxy 的值写成 http:// 并不矛盾:它描述本地代理入口的协议,HTTPS 目标通常通过 HTTP CONNECT 隧道连接。应用到目标站点的 TLS 加密并不会因此自动取消。
TUN 模式:授权、路由与规则分流
TUN 是三层虚拟网络接口,处理 IP 数据包。在 macOS 上,客户端通常通过特权辅助服务创建或管理接口并设置路由。开启前先选中有效配置,确认内核能够正常启动,再按客户端提示安装辅助服务并完成系统授权。不要把系统登录密码输入订阅页面或配置文件。
理解最小配置中的关键项
下面是 mihomo 配置片段,用来解释常见字段,不是完整订阅。不同客户端可能从界面生成这些字段,也可能覆盖订阅中的值。修改前备份配置,并检查最终生效配置;不要直接覆盖整份订阅。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
dns:
enable: true
enhanced-mode: fake-ip
enable启用 TUN;它仍依赖足够的系统权限与成功启动的内核。stack选择协议栈实现。示例使用mixed,并不表示它在每台 Mac、每个网络环境中都优于其他选项。auto-route请求自动配置路由;auto-detect-interface用于自动识别出站接口。切换 Wi-Fi、网线或热点后,应重新确认出口。dns-hijack指定劫持目标;any:53针对进入相应处理路径的传统 53 端口 DNS 请求,并非拦截所有加密 DNS。
仅有这段配置还缺少节点、策略组、规则和合适的上游 DNS 等内容。优先使用客户端支持的配置方式;如果内核报字段错误,先核对实际内核类型和版本,再按对应文档调整。
区分 TUN 开关与全局模式
开启 TUN 后,流量进入 mihomo,仍可在规则模式下按域名、IP 或其他条件匹配规则。命中直连规则就直连,命中代理组就使用组内选中的出口。全局模式通常把流量交给全局策略组,但仍受入口覆盖和路由排除影响。需要扩大接管范围时开 TUN;需要改变出口选择时查规则与策略组。
DNS:网页可用不代表解析路径一致
DNS 把域名转换成 IP 地址。系统代理只改变应用如何连接代理,并不统一控制所有应用的域名解析。浏览器可能通过代理发送域名,也可能使用自己的安全 DNS;其他程序可能先查询系统 DNS,再连接得到的 IP。
TUN 可以配合内核 DNS 处理更多解析请求。启用 fake-ip 后,内核会为域名分配用于映射的虚拟地址,再在连接阶段关联真实目标。看到 198.18.0.0/15 范围内的地址不一定是故障,但要以实际配置的 fake-ip 地址段为准。
按三个层次检查解析问题
- 检查系统入口。运行
scutil --dns,查看当前解析器。它显示系统配置,不能证明每个应用都使用这些解析器。 - 检查内核记录。打开客户端的连接与日志页面,用同一个域名重新发起请求,观察是否出现 DNS 请求、规则命中和出口选择。
- 检查应用自带设置。查看浏览器安全 DNS、应用内代理及加密解析设置。DoH 使用 HTTPS 传输,DoT 通常使用 853 端口,不能只靠 53 端口劫持覆盖。
不要只运行一次 dig 就认定整个系统的 DNS 路径。macOS 的分域解析、VPN 解析器和应用缓存都可能造成差异;dig 的查询路径也不完全等同于应用调用系统解析服务。排查时记录目标域名、时间和所用工具,避免混用不同测试结果。
游戏与 UDP:接管成功后还要检查节点
游戏经常同时使用 TCP 和 UDP。传统 HTTP 系统代理通常不能承接游戏自行发出的 UDP 数据包;SOCKS 协议虽然有 UDP 转发机制,但应用也必须主动支持并使用。TUN 能把更多这类流量送入内核,所以更适合排查“不跟随系统代理”的游戏连接。
不过,虚拟网卡不会为远端节点补上 UDP 能力。节点协议、服务端配置、策略组所选出口和本地网络都可能限制 UDP。先在客户端连接列表里确认游戏连接是否出现,再看它命中了 DIRECT 还是代理组,最后检查所选节点是否支持所需流量。
- 登录成功、进入对局失败:分别检查登录阶段的 TCP 请求与对局阶段的 UDP 连接,不要只测登录页面。
- 能连接但延迟高:在相同区服、相同时间段比较游戏内延迟与丢包。节点列表的 HTTP 测速不能等同于游戏延迟。
- 局域网联机或设备发现异常:检查本地网段绕过策略。广播、多播和发现协议不应被当成普通远端单播连接处理。
如果应用依赖特定网络接口、反作弊组件或特殊传输方式,TUN 也不保证兼容。先保留原来的网络设置和恢复方法,每次只改一个变量,才能判断是接管方式、规则还是出口造成问题。
Mac 上的选择与故障恢复顺序
按应用需求选择入口
- 主要使用浏览器和遵守系统代理的应用:先开系统代理,配置更直观,也便于检查本地端口。
- 偶尔使用终端:优先给命令加
--proxy,或设置当前会话变量,保持影响范围清楚。 - 多个程序忽略代理、需要处理 UDP:考虑 TUN,同时检查辅助服务、DNS 和路由。
- 正在连接公司 VPN:先按组织网络要求操作。两个工具都可能修改路由和 DNS,应分别测试,避免直接叠加。
开启 TUN 后断网,先恢复再定位
- 关闭 TUN,保留客户端运行,检查普通网络是否恢复。暂时不要反复导入不同订阅。
- 关闭系统代理,清除测试终端中的代理变量,再确认直连状态。若曾设置
all_proxy或大写变量,也需清除相应项。 - 运行
scutil --proxy检查残留代理;运行route -n get default查看默认路由。TUN 可能使用更具体的分流路由,因此默认路由本身不能代表全部接管结果。 - 使用
netstat -rn -f inet查看 IPv4 路由;涉及 IPv6 时再运行netstat -rn -f inet6。出现utun接口不一定属于当前客户端,其他 VPN 也可能使用它。 - 确认恢复后,仅开启一种入口重新测试。若只有 TUN 失败,再核对服务权限、路由冲突与 DNS 日志。
系统代理与 TUN 没有固定的优劣排序。前者适合能主动使用代理的应用,后者扩大接管范围但增加路由、权限和 DNS 的排查维度。先用最少的设置满足当前任务,再逐步扩展覆盖范围,比同时开启所有选项更容易维护。