先固定拓扑:主路由负责出口,旁路由负责分流

旁路由直跑 mihomo,首先要解决的是流量路径,而不是订阅导入。建议只选一台测试终端修改网关,确认转发、DNS 和规则都正常后,再调整 DHCP。本文采用单网口、同网段旁路由:主路由继续拨号、提供 DHCP 和互联网出口;OpenWrt 接入主路由 LAN,由 mihomo 处理选定终端的流量。

设备IPv4 地址默认网关与职责
主路由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 中建立固定租约。OpenWrt 的「网络」→「接口」→「LAN」→「编辑」中设置静态 IPv4 地址、子网掩码和 IPv4 网关;旁路由自己的网关不能填成自身地址。

  • 同一广播域只保留一个 DHCP 服务。旁路由 LAN 的「DHCP 服务器」→「常规设置」中勾选「忽略此接口」,但保留 dnsmasq 的 DNS 功能。
  • 主路由的默认出口不要再指向旁路由,否则容易形成“旁路由交给主路由,主路由又交回来”的转发环路。
  • 测试阶段保留一条直接访问主路由的管理路径,避免服务停止后无法修改终端设置。

安装内核:区分 CPU 架构、工作目录和运行权限

mihomo 是 Clash Meta 后续使用的内核名称。直接部署内核不包含图形客户端,也不会自动生成 OpenWrt 防火墙配置。先通过 SSH 检查系统,确认下载的是对应架构的 Linux 可执行文件:

ubus call system board
uname -m
df -h /overlay /tmp
date
ip -4 route show

x86_64 通常对应 amd64,aarch64 通常对应 arm64。MIPS 设备还必须区分大小端、指令集与浮点 ABI,不能仅凭“64 位路由器”选择文件。看到 Exec format error 时先核对架构;遇到 Illegal instruction 时检查 CPU 指令集要求,不要反复修改 YAML。

放置二进制与配置

把已解压的内核通过 SCP 或 SFTP 上传到路由器的 /tmp/mihomo,再执行下面的命令。/tmp 通常位于内存,重启会清空;长期运行的内核和配置应放在持久存储中。

mkdir -p /etc/mihomo
cp /tmp/mihomo /usr/bin/mihomo
chmod 0755 /usr/bin/mihomo
chmod 0700 /etc/mihomo
/usr/bin/mihomo -v

将实际配置保存为 /etc/mihomo/config.yaml,并设置 chmod 0600 /etc/mihomo/config.yaml。订阅地址、节点密码和控制接口密钥都属于敏感信息。配置中若启用了规则集或地理数据库,要确认对应资源能下载或已放入工作目录;小容量闪存设备尤其需要关注剩余空间。

TUN 还需要内核支持。以 OpenWrt 24.10 系列常见的 opkg 环境为例,可执行以下命令;使用其他版本时,应先确认固件的包管理器和软件源。内核模块必须匹配当前固件内核,不能强装其他版本的软件包。

opkg update
opkg install kmod-tun ip-full
test -c /dev/net/tun && echo "TUN device ready"

先执行 /usr/bin/mihomo -t -d /etc/mihomo 检查配置。测试通过只能证明语法和部分资源初始化可用,不代表透明转发已经成功。

TUN 与 redir:按协议需求选择一种接管方式

TUN 通过虚拟网络设备接收 IP 流量,适合需要 TCP、UDP 一并处理的部署。redir 则依靠防火墙把 TCP 连接重定向到内核监听端口,链路较容易逐段观察,但单独的 redir-port 不接管 UDP。两种方式先选一种,不要同时开启多套插件、TUN 和手写透明代理规则。

项目TUNredir
接管范围可处理 TCP 与 UDP,实际能力也取决于节点主要是 TCP;UDP 需另做 TPROXY 等方案
必要条件/dev/net/tun、路由权限、转发放行TCP 监听端口与防火墙重定向规则
主要排查点策略路由、出口识别、TUN 防火墙区域规则命中、保留地址排除、重复接管
本文示例端口mixed-port: 7890 用于显式代理验证redir-port: 7892

TUN 最小链路测试配置

下面是一份用于验证直连转发的基础配置。它没有代理节点,最终规则为 DIRECT,因此测试成功不等于节点代理成功。先用它检查 TUN 与 DNS 链路,再合并实际的 proxies、proxy-providers、proxy-groups 和分流规则;不要用它覆盖尚未备份的配置。

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

tun:
  enable: true
  device: mihomo
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  strict-route: false
  dns-hijack:
    - any:53

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: redir-host
  nameserver:
    - 223.5.5.5
    - 119.29.29.29

