TUN 模式与系统代理的接管范围
系统代理是提供给应用的一组代理地址设置。浏览器可以读取这些设置,把请求发送到本机 HTTP 代理端口;自行建立连接的游戏、命令行工具或部分桌面程序,则可能完全不读取它。系统代理已开启,不代表所有程序的连接都会经过 Clash。
TUN 是工作在网络层的虚拟接口。客户端创建接口,再调整系统路由,让符合条件的 IP 数据包进入内核。内核处理 TCP、UDP 等连接,按照规则选择直连、代理或拒绝。应用通常不需要单独填写代理地址,但仍可能受到路由排除、应用排除和平台限制的影响。
| 项目 | 系统代理 | TUN 模式 |
|---|---|---|
| 接入方式 | 应用向本地代理端口发送请求 | 路由把 IP 数据包送入虚拟接口 |
| 应用配合 | 需要读取系统代理或手动配置 | 一般不需要应用设置代理 |
| UDP 流量 | 系统 HTTP 代理设置通常不覆盖 | 可接管,出口节点还需支持 UDP |
| 主要权限 | 修改当前用户代理设置 | 创建接口、调整路由或获得 VPN 授权 |
| 典型用途 | 浏览器、支持代理的桌面应用 | 不读取代理设置的程序与 UDP 应用 |
本文的 YAML 示例面向 Clash Meta 延续项目 mihomo。不同 Clash 分支的字段与平台支持并不完全相同;先在客户端的“关于”或内核信息中确认内核名称,再对照该内核文档。界面上出现 TUN 开关,也不意味着旧内核支持下文全部字段。
虚拟网卡、路由表与 DNS 的协作
一次连接的处理顺序
- 应用请求解析域名,或直接连接某个 IP 地址。
- 操作系统根据路由表选择出口。启用自动路由后,相关流量被送入 TUN 接口。
- 内核取得目标地址,结合 DNS 映射、规则和可选的嗅探信息进行匹配。
- 命中代理的连接通过所选节点发出;直连连接从实际网络接口发出。
内核发往代理服务器的连接必须从真实出口离开,不能再次进入自身。auto-detect-interface 用于自动识别出站接口,减少形成路由环路的风险。切换 Wi-Fi、接入网线或启停其他 VPN 后,原来的接口选择可能变化,应重新检查日志与路由。
DNS 劫持不是所有加密 DNS 的拦截器
dns-hijack 可以把匹配的 DNS 流量交给内核 DNS 模块。例如 UDP 53 和 TCP 53。浏览器使用 HTTPS 连接到外部解析服务时,请求通常走 443 端口,不属于普通的 53 端口 DNS 查询;不能仅靠一条 any:53 就断言所有域名查询已被接管。
使用 fake-ip 时,内核会返回映射地址,再根据后续连接恢复域名。示例中的 198.18.0.1/16 来自专用测试地址空间,用于内部映射,并不是代理服务器地址。依赖真实解析结果的局域网设备或应用,可能需要按域名设置 fake-ip-filter,不要直接把大量域名全部排除。
mihomo TUN 配置与 stack 选择
下面是合并到现有配置的示例,不包含节点、代理组和分流规则,不能替代完整订阅。先备份配置,再通过客户端支持的覆写或合并功能添加,避免订阅更新后本地修改被覆盖。已有同名字段时应合并其内容,不要在 YAML 顶层重复写两份 dns 或 tun。
mixed-port: 7890
mode: rule
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
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
mixed-port: 7890是本例的 HTTP/SOCKS 混合代理入口,不是 TUN 接收数据包所用的端口。换成其他未占用端口,不会直接改变虚拟接口路由。listen: 127.0.0.1:1053是内核 DNS 的本地监听地址;它不等于要求把系统 DNS 填成“127.0.0.1:1053”。多数系统 DNS 设置只接受服务器 IP,不接受这种带端口写法。auto-route负责自动添加相关路由;auto-detect-interface负责识别实际出站接口。它们不是节点测速或自动选节点功能。- 示例解析服务器用于说明字段结构。实际部署应按网络可达性、解析策略和隐私要求选择上游,不能把示例地址当作所有网络的固定答案。
system、gvisor 与 mixed 的区别
| stack 值 | 处理方式 | 选择依据 |
|---|---|---|
system | 使用系统网络栈相关实现 | 关注平台适配和实际连接表现 |
gvisor | 使用用户态网络栈 | 用于对比系统栈下的兼容性问题 |
mixed | TCP 使用 system,UDP 使用 gvisor | 在两种处理方式之间组合使用 |
不要把某种 stack 等同于固定的“最快模式”。吞吐、CPU 占用和兼容性受系统、内核构建、节点协议与应用负载共同影响。排查时固定同一个节点和测试目标,每次只更改 stack 一项,重新建立连接后比较。旧连接未断开时,测试结果可能仍来自原来的处理路径。
Windows:服务权限与虚拟网卡检查
Windows 10、Windows 11 上,创建虚拟接口和修改路由需要相应权限。桌面客户端常通过管理员启动或后台服务运行内核;“开机启动”和“服务模式”不是同一设置。服务安装成功后,还要确认服务确实运行。
- 先关闭 TUN,导入配置并选择一个可用节点。使用系统代理打开测试网页,确认订阅和节点本身可以工作。
- 在客户端设置中查找“服务模式”,按提示安装并启动服务,或按客户端说明以管理员身份启动。Windows 弹出用户账户控制窗口时,核对程序路径。
- 暂时关闭系统代理,再开启“虚拟网卡模式”或“TUN”。这样验证时不容易把系统代理的效果误认为 TUN 已生效。
- 打开「设置」→「网络和 Internet」→「高级网络设置」,查看网络适配器变化。接口名称由客户端与内核配置决定,不必强求名称为 Clash。
- 打开客户端连接列表,运行一个没有单独配置代理的程序,确认出现对应连接及规则命中。
需要进一步检查时,在 PowerShell 中执行以下只读命令。重点观察新增的接口、路由的接口索引和 DNS 服务器,而不是只看任务栏中的连接图标。
Get-NetAdapter
Get-NetRoute -AddressFamily IPv4
Get-DnsClientServerAddress
Get-NetTCPConnection -State Listen -LocalPort 7890
最后一条只检查本例代理端口是否有监听,不能证明 TUN 正常。如果日志出现权限不足,先处理服务权限;如果端口被占用,再核对监听进程。不要为解决接口创建失败而直接关闭整个系统防火墙。
macOS:辅助服务与 utun 路由验证
macOS 客户端通常借助特权辅助服务创建或管理 TUN,也有客户端采用系统网络扩展。授权方式取决于客户端实现,不能把某一款软件的菜单照搬到所有应用。下载与安装时还应区分 Apple 芯片和 Intel 架构。
- 先用系统代理验证节点,再按客户端提示安装辅助服务或批准网络扩展。输入管理员密码前,核对授权请求来自当前安装的客户端。
- 启用 TUN。如果系统提示需要允许后台组件,按提示进入「系统设置」→「通用」→「登录项与扩展」检查对应项目;不同 macOS 版本的名称可能略有变化。
- 暂时关闭系统代理后重新打开测试应用,在客户端中检查连接是否仍然进入内核。
- 从睡眠恢复或切换网络后重新测试。若只有恢复后失效,记录当时的出站接口与内核日志,再重启 TUN 验证。
ifconfig
netstat -rn -f inet
route -n get 1.1.1.1
scutil --dns
utun 接口可能同时被其他系统服务或 VPN 使用。看到 utun0 并不能证明它属于当前客户端,编号也不固定。应比较 TUN 开启前后的接口和路由变化,并结合客户端日志判断。路由查询只说明目标 IP 的选路情况,不能单独证明所有域名解析或 IPv6 流量都已进入内核。
Android:VPN 授权、应用范围与后台限制
Android 客户端通常通过系统 VpnService 提供虚拟接口,不要求普通用户获取 root 权限。第一次连接会显示系统 VPN 授权对话框。Android 界面的“VPN 模式”与桌面端 TUN 目标相近,但接口和路由往往由应用负责,因此不能机械复制桌面端的 auto-route 配置。
- 导入订阅并选定代理组,启动连接,确认系统 VPN 授权窗口中的应用名称后允许。
- 在客户端检查应用分流设置。使用“仅代理所选应用”时,未选中的应用不会因为 VPN 图标出现就自动进入代理。
- 在 Android 13 的常见入口「设置」→「网络和互联网」→「VPN」查看当前 VPN。厂商系统可能将入口放在“连接与共享”等分类,可在设置内搜索“VPN”。
- 进入客户端的系统应用信息,在「电池」或「应用电池用量」中按需允许后台运行。只有锁屏后断线时,优先排查省电和后台限制。
- 若已启用“始终开启 VPN”或“屏蔽未使用 VPN 的连接”,先确认客户端可稳定重连。后者在 VPN 中断时可能直接阻止联网。
同一用户或工作资料中,通常只能有一个基于 VpnService 的应用保持活动。另一个 VPN、使用本地 VPN 的过滤工具或抓包工具启动时,可能替换当前连接。此时应确认系统当前授权的 VPN 应用,而不是反复重新导入订阅。
开启后无网络:按连接层次排查
先区分节点故障与接管故障
关闭 TUN,恢复系统代理,使用同一节点访问同一目标。如果仍失败,先处理节点、订阅或代理组;如果系统代理正常而 TUN 失败,再检查权限、路由、DNS 和其他 VPN。这个对照过程比同时改端口、stack、DNS 更容易缩小范围。
- 浏览器正常,游戏不通:检查游戏连接是否出现在客户端中,节点是否支持 UDP,以及规则是否把目标送到预期代理组。HTTP 网页可用不能证明 UDP 出口可用。
- IP 可达,域名失败:查看 DNS 日志、系统解析设置和浏览器安全 DNS。
nslookup example.com可辅助观察查询结果,但与浏览器使用加密 DNS 时的路径可能不同。 - 局域网打印机或 NAS 失联:核对私网地址路由、域名解析和规则。私网连接需要正确直连或排除;只添加一条直连规则不一定能修复已经错误的系统路由。
- 部分网页长时间等待:检查 IPv4 与 IPv6 是否采用不同出口,再检查 MTU。不要直接套用固定 MTU 数值,应先确认是否存在隧道叠加或路径分片问题。
- 重启客户端后才恢复:检查旧服务、重复内核进程和其他 VPN 是否同时存在,记录报错时间,避免仅凭现象认定为 stack 问题。
验证与回退顺序
一次有效验证应同时看到三类证据:接口或路由发生预期变化;未配置代理的应用连接进入内核;规则命中与最终出口符合预期。单独看到 VPN 图标、代理端口监听或节点延迟数值,都不足以完成验证。
需要回退时,先通过客户端关闭 TUN,等待接口和路由清理,再按原先习惯恢复系统代理。Android 若启用了阻止非 VPN 连接,还要检查该开关。仍无法联网时,再查看系统中是否残留手动 DNS、代理地址或其他 VPN;不要直接删除无法确认归属的网络适配器。
常见问题
TUN 开启后还需要打开系统代理吗?
如果目标流量已由 TUN 接管,通常不需要再依赖系统代理。两者可以同时存在,但排查时建议先只保留一种入口,避免浏览器经代理端口成功后掩盖 TUN 路由失效。
TUN 能让所有节点支持 UDP 吗?
不能。TUN 可以接收应用的 UDP 数据包,后续还取决于节点协议、客户端节点配置、服务端能力和网络策略。应在连接列表里确认 UDP 连接,再检查所选节点的支持情况。
启用 TUN 是否等于所有 IPv6 流量都被代理?
不等于。需要分别核对内核 IPv6 配置、系统路由、DNS 返回结果和节点能力。如果只验证 IPv4 网站,不能据此判断 IPv6 的真实路径。即使 IPv6 已接管,命中直连规则时仍然会直连。
订阅更新后 TUN 设置为什么恢复了?
直接编辑订阅生成的配置,可能在下次更新时被覆盖。应使用客户端提供的持久覆写、合并或独立运行设置,并在更新后查看最终生效配置。界面开关与 YAML 字段冲突时,以客户端实际提交给内核的配置为准。