主路由与旁路由:先确定数据经过哪里

OpenWrt 运行 mihomo 的前提不是装好一个二进制文件,而是让目标流量经过它。mihomo 是 Clash Meta 后续使用的内核名称;内核负责代理协议、规则匹配与连接处理,OpenWrt 负责网络接口、路由、防火墙和服务管理。配置文件能够通过语法检查,不代表局域网终端已经被接管。

主路由通常直接承担上网出口、NAT 和 DHCP。旁路由则是局域网中的另一台设备,主路由继续拨号或连接上级网络。本文使用单网口、同网段旁路由作为示例;双网口串联设备需要按实际接口重新规划转发区域,不能直接套用同网段设置。

示例拓扑与职责分配
项目主路由部署旁路由部署
上网出口OpenWrt 直接连接上级网络保留现有主路由作为出口
终端默认网关OpenWrt 的 LAN 地址需要接管的终端指向旁路由
DHCP 服务通常由 OpenWrt 提供可以继续由主路由提供
故障影响可能影响全部终端可先限定为一台测试终端
主要难点出口防火墙与资源负载网关、回程路径与 DNS 一致性

同网段示例地址

  • 主路由:192.168.10.1/24,负责联网和 DHCP。
  • OpenWrt 旁路由:192.168.10.2/24,默认网关为 192.168.10.1。
  • 测试终端:192.168.10.100/24,默认网关和 DNS 暂时均设为 192.168.10.2。

地址必须替换为实际局域网地址。旁路由应使用固定地址,或者在 DHCP 服务端建立固定租约,并避免与动态地址池重叠。两个设备不要同时向同一广播域发送未协调的 DHCP 配置。

部署前检查:架构、存储与固件能力

先在 OpenWrt 的「状态」→「概览」查看固件信息,再通过 SSH 确认 CPU 和系统。商品名称中的“64 位处理器”不能替代固件架构:同一硬件可能运行不同位宽的用户空间。

ubus call system board
uname -m
cat /etc/openwrt_release
df -h /overlay /tmp
free -m

x86_64 通常对应 amd64 构建,aarch64 通常对应 arm64 构建。ARM 32 位还要核对指令集,MIPS 则需要区分大小端和浮点 ABI。不同发布资产的命名方式可能变化,应按 mihomo 发布说明选择,不能仅凭文件名中出现“linux”判断可用。

安装包管理与内核模块

  • 采用 opkg 的固件可用 opkg print-architecture 查看包架构;采用 apk 的固件可用 apk --print-arch 辅助判断。不要混用两个包管理器的安装命令。
  • TUN 方案需要固件具备 TUN 支持,常见相关软件包为 kmod-tun;TPROXY 需要相应的防火墙及内核模块支持。
  • OpenWrt 22.03 起默认防火墙通常为 firewall4,底层使用 nftables。旧教程中的 iptables 规则不宜直接复制到 firewall4 环境。
  • 内核模块必须与正在运行的固件内核匹配。仓库不可用或版本不一致时,应先解决固件与软件源匹配问题。

内核直跑:先完成配置测试与显式代理

常见部署方式有两种:通过 OpenWrt 插件管理内核,或者直接运行 mihomo。插件通常接管服务脚本、防火墙、DNS 和订阅更新;直接运行则需要逐项配置这些功能。两种方式应择一管理同一个实例,避免插件启动的内核与手动进程争用监听端口。

下面假定已经把与架构匹配的内核解压为 /usr/bin/mihomo,并将完整配置放在 /etc/mihomo/config.yaml。这些是本文采用的路径,不是所有插件的默认路径。订阅若只包含节点列表,还需要补齐代理组、规则等完整配置结构。

chmod 0755 /usr/bin/mihomo
/usr/bin/mihomo -v
/usr/bin/mihomo -t -d /etc/mihomo -f /etc/mihomo/config.yaml

-v 用于确认程序能执行并记录实际版本,-t 用于测试配置。若出现 Exec format error,优先检查架构及文件是否已解压;若出现 YAML 解析错误,应先修复缩进、字段类型或引用的规则集,不要继续叠加网络设置。