rules:
  - IP-CIDR,192.168.10.0/24,DIRECT,no-resolve
  - MATCH,DIRECT

allow-lan: false 限制的是显式代理监听,并不等于禁止 TUN 处理转发流量。auto-route 会建立接管所需路由,但不会替你完成所有 OpenWrt 防火墙区域配置。auto-detect-interface 也需要正常的默认路由作为依据;多 WAN、VPN 出口或其他策略路由并存时,应根据实际出口明确设置 interface-name,而不是猜测一定是 eth0。

redir 的边界

选择 redir 时,关闭 tun.enable,设置 redir-port: 7892,再在防火墙的 prerouting 路径中仅重定向指定 LAN 终端的 TCP 流量。OpenWrt 22.03 及之后常见的是 firewall4 与 nftables,旧教程的 iptables 命令不能假定会写入同一套有效规则。

  • 规则应限定入口接口和测试源地址 192.168.10.100,排除路由器管理地址、局域网及必要的保留地址段。
  • 不能把内核自身建立的节点连接再次送回透明入口。若扩展到路由器本机流量,必须另做出口绕行与环路防护。
  • HTTP/3 使用 UDP/443。只有 TCP redir 时,浏览器的 HTTP/2 与 HTTP/3 可能走不同出口,这不是 7892 端口失效。
  • 不要整段替换 table inet fw4。规则持久化后还要测试 /etc/init.d/firewall reload,确认规则没有随重载消失。

DNS 指向:终端到旁路由,再由本地服务向上游解析

推荐的初始链路是:终端查询 192.168.10.2:53,OpenWrt dnsmasq 转发到 127.0.0.1:1053,mihomo 再请求明确指定的上游解析器。这样既保留 dnsmasq 对局域网名称的处理,也避免两个服务同时绑定同一地址的 53 端口。

在没有自定义分域解析的简单环境中,可用下面的 UCI 设置。先备份 /etc/config/dhcp;命令会移除第一组 dnsmasq 的既有通用上游列表,有企业域名或其他本地转发规则时应手工合并,不要直接执行。

cp /etc/config/dhcp /root/dhcp.before-mihomo
uci set dhcp.@dnsmasq[0].noresolv='1'
uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server='127.0.0.1#1053'
uci commit dhcp
/etc/init.d/dnsmasq restart

nslookup example.com 127.0.0.1

noresolv='1' 用于避免 dnsmasq 同时读取自动生成的上游列表。mihomo 的上游不能再填 192.168.10.2,否则会出现 dnsmasq 与 mihomo 相互转发的 DNS 环路。若节点服务器使用域名,也要保证它的解析链路在代理尚未连接时能够工作。

初次部署使用 redir-host 更容易直接观察解析结果。切换到 fake-ip 前,先确认旁路由转发稳定,再根据局域网域名和设备兼容性配置 fake-ip-filter。浏览器安全 DNS、Android 私人 DNS及应用内 DoH 可能绕过普通的 53 端口查询;dns-hijack 不会自动解密这些连接。

OpenWrt 转发与同网段回程:TUN 创建成功还不够

在「网络」→「防火墙」中核对实际区域和转发关系。常见做法是为 TUN 设备 mihomo 建立独立区域,允许 LAN 流量进入该区域,并允许 TUN 解出的直连流量流向实际出口区域。单臂旁路由的出口往往仍是 LAN;不能照搬双网口教程,默认认为出口一定属于 WAN。

  • 允许终端访问旁路由的 UDP/TCP 53 端口;不要把 DNS 服务意外开放到不可信接口。
  • 检查 net.ipv4.ip_forward 是否为 1。内核有路由而转发关闭时,终端仍无法上网。
  • 排障时临时关闭软件与硬件流量分载,避免已有连接走快速路径,干扰规则计数和抓包观察。
  • 不要用全局关闭防火墙的方式“修复”转发。只放行明确需要的区域与方向,并核对现有规则顺序。

同网段还有一个容易忽略的问题:旁路由将直连流量交给主路由后,主路由可能把回包直接发给终端,形成不对称路径。在需要双向都经过旁路由的设计中,应对选定的转发流量做有范围限制的源地址转换,使上游看到的源地址为 192.168.10.2。不要不加判断地给整个 LAN 区域开启所有流量的伪装;另一种更清晰的方案是把被代理终端放到独立子网。

同一接口进出的转发还可能触发 ICMP Redirect,提示终端改走主路由。在此拓扑下应检查相关设置,尤其是实际 LAN 设备上的值:

sysctl net.ipv4.ip_forward
sysctl net.ipv4.conf.all.send_redirects
sysctl net.ipv4.conf.default.send_redirects
sysctl net.ipv4.conf.br-lan.send_redirects

