先确认实现:TUN 不一定需要系统扩展

macOS 上开启 Clash TUN 的关键,是让内核获得创建虚拟网络接口和调整路由的权限。使用 mihomo 的客户端,常见做法是安装特权辅助服务,再由内核操作系统提供的 utun 接口;采用 Apple Network Extension 的应用,则可能需要添加 VPN 配置,或批准网络扩展。两条路径不能混为一谈,也不需要全部做一遍。

本文以 macOS 13 及以上的系统设置结构为参照,分别说明辅助服务与网络扩展路径。具体按钮名称取决于客户端版本;操作前先在「关于」或「内核」页面记录客户端版本、mihomo 版本和 macOS 版本。Apple 芯片 Mac 优先选择 arm64 构建,Intel Mac 选择 x86_64;处理器架构本身不会免除网络权限要求。

虚拟网卡接管的是 IP 流量,不是自动代理所有连接

TUN 是三层虚拟网络接口。应用生成的 IP 数据包经系统路由进入虚拟接口后,由代理内核读取,再根据规则选择代理节点、直接连接或拒绝连接。它能覆盖许多不读取系统 HTTP 代理设置的程序,但覆盖范围仍受路由、排除列表、IPv6 设置和其他 VPN 影响。

因此,“开启 TUN”与“全部走代理”是两个独立设置。TUN 配合规则模式时,命中 DIRECT 的连接仍然直连;切到全局模式后,也不能假定所有被系统排除的流量都会经过内核。UDP 是否可用,还取决于所选节点、协议与服务端支持。

系统代理与 TUN:按应用需求选择

项目 系统代理 TUN 模式
流量入口 应用读取系统代理,再连接本地代理端口 系统路由将匹配的 IP 数据包送入虚拟接口
常见适用场景 浏览器、遵循系统代理的桌面应用 部分命令行工具、游戏及不读取代理设置的应用
UDP 处理 普通 HTTP 代理不能通用承载 UDP 可以接收 UDP,出口仍需支持 UDP 转发
权限要求 修改系统代理设置可能需要授权 通常需要辅助服务或网络扩展授权
故障影响范围 主要影响使用代理的应用 路由或 DNS 出错时可能影响整机联网

如果只是 Safari 正常访问网页,先使用系统代理即可。若浏览器可用、终端工具却直接连接,先检查工具自身的代理参数,再决定是否开启 TUN。TUN 扩大了流量覆盖范围,也增加了路由和 DNS 的排查项目,并不是延迟优化开关。

先用系统代理验证节点

  1. 导入订阅并完成更新,确认配置能够通过客户端的语法检查。
  2. 选择规则模式,在代理组中指定一个可用节点。
  3. 开启系统代理,用浏览器访问实际需要使用的服务,并观察连接日志。
  4. 确认节点工作正常后,再关闭系统代理并单独测试 TUN,避免混淆两条流量入口。

系统代理与 TUN 可以在部分客户端中同时使用,但首次排查建议只保留一个入口。若节点本身握手失败,切换到 TUN 不会修复订阅过期、节点密码错误或服务端不可达。

启用前:备份配置并记录网络状态

先把客户端移入「应用程序」,再从该位置启动。直接从磁盘映像运行,或安装服务后移动应用,可能造成辅助服务指向的程序路径与当前安装位置不一致。备份当前配置、覆写文件和代理组选择;订阅链接包含访问凭据,不要粘贴到公开工单。

  • 暂停其他隧道:临时断开其他 VPN、TUN 代理及可能接管路由的网络工具。企业设备先确认管理要求,不要移除公司下发的网络配置。
  • 记录 DNS:打开「系统设置」→「网络」→ 当前网络服务 →「详细信息」→「DNS」,记录手动填写的服务器地址。
  • 确认本地端口:查看客户端实际的 HTTP、SOCKS 或混合端口。下文用 7890 举例,它不是所有客户端的固定值。
  • 保留离线退路:提前打开客户端设置页,确认 TUN 开关与辅助服务管理入口,避免断网后才查恢复方法。

在「应用程序」→「实用工具」→「终端」执行以下只读命令,可记录切换前的状态。输出含网络地址与接口信息,分享日志前应先脱敏。

sw_vers
uname -m
scutil --proxy
scutil --dns
route -n get 1.1.1.1
ifconfig -l

uname -m 在原生 Apple 芯片终端环境通常返回 arm64;终端若通过 Rosetta 运行,可能显示 x86_64,因此设备型号仍应在苹果菜单 →「关于本机」核对。route -n get 查看指定目标的路由选择,比只查看默认路由更适合后续验证 TUN。