用 7890 端口验证代理链路

可先合并以下片段到完整配置。示例仅允许监听旁路由的局域网地址;是否允许其他设备连接,还取决于防火墙。allow-lan 开启后不能把该端口暴露到公网。

mixed-port: 7890
allow-lan: true
bind-address: 192.168.10.2
mode: rule
log-level: info

通过测试后,在 SSH 前台启动内核,便于观察错误。此时不要同时启动另一个相同实例。

/usr/bin/mihomo -d /etc/mihomo -f /etc/mihomo/config.yaml

在测试电脑上将 HTTP 代理指向 192.168.10.2:7890,或者用下列命令发起 HTTPS 请求。成功说明显式代理入口、节点和目标站之间的基本路径可用,并不说明 UDP 或透明代理已经生效。

curl -I --proxy http://192.168.10.2:7890 https://example.com/

前台验证结束后再交给 procd 服务脚本托管,设置开机启动和异常重启。服务应使用绝对路径,并将日志接入系统日志;不要依赖关闭 SSH 后可能结束的临时进程。

透明代理选择:REDIRECT、TPROXY 与 TUN

终端手动填写代理只覆盖遵循该代理设置的应用。旁路由要接管普通转发流量,还需要透明代理入口及对应路由。下面三种方案并不是三个可随意同时开启的开关,尤其不要让插件规则与手写规则重复截获同一批流量。

Linux 透明代理方案对照
方案主要入口额外条件
REDIRECTredir-port: 7892,通常用于 TCP需要 NAT 重定向规则,不可据此认为 UDP 已被接管
TPROXYtproxy-port: 7893,可处理 TCP、UDP需要透明套接字支持、标记和策略路由
TUN虚拟网络接口需要 TUN 支持、路由与转发权限,以及正确的防火墙处理

TUN 配置片段的边界

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

该片段展示 mihomo 的 TUN 配置方向,不是一份完整的 OpenWrt 透明代理部署脚本。auto-route 可以配置相关路由,但并不等于任意 LAN 拓扑都已打通。仍要检查 LAN 转发流量是否进入 TUN、出站连接能否到达主路由,以及 firewall4 是否允许所需转发。

多出口环境下,自动检测可能选到并非预期的出口,应检查实际路由,必要时按内核配置文档指定接口。Linux 上的 auto-redirect 是另一个涉及 nftables 的选项,其可用性和行为应以实际 mihomo 版本为准,不能把新版本示例原样放进旧内核。

网关与 DNS:两个设置分别验证

默认网关决定普通流量的下一跳,DNS 决定域名查询送到哪里。只改 DNS,业务连接仍可能绕过旁路由;只改网关,终端也可能继续使用此前缓存的 DNS、IPv6 DNS 或应用自己的加密解析。

先用一台终端验证网关

  1. 在 LuCI「网络」→「接口」→「LAN」→「编辑」中确认旁路由地址与掩码。不同固件的标签页可能略有差异,应以实际页面为准。
  2. 确认旁路由自身默认路由经 192.168.10.1 出口,可执行 ip route show default 检查。
  3. 只修改测试终端的默认网关为 192.168.10.2,暂不修改主路由对全网的 DHCP 下发配置。
  4. 确认终端能访问旁路由和主路由,再测试外部站点。网关变更后,需要注意旧连接可能继续使用原有路径。

如果后续通过 DHCP 批量下发,IPv4 的选项 3 是默认网关,选项 6 是 DNS 服务器。修改后需要让终端续租,并检查实际获得的参数。同网段旁路由可能出现直连连接的非对称回程及 ICMP 重定向,应结合抓包决定是否需要对受控转发流量做源 NAT。源 NAT 会改变主路由看到的源地址,不能把“开启伪装”当成所有拓扑的固定步骤。

保留 dnsmasq 的 53 端口

一种便于分层排查的安排是:dnsmasq 继续监听局域网的 53 端口,mihomo DNS 监听 127.0.0.1:1053,再由 dnsmasq 把上游查询转给 mihomo。下列片段用于合并到已有配置,示例上游需要在实际网络中可达。

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