ip -4 route show
ip -4 rule show
ip -4 route show table all

如果设备名确实是 br-lan,可将上述三个 send_redirects 项设为 0,验证后再持久化。接口名含点或采用不同桥接结构时,应按实际设备调整。不要把所有 sysctl 开关一起修改,否则很难判断是哪一步改变了数据路径。

开机自启:使用 procd,而不是 systemd

OpenWrt 通常使用 procd 管理服务,不适用桌面 Linux 的 systemctl enable mihomo。先停掉其他代理管理插件,确认没有第二个进程占用端口或维护相同的 TUN 路由,再创建 /etc/init.d/mihomo:

#!/bin/sh /etc/rc.common

START=99
STOP=10
USE_PROCD=1

start_service() {
    /usr/bin/mihomo -t -d /etc/mihomo || return 1

    procd_open_instance
    procd_set_param command /usr/bin/mihomo -d /etc/mihomo
    procd_set_param respawn 3600 5 5
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_set_param limits nofile="65535 65535"
    procd_close_instance
}

该脚本先检查配置,再交由 procd 启动。respawn 的示例参数用于限制短时间内反复崩溃重启。服务默认以 root 运行,便于创建 TUN 与修改路由;若要改为低权限用户,必须另外设计能力授权,不能只增加一行用户名。

chmod 0755 /etc/init.d/mihomo
/etc/init.d/mihomo start
logread -e mihomo
ip link show mihomo

# 确认运行与转发正常后再开启自启动
/etc/init.d/mihomo enable

修改 YAML 后先执行 mihomo -t -d /etc/mihomo,通过后再执行 /etc/init.d/mihomo restart。只有防火墙规则另行持久化、DNS 服务就绪、启动后的资源下载可用,才算完整的开机恢复;START=99 本身不保证互联网已经连通。

验收与回滚:按端口、DNS、转发、节点四层检查

验收时保持只有测试终端改网关。先在旁路由上验证显式代理,再验证终端透明流量,最后才在主路由 DHCP 中推广网关与 DNS。这样能区分“内核能联网”和“终端流量已经被接管”。

  1. 确认内核运行。查看 logread -e mihomo,排除端口占用、规则下载失败与 TUN 创建失败。若安装了 ss,可执行 ss -lntup 检查 7890、1053 等实际监听。
  2. 验证显式代理。路由器具备 curl 时执行 curl -I -x http://127.0.0.1:7890 https://example.com。此步骤绕开终端透明转发,失败时先查内核、上游 DNS 与出口。
  3. 验证终端 DNS。在 Linux 测试终端执行 nslookup example.com 192.168.10.2,再用 ip -4 route show default 确认网关。解析成功不代表 TCP 已经过 TUN。
  4. 确认透明规则命中。终端关闭应用内显式代理后发起新连接,观察 mihomo 日志中的源地址、规则和出站。合并节点配置后,要看到实际代理组与节点,而不是一直命中 DIRECT。
  5. 测试恢复能力。依次测试服务重启、防火墙重载、设备重启。检查 DNS 是否恢复、TUN 是否重建,以及终端是否仍使用原定网关。

常见现象与优先检查项

现象优先检查
路由器可访问,终端不可访问终端网关、IPv4 转发、防火墙区域、同网段回程
IP 连接可用,域名失败53/1053 端口、dnsmasq 上游、DNS 环路
部分应用绕过代理IPv6 默认路由、UDP、应用自己的代理或 DNS
小请求成功,下载经常卡住路径 MTU、上游封装、重传;不要先盲目调大 TUN MTU
重启后失效procd 启用状态、持久配置位置、防火墙规则恢复、启动日志

需要回滚时,先把测试终端的网关与 DNS 恢复为主路由 192.168.10.1,再停止 mihomo,撤销自定义透明规则和转发配置。若已经让 dnsmasq 只转发到 1053,必须同时恢复其上游;否则停掉内核后,旁路由仍会接收查询,却没有可用解析服务。

/etc/init.d/mihomo stop
/etc/init.d/mihomo disable

# 仅在备份就是本次部署前配置时恢复
cp /root/dhcp.before-mihomo /etc/config/dhcp
/etc/init.d/dnsmasq restart

最后再决定是否推广到全网。主路由通过 DHCP 选项 3 发布网关、选项 6 发布 DNS;只有需要经过旁路由的终端才应获得对应地址。保留拓扑记录、配置备份和回滚路径,比一次性套入完整规则更有利于长期维护。字段含义可继续查看配置参考,客户端导入流程见快速上手。