路径一:安装辅助服务并开启 mihomo TUN

如果设置页面出现「服务模式」「辅助服务」或「特权服务」,通常走这条路径。以下是操作顺序,不代表所有客户端都使用同一套菜单名称;应以当前应用界面的文字与项目说明为准。

  1. 进入客户端「设置」,找到服务管理区域,点击「安装」或「安装辅助服务」。仅在主动执行此操作后确认系统认证提示。
  2. 使用管理员账户授权。系统可能要求输入密码或使用触控 ID;账户没有管理员权限时,应联系设备管理员。
  3. 等待界面显示服务运行,再按客户端提示重启内核。不要仅凭安装按钮消失判断服务已正常启动。
  4. 进入网络或 TUN 设置,开启 TUN 模式,首次测试保留客户端推荐的协议栈和路由选项。
  5. 查看启动日志,确认未出现权限不足、接口创建失败或路由添加失败,然后检查真实连接是否进入日志。

特权辅助服务通常通过系统服务管理机制运行,不等于第三方内核扩展。若此时没有出现「允许系统扩展」按钮,并不表示漏了授权步骤。也不要为了绕过权限问题,长期使用 sudo 启动整个图形客户端。

辅助服务无法启动时的检查顺序

  • 确认当前启动的是「应用程序」中的同一份客户端,而不是下载目录或磁盘映像里的副本。
  • 若应用升级后出现服务不匹配,优先使用客户端自带的卸载服务、重新安装服务功能。
  • 在 macOS 13、14 中,可检查「系统设置」→「通用」→「登录项」里的后台项目;在 macOS 15 中,对应入口为「登录项与扩展」。只有实际注册了后台项目的应用才会显示相关条目。
  • 记录首次失败的日志时间和错误信息,不要连续安装多个客户端的辅助服务来试错。

服务的标识符、安装路径与管理命令由客户端决定。不要照抄其他项目的 launchctl 删除命令,也不要批量删除 /Library/LaunchDaemons/ 中的文件。

路径二:批准 VPN 配置与网络扩展

只有客户端明确采用 Network Extension,并实际弹出相应请求时,才走这条路径。Apple 的 Network Extension 框架可以采用不同的部署形式;VPN 配置许可、应用扩展与系统扩展批准是不同环节,不能把所有提示都称为“驱动授权”。

  1. 在客户端启用其隧道功能。若 macOS 提示应用要添加 VPN 配置,核对应用名称后选择允许。
  2. 如果出现系统扩展被阻止的提示,按提示打开「系统设置」。macOS 13、14 常见批准入口在「隐私与安全性」页面下方,且只有存在待批准请求时才会显示。
  3. 在 macOS 15 中,检查「系统设置」→「通用」→「登录项与扩展」→「网络扩展」;列表内容取决于应用采用的扩展类型和安装状态。
  4. 仅当系统或客户端要求时重启。随后回到应用连接隧道,并在「系统设置」→「VPN」或「网络」相关页面核对连接状态。

不要把与当前客户端无关的 VPN 配置一并删除。个人 VPN、公司 VPN 和内容过滤器可能分别属于不同网络组件;删除之前应记录名称和用途,并优先在所属应用中断开或卸载。

mihomo 配置:TUN、DNS 与规则分别检查

很多图形客户端会在启动前合并订阅、覆写和界面设置。直接编辑订阅缓存文件,下一次更新后可能被覆盖。优先使用客户端的 TUN 设置或持久化覆写功能,并检查最终运行配置;原版 Clash、旧版 Premium 与 mihomo 的配置能力并不完全一致。

下面是 mihomo 的局部配置示例,不是一份可直接导入的完整订阅。它没有节点、代理组和规则,应合并进现有配置,避免产生重复的顶层 tun 或 dns 键。客户端若已生成这些字段,以它的配置机制为准。

tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 1.1.1.1
  • auto-route:让内核自动设置到 TUN 的路由。它是否成功,仍需从日志和实际路由判断。
  • auto-detect-interface:尝试识别出站接口。Wi-Fi、有线网络与其他 VPN 同时存在时,应重点检查是否选错出口。
  • dns-hijack:把进入 TUN、符合条件的传统 DNS 请求交给内核 DNS。示例覆盖 UDP 与 TCP 的 53 端口,不会把任意加密 DNS 自动解密。
  • fake-ip-range:为 fake-ip 映射分配地址空间,不是代理服务器地址。若与现有网络用途冲突,应结合网络环境调整。