在采用常见 LuCI 布局的固件中,可到「网络」→「DHCP/DNS」→「常规设置」的 DNS 转发项填写 127.0.0.1#1053。同时检查是否仍读取其他上游,以免查询绕过预定链路。若 mihomo 上游又指回 dnsmasq,就会形成 DNS 循环。

Fake-IP 返回的合成地址必须由透明代理路径正确接管;显式代理测试阶段不要急于把全网 DNS 切换到这一模式。遇到局域网域名、打印机或特定应用兼容问题,应按实际域名配置过滤或选择合适的解析模式,而不是直接清空全部 DNS 设置。

示例上游是普通 DNS,仅用于说明监听与转发关系,不代表查询已加密。浏览器安全 DNS、应用内 DoH 和 Android 私人 DNS 也不会因为设置了 dns-hijack 就自动全部被截获。

逐层排错:从进程到 IPv6

排查时保留一台未改网关的管理设备,并记录原始配置。按入口、路由、解析、规则的顺序检查,比反复更换节点更容易定位问题。以下命令用于观察状态,不会替代防火墙配置。

pgrep -af mihomo
logread -e mihomo
ip addr show
ip route show table all
ip rule show
nft list ruleset
nslookup example.com 192.168.10.2
常见现象与优先检查项
现象优先检查判断依据
内核启动后立即退出配置测试、端口占用、文件权限启动日志是否出现监听失败或配置错误
7890 可用,透明代理不可用终端网关、转发链、策略路由业务流量是否真正到达旁路由
能连外部 IP,域名访问失败53 与 1053 的监听及上游转发查询是否超时,是否出现解析循环
TCP 正常,游戏或 QUIC 异常UDP 接管、节点协议与服务器支持是否只有 TCP 被重定向
少数应用仍使用原出口IPv6 默认路由、应用独立代理或 VPN终端是否存在另一条可用网络路径

IPv6 不随 IPv4 网关一起改变

终端即使获得了指向旁路由的 IPv4 网关,仍可能从主路由的 RA 获得 IPv6 默认路由。此时 IPv6 连接可以直接经过主路由。应分别检查 IPv4 和 IPv6 路由、DNS 与防火墙,并决定完整接管 IPv6,还是在测试网络中暂时停止下发 IPv6 路由;只在 mihomo 中关闭某个 IPv6 选项并不能撤销终端已有的路由。

吞吐测试不能只看延迟

旁路由的 CPU、加密协议、网口速率和虚拟机网卡都可能影响吞吐。先测试普通局域网传输,再比较显式代理和透明代理的同一目标下载。测试时记录 CPU 占用、流量路径及实际节点,不能用一次延迟测试代替带宽测试。故障定位期间,可临时停用软件或硬件流量卸载,避免既有快路径干扰规则验证。

上线与回退:一次只扩大一个范围

  1. 保存基线。备份 OpenWrt 网络、防火墙、DHCP 和 mihomo 配置,记录主路由原有网关、DNS 下发方式。
  2. 验证显式代理。先确认内核、订阅、代理组与规则工作正常,再部署透明接管。
  3. 验证单台终端。分别测试网页、DNS、UDP、局域网设备访问和 IPv6,不要只观察一个网站。
  4. 验证重启恢复。确认接口就绪后服务能启动,DNS 不依赖尚未启动的代理链路,防火墙重载后规则仍然正确。
  5. 扩大 DHCP 范围。单机稳定后再逐步下发旁路由地址,并保留可直接管理主路由的设备。

需要回退时,先把测试终端或 DHCP 下发的网关恢复为 192.168.10.1,同时恢复可用 DNS,并让终端续租。之后再停止透明代理服务和清理其管理的规则。只停止 mihomo、却保留指向它的 DNS 转发和透明重定向,可能导致终端继续断网。

旁路由部署的核心是路径一致:终端把流量交给正确网关,DNS 返回的地址能沿对应路径处理,内核出站不会被再次截获。确定这三点后,再增加规则集、订阅更新和监控,部署过程更容易复现,也更容易回退。需要了解客户端与内核的区别,可继续查阅概念速查;跨平台安装步骤见全平台指南。