先区分流量接管与规则分流

系统代理和 TUN 解决的是同一个前置问题:应用的连接怎样进入 Clash 内核。连接进入内核之后,才由 mode、rules 和策略组决定直连、代理或拒绝。因此,“启用 TUN”不等于“全部连接走代理”,“开启系统代理”也不等于“整台设备已经被接管”。

本文的字段示例以 Clash Meta 后续维护的 mihomo 内核为准。不同图形客户端会生成或覆盖部分配置;旧版 Clash 内核、移动端 VPN 接口与桌面客户端的选项不能直接视为完全一致。开始修改前,应在客户端的内核信息或启动日志中确认实际运行的是哪一种内核。

例如,mode: rule 下,一条进入 TUN 的连接仍可能命中 DIRECT;一条经过系统代理进入本地 7890 端口的连接,也可能被规则送往代理节点。接管入口和出口选择应分开检查。

系统代理:应用主动连接本地端口

图形客户端的“系统代理”通常会修改操作系统的代理设置,让遵守该设置的应用把请求交给本地监听端口。以 mixed-port: 7890 为例,应用先连接 127.0.0.1:7890,再由内核建立后续连接。mixed 端口接受 HTTP 代理与 SOCKS 代理连接。

HTTPS 经过代理,不等于解密 HTTPS

浏览器使用 HTTP 代理访问 HTTPS 网站时,通常通过 CONNECT 建立隧道。仅开启系统代理不会自动解密网站的 TLS 内容,也不需要为普通代理用途安装站点证书。代理协议中的 HTTP 与目标网站是否使用 HTTPS,是两个不同层面。

系统代理没有生效的常见范围

  • 命令行程序:可能只读取 HTTP_PROXY、HTTPS_PROXY 等环境变量,或要求单独指定代理参数。
  • 游戏和自定义网络程序:可能直接建立套接字,不读取系统代理设置。
  • Windows 服务:运行账户和网络 API 可能与当前用户不同。用户代理设置不等同于所有服务的代理设置。
  • UDP 业务:不能因为 HTTP 代理已启用,就推断游戏 UDP、语音或 QUIC 已经经过代理。

系统代理适合先验证订阅、节点和基本规则。它通常不需要为了修改当前用户的代理设置而持续以管理员身份运行,影响范围也更容易判断。若只有浏览器需要代理,不必仅为扩大接管范围而立即启用 TUN。

TUN:通过虚拟接口接收 IP 数据包

TUN 在系统中建立虚拟网络接口,并配合路由把符合条件的 IP 数据包交给内核。应用仍按普通联网方式连接目标地址,不必主动理解 HTTP 或 SOCKS 代理。mihomo 接收数据包后处理连接,再根据规则选择出口。

auto-route: true 用于自动配置相关路由;auto-detect-interface: true 用于自动检测出口接口。它们不能替代权限,也不能保证与其他 VPN 的路由完全兼容。连接公司 VPN、切换 Wi-Fi 或增加有线网卡后,出口接口与路由优先级都可能发生变化。

比较项 系统代理 TUN
进入内核的方式 应用连接本地代理端口 路由把 IP 数据包送入虚拟接口
应用是否需要配合 需要读取代理设置或显式指定代理 通常不需要应用理解代理协议
UDP 接管 普通 HTTP 系统代理不能据此覆盖 UDP 可接管路由范围内的 UDP,出口仍需支持
系统权限 一般可修改当前用户设置 通常需要提权、服务或平台授权
主要排查对象 端口、应用设置、环境变量 虚拟接口、路由、DNS、出口接口

TUN 并不使不支持 UDP 的节点获得 UDP 能力,也不代表任意 IP 协议都能通过远端代理转发。尤其不要用一次 ping 成功或失败,单独判断 TCP 网站访问是否正常;ICMP 与实际业务连接的处理路径可能不同。

DNS:解析路径会影响规则命中

系统代理下,域名由谁解析取决于应用和代理协议。HTTP 代理可以收到域名形式的目标;SOCKS5 既可以接收域名,也可以接收应用已解析好的 IP。终端里的 socks5:// 与 socks5h:// 就可能产生不同的解析路径,不能只看出口 IP 是否变化。

TUN 接收到的通常是 IP 数据包。为了让域名规则仍能稳定工作,内核需要结合 DNS 映射、已有元数据,或按需使用流量嗅探。只打开虚拟接口而不检查 DNS,容易出现网站能访问但域名规则命中不符合预期的情况。

fake-ip 与 DNS 劫持各自负责什么

  • enhanced-mode: fake-ip:对适用的 DNS 查询返回映射地址,内核再把该地址关联回域名。示例中的 198.18.0.1/16 用于这一映射,不是真实网站出口地址。
  • dns-hijack:把命中条件的 DNS 流量交给内核 DNS 处理。常见配置覆盖 UDP 53 和 TCP 53。
  • nameserver:指定内核实际使用的上游解析器。是否加密、能否访问和分流策略,需要另外评估。

IPv6 也要单独验证。仅调整 IPv4 路由,不能据此认定 IPv6 已按相同策略接管。企业内网域名、打印机名称和局域网服务若依赖本地 DNS,应保留对应的解析路径;不要把所有解析异常都归因于节点不可用。