示例中的 DNS 上游是明文解析器,仅用于解释配置结构,不是所有网络环境下的推荐答案。企业内网域名可能只能由公司 DNS 解析;需要按域名规划 nameserver-policy 等设置,不能简单用公共 DNS 替换全部解析路径。

两个容易遗漏的边界

IPv6 要单独验证。这段示例不构成完整的 IPv6 接管方案。网络同时具备 IPv4 与 IPv6 时,应检查内核的 IPv6 设置、TUN 路由及实际连接记录,不能仅凭 IPv4 测试通过就认定所有连接都按预期转发。

DNS 正常不等于规则正确。规则仍按顺序匹配,通常在首次命中后确定策略。公司域名应直连还是走特定出口,需要在规则中明确表达;TUN 本身不会修正规则顺序,也不会自动补齐订阅缺失的规则集。

验证是否生效:接口、路由、连接日志一起看

看到 TUN 开关亮起只说明界面状态发生变化,看到 utun 也不足以确认当前客户端接管成功。macOS 自身服务和其他 VPN 都可能创建 utun 接口,编号也会变化,不能把 utun0 或 utun3 写成固定答案。

ifconfig -l
route -n get 1.1.1.1
scutil --dns
scutil --proxy
lsof -nP -iTCP:7890 -sTCP:LISTEN

对比启用前后的接口列表,并查看具体目标的路由是否符合客户端设计。有些实现使用多条更具体的路由,而不是替换唯一默认路由。lsof 这条命令仅检查示例本地端口是否有进程监听,不能用来证明 TUN 已生效。

做一次排除显式代理的请求

curl --noproxy '*' --connect-timeout 10 --max-time 20 -I https://example.com

该命令不显式使用 HTTP 或 SOCKS 代理,适合配合 TUN 测试;它使用 10 秒连接超时、20 秒总超时,便于失败后及时返回。随后在客户端连接页面查找 example.com,检查命中的规则、代理组与实际节点。收到 HTTP 响应仅说明请求完成,不能单独证明它走了代理。

  • 先测试一个应当直连的目标,确认日志显示预期的直连策略。
  • 再测试一个应当代理的目标,确认命中正确代理组,而不是规则末尾的意外兜底。
  • 若需要 UDP,使用实际需要的 UDP 应用测试;TCP 请求成功不能证明 UDP 转发正常。
  • 切换 Wi-Fi 或从睡眠恢复后再测一次,检查自动检测接口是否跟上网络变化。

常见故障与恢复顺序

开启后整机断网

先关闭 TUN,确认基础网络恢复,再看日志中最早出现的错误。如果关闭后恢复,优先检查 DNS 请求、路由设置与出站接口;如果仍不恢复,检查系统代理是否还指向已经退出的本地端口,以及另一套 VPN 是否仍连接。

系统代理可用,TUN 提示权限不足

优先处理辅助服务状态,不要先换节点。检查服务是否已安装、当前应用路径是否变化、升级后是否需要更新服务。若错误明确指向创建接口或添加路由失败,应保留该条日志,再根据所用客户端的服务管理方式修复。

网页可用,但游戏或语音失败

检查该连接是否确实进入 TUN、节点是否支持 UDP,以及规则是否选中了正确出口。若仅特定网络失败,再考虑路径 MTU 或运营商网络限制;不要直接照抄一个更小的 MTU 数值,先记录失败场景并逐项测试。

睡眠唤醒后无法解析域名

先重新连接 TUN,并检查实际出站接口与 DNS 状态。若需要清理系统 DNS 缓存,可在确认路由和内核 DNS 已恢复后执行下列命令;它们不会修复错误的 DNS 上游或规则。

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

停止使用时怎样回退

  1. 在客户端关闭 TUN,等待连接断开后再退出应用,不要首先强制结束内核。
  2. 如果曾开启系统代理,也在客户端关闭,并用 scutil --proxy 检查残留状态。
  3. 恢复之前记录的手动 DNS 设置;原先使用自动 DNS 的网络不要额外保留临时公共 DNS。
  4. 不再使用该客户端时,通过应用提供的入口卸载辅助服务;Network Extension 路径则按所属应用的卸载说明移除相关配置。
  5. 重新测试直连网络,必要时断开并重连当前网络服务。

需要继续排查时,可查看排查手册;首次导入订阅与选择代理组的操作见快速上手。提交问题时附上系统版本、客户端与内核版本、启用路径和脱敏后的首条错误,比单独提供一张开关截图更有帮助。