从 Mihomo TUN 模式看策略路由的艺术

0. 诡异的“现状”

当我第一次开启 Mihomo (Clash Meta) 的 TUN 模式并成功科学上网后,作为一个有好奇心的 Linux 用户,我习惯性地敲下 ip route 想看看默认网关变成了什么。

然而,看到的结果可能会让我大吃一惊:

1
2
3
4
5
default via 192.168.3.1 dev wlp0s20f3 proto dhcp src 192.168.3.100 metric 600 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.3.0/24 dev wlp0s20f3 proto kernel scope link src 192.168.3.100 metric 600
198.18.0.0/30 dev Meta proto kernel scope link src 198.18.0.1

一切看起来太“正常”了。
默认网关(default)依然指向家里的路由器(192.168.3.1),并没有像传统的 VPN 那样被修改为虚拟网卡。

既然路由表没变,流量是怎么“凭空”跑进 Mihomo 的 Meta 网卡的?
实际上,真正的 Magic 并没有发生在大家熟悉的 ip route(路由表)里,而是发生在其上层——**ip rule(路由策略)** 中。

让我们看看 ip rule 的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
0:      from all lookup local
5210: from all fwmark 0x80000/0xff0000 lookup main
5230: from all fwmark 0x80000/0xff0000 lookup default
5250: from all fwmark 0x80000/0xff0000 unreachable
9000: from all to 198.18.0.0/30 lookup 2022
9001: not from all dport 53 lookup main suppress_prefixlength 0
9001: from all iif Meta goto 9010
9002: not from all iif lo lookup 2022
9002: from 0.0.0.0 iif lo lookup 2022
9002: from 198.18.0.0/30 iif lo lookup 2022
9010: from all nop
32766: from all lookup main
32767: from all lookup default


1. 地图与分拣员

在 Linux 网络世界里,管理流量主要靠两个层级:

  • **ip route (路由表 - 地图)**:它只负责回答”去哪里怎么走”。比如:去局域网走 Wi-Fi 网卡,去互联网走网关。
  • ip rule (路由策略 - 分拣员):它是路由表的”经理”。它决定了有资格看哪张地图

为什么不只用一张地图?
因为需求太复杂。比如:代理软件自身的流量必须走”普通地图”发出去,而浏览器的流量必须看”代理地图”进 TUN 网卡。如果大家看同一张图,就会陷入”无限套娃”的死循环。


2. Mihomo 的 TUN 模式是如何工作的?

通过观察 ip rule 的输出,我们可以将数据包的处理流程分为三个阶段:

第一阶段:特殊车辆避让(防环路)

1
5210: from all fwmark 0x80000/0xff0000 lookup main
  • 原理:Mihomo 给自己发出的加密数据包打上了”防火墙标记”(fwmark 0x80000)。
  • 逻辑:分拣员看到这种标记,会命令它直接查 main 表(物理网卡出口)。这保证了代理后的流量能正常发出,而不会被再次拦截,完美避免了环路

第二阶段:精妙的分流(劫持核心)

1
2
9001: not from all dport 53 lookup main suppress_prefixlength 0
9002: from 0.0.0.0 iif lo lookup 2022

这是最精彩的部分:

  1. 黑科技 suppress_prefixlength 0:内核先尝试查 main 表。如果你访问的是局域网(掩码长度 > 0),就直接查表走人;如果你访问的是互联网(只能匹配到默认路由,掩码长度为 0),这条规则就会失效,继续往下走。
  2. 强制入表:没被 main 表接纳的上网流量,在 9002 规则处被统统扔进了 **table 2022**。
  3. 进入 TUNtable 2022 是一张 Mihomo 专门画的地图,上面只有一条路:default dev Meta。于是,流量顺着管道进入了 Mihomo 进程。

第三阶段:兜底与放行

1
2
9010: from all nop
32766: from all lookup main
  • 对于那些从 TUN 网卡处理完出来、准备发往互联网的包,Mihomo 通过 goto 9010 让它们跳过拦截区,最终从 32766 处的 main 表正常发出。

3. 流量的一生:以访问 Google 为例

  1. 应用发起请求:目标 8.8.8.8
  2. 分拣员判断
    • 不是本地包?跳过 local
    • 没有标记?跳过 5210
    • main 表发现只有默认路由?被 suppress_prefixlength 0 踢出。
    • **匹配 9002**:滚去查 table 2022
  3. 进入虚拟网卡table 2022 说走 Meta 设备,Mihomo 收到数据包。
  4. 代理加密:Mihomo 处理后,给新包打上 0x80000 标记。
  5. 二次出发
    • 匹配 5210 规则。
    • 直接查 main 表。
    • 顺利通过 Wi-Fi 网卡发出。

4. ip 命令家族速查

ip 命令是现代 Linux 运维的标配:

命令 职责 场景举例
ip link 网卡开关/物理属性 修改 MTU、开启/关闭网卡
ip addr IP 地址管理 给网卡添加多个 IP
ip route 管理地图 手动添加静态路由
ip rule 决策引擎 实现多线接入、流量劫持
ip neigh 邻居发现 查看局域网内的 MAC 地址
ip netns 网络多重宇宙 Docker 容器的网络隔离原理

从 Mihomo TUN 模式看策略路由的艺术
https://20040702.xyz/2026/01/01/linux-route/
作者
Seeker
发布于
2026年1月1日
许可协议