mihomo 配置:从最小改动开始

下面是用于解释字段的配置片段,不是完整订阅。应合并到现有配置的对应位置,保留已有的 proxies、proxy-groups 与 rules。同一层级不要重复声明两个 dns 或两个 tun;客户端若提供覆写功能,应使用其持久化覆写入口,避免订阅刷新后丢失修改。

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info

tun:
  enable: true
  stack: mixed
  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
    - 119.29.29.29

127.0.0.1:1053 是这里显式开放的本地 DNS 监听地址,不表示操作系统会自动向这个端口查询。TUN 的 DNS 劫持是另一条进入内核 DNS 的路径。示例上游使用传统 DNS,目的是让字段关系清楚;实际部署应依据网络环境和隐私要求选择上游,不要把这两个地址理解为通用最优配置。

stack 应该选 system、gvisor 还是 mixed

  • system:使用系统协议栈处理连接,需结合当前系统和内核实现验证兼容性。
  • gvisor:使用用户态协议栈,可作为特定兼容性问题的对照方案。
  • mixed:在 mihomo 中组合使用协议栈,TCP 使用 system 路径,UDP 使用 gVisor 路径。

不要把某种 stack 写成所有设备上的速度排名。测试时保留同一节点、同一目标和同一规则,只改变 stack,重启内核并确认旧连接已经退出,再比较连接成功率与业务表现。若当前客户端或内核不支持某个取值,先恢复其默认值,不应反复套用其他版本的配置。

权限与搭配:先单独验证,再决定并用

Windows 上,创建虚拟网卡和配置路由通常需要管理员权限,部分客户端通过服务模式执行这些操作。macOS、Linux 也需要相应的提权或服务权限;Linux 还涉及 TUN 设备与网络管理能力。图形界面的 TUN 开关显示开启,只能说明已发起操作,仍应检查启动日志中是否出现权限、接口创建或路由添加失败。

按使用范围选择入口

  1. 浏览器和常规桌面应用:先只开系统代理,确认节点、规则和本地端口正常。
  2. 终端工具:优先用显式代理参数验证,再决定是否设置环境变量。临时变量比全局修改更容易回退。
  3. 不读取代理设置的程序:关闭系统代理后单独测试 TUN,避免两个入口同时变化而难以定位问题。
  4. 多个入口确有需求:验证通过后可以同时开启。应用显式指定本地代理时会走该入口,其他符合路由条件的流量可由 TUN 接管。

同时开启并不必然意味着重复代理,也不会自动带来更好的网络质量。正常情况下,内核需要让自身的出站连接绕开 TUN 接管以避免回环。手工路由、其他 VPN 或错误的出口接口可能破坏这一前提,因此并用后出现异常,应先退回单入口配置。

系统代理开关还可能保留“绕过本地地址”等规则;TUN 的私网路由行为则是另一个配置层面。需要访问 NAS、局域网打印机或公司内网时,应分别检查系统代理绕过列表、路由和 mihomo 规则,而不是假设两者的例外范围相同。

验证与排障:确认连接究竟走哪条路径

用同一个目标进行对照,先证明本地代理端口可用,再判断系统接管是否生效。下面的命令仅是测试方法,不代表预先得到的实测结果。Windows 建议明确使用 curl.exe,避免部分 PowerShell 环境中的同名别名影响参数。

第一步:显式指定代理,排除系统接管因素

curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/
curl --proxy socks5h://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com/

此时即便系统代理关闭,命令也会尝试连接指定的本地端口。若出现连接被拒绝,先检查内核是否启动、实际监听端口是否为 7890。若能进入内核但访问失败,再检查日志中的解析、规则、节点握手和远端连接错误。

第二步:取消显式代理,验证 TUN 路径

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

--noproxy "*" 让这次 curl 请求不使用其应用层代理配置,但不会绕过操作系统的 TUN 路由。关闭系统代理、开启 TUN 后运行该命令,同时在客户端连接页检查目标、命中规则和策略。仅凭命令成功,仍不足以证明使用了代理节点,因为规则可能选择 DIRECT。

第三步:按现象缩小范围

  • 显式代理成功,TUN 失败:先看权限、虚拟接口和路由;Windows 可用 route print,Linux 可用 ip route 检查路由表。
  • 浏览器成功,终端失败:检查终端环境变量及工具自身代理选项,不能直接认定节点故障。
  • 域名失败,已知 IP 连接正常:重点检查 DNS,但应使用合适的测试服务;直接把 HTTPS 域名替换为 IP 会引入证书和 SNI 差异。
  • TCP 正常,语音或游戏异常:检查 UDP 接管、节点 UDP 能力及服务端限制,而不是只切换规则模式。
  • 开启另一套 VPN 后异常:临时关闭其中一套,比较默认路由、DNS 和出口接口,再配置两者的共存边界。

每次只改一个变量,并记录“入口、DNS、命中规则、实际策略、错误日志”五项信息。需要回退时,先关闭 TUN、恢复原配置,再核对系统代理地址;退出客户端前清理仍指向 127.0.0.1:7890 的代理设置,避免本地监听停止后应用继续连接旧端口。

首次配置可从入门教程开始;需要核对规则和配置结构时,查阅完整文档。