Main Router vs. Side Router: Start by Mapping the Traffic Flow
Running mihomo on OpenWrt is about more than installing a binary—you need to route the traffic you want to proxy through it. mihomo is the name of the kernel used by Clash Meta going forward. It handles proxy protocols, rule matching, and connections; OpenWrt manages network interfaces, routing, the firewall, and services. A configuration that passes syntax checks does not mean LAN devices are being routed through the proxy.
The main router typically handles the internet connection, NAT, and DHCP. A side router is another device on the LAN, while the main router continues to connect to the upstream network. This guide uses a single-port side router on the same subnet as an example. For a dual-port device wired inline, plan the forwarding zones around the actual interfaces; same-subnet settings won't apply as-is.
| Item | Main-router setup | Side-router setup |
|---|---|---|
| Internet gateway | OpenWrt connects directly to the upstream network | Keep the existing main router as the gateway |
| Default gateway for clients | OpenWrt LAN address | Point devices to be routed through the side router |
| DHCP service | Usually provided by OpenWrt | Can remain on the main router |
| Impact of failure | May affect every device | Can be limited to a single test device |
| Main challenge | Gateway firewall and system load | Gateway settings, return path, and DNS consistency |
Example addresses on the same subnet
- Main router:
192.168.10.1/24, handling internet access and DHCP. - OpenWrt side router:
192.168.10.2/24, with192.168.10.1as its default gateway. - Test device:
192.168.10.100/24, with192.168.10.2temporarily set as both its default gateway and DNS server.
Replace these addresses with those used on your LAN. Give the side router a static address or create a DHCP reservation, and make sure it does not overlap with the dynamic address pool. Do not let both devices advertise conflicting DHCP settings on the same broadcast domain.
Before You Start: Check Architecture, Storage, and Firmware Support
First, check the firmware details under Status → Overview in OpenWrt, then use SSH to confirm the CPU and system architecture. A product listing that says “64-bit processor” does not guarantee a 64-bit userspace: the same hardware may run firmware with different word sizes.
ubus call system board
uname -m
cat /etc/openwrt_release
df -h /overlay /tmp
free -m
x86_64 usually maps to an amd64 build, and aarch64 to an arm64 build. For 32-bit ARM, also check the instruction set; for MIPS, confirm endianness and floating-point ABI. Release asset names can change, so choose a build based on the mihomo release notes—not just because the filename contains “linux.”
Package Manager and Kernel Modules
- On firmware that uses opkg, run
opkg print-architectureto check the package architecture. On apk-based firmware,apk --print-archcan help. Do not mix commands from the two package managers. - The TUN approach requires firmware with TUN support;
kmod-tunis a commonly used package. TPROXY requires the relevant firewall and kernel module support. - Since OpenWrt 22.03, the default firewall is typically firewall4, which uses nftables underneath. Avoid copying iptables rules from older guides directly into a firewall4 setup.
- Kernel modules must match the firmware kernel currently in use. If a package repository is unavailable or versions do not match, resolve the firmware and package-feed mismatch first.
Run the Kernel Directly: Test the Configuration and Explicit Proxy First
There are two common deployment options: manage the kernel through an OpenWrt plugin, or run mihomo directly. A plugin usually handles service scripts, firewall rules, DNS, and subscription updates. When running mihomo directly, you need to configure each of these yourself. Choose one method to manage the instance so a plugin and a manually started process don't compete for the same listening ports.
For this guide, assume the architecture-matched kernel has been extracted to /usr/bin/mihomo, and the complete configuration is at /etc/mihomo/config.yaml. These are the paths used here, not universal plugin defaults. If your subscription contains only a list of nodes, you'll also need to add the full configuration structure, including proxy groups and rules.
chmod 0755 /usr/bin/mihomo
/usr/bin/mihomo -v
/usr/bin/mihomo -t -d /etc/mihomo -f /etc/mihomo/config.yaml
Use -v to confirm the program runs and check its actual version; use -t to test the configuration. If you see Exec format error, check the architecture and make sure the file has been extracted. For YAML parsing errors, fix indentation, field types, or referenced rule sets before adding network settings.
Test the Proxy Path on Port 7890
You can merge the following snippet into a complete configuration. This example listens only on the side router's LAN address; whether other devices can connect also depends on the firewall. Once allow-lan is enabled, do not expose this port to the public internet.
mixed-port: 7890
allow-lan: true
bind-address: 192.168.10.2
mode: rule
log-level: info
Once the test passes, start the kernel in the foreground over SSH so you can watch for errors. Do not start a second instance at the same time.
/usr/bin/mihomo -d /etc/mihomo -f /etc/mihomo/config.yaml
On a test computer, set the HTTP proxy to 192.168.10.2:7890, or use the command below to make an HTTPS request. A successful request confirms the basic path between the explicit proxy, the node, and the destination site. It does not confirm that UDP or transparent proxying is working.
curl -I --proxy http://192.168.10.2:7890 https://example.com/
After foreground testing, run mihomo under a procd service script and configure it to start on boot and restart after failures. Use absolute paths and send logs to the system logger. Do not rely on a temporary process that may stop when you close SSH.
Choose a Transparent Proxy Method: REDIRECT, TPROXY, or TUN
Manually setting a proxy on a device only affects apps that honor that setting. To route ordinary forwarded traffic through a side router, you also need a transparent proxy entry point and the corresponding routes. These are not three switches to turn on at once. In particular, avoid having plugin rules and custom rules intercept the same traffic.
| Method | Primary entry point | Additional requirements |
|---|---|---|
| REDIRECT | redir-port: 7892, typically for TCP | Requires NAT redirect rules; this does not mean UDP is covered |
| TPROXY | tproxy-port: 7893, supports TCP and UDP | Requires transparent socket support, packet marks, and policy routing |
| TUN | Virtual network interface | Requires TUN support, routing and forwarding permissions, and the correct firewall rules |
What the TUN Configuration Snippet Does—and Doesn't—Cover
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
This snippet shows how to configure TUN in mihomo; it is not a complete OpenWrt transparent proxy deployment script. auto-route can configure related routes, but it does not guarantee connectivity for every LAN topology. You still need to check that forwarded LAN traffic enters TUN, outbound connections can reach the main router, and firewall4 allows the required forwarding.
In a multi-gateway setup, automatic detection may select the wrong outgoing interface. Check the actual routes and, if needed, specify an interface as described in the kernel configuration docs. On Linux, auto-redirect is a separate nftables-related option. Check its availability and behavior against your mihomo version; don't copy a current example into an older kernel without checking compatibility.
Gateway and DNS: Verify Them Separately
The default gateway determines the next hop for regular traffic; DNS determines where domain lookups go. Changing DNS alone may leave application traffic bypassing the side router. Changing the gateway alone may leave devices using cached DNS, IPv6 DNS, or encrypted DNS built into an app.
Test the Gateway on One Device First
- In LuCI, open Network → Interfaces → LAN → Edit and confirm the side router's address and subnet mask. Tab names may vary slightly between firmware versions, so follow the interface shown on your device.
- Check that the side router's default route uses
192.168.10.1as its gateway by runningip route show default. - Change the default gateway on the test device only to
192.168.10.2. Leave the main router's DHCP settings for the rest of the network unchanged for now. - Confirm the device can reach both the side router and the main router, then test an external site. After changing the gateway, remember that existing connections may continue using the old path.
If you later push settings to multiple devices through DHCP, IPv4 option 3 is the default gateway and option 6 is the DNS server. After making changes, renew the DHCP lease and check which settings the device actually received. On a same-subnet side router, direct connections can have an asymmetric return path and trigger ICMP redirects. Use packet captures to decide whether source NAT is needed for the forwarded traffic you control. Source NAT changes the source address seen by the main router, so masquerading is not a required step for every topology.
Keep dnsmasq on Port 53
One setup that's easy to troubleshoot in layers is to leave dnsmasq listening on LAN port 53, have mihomo DNS listen on 127.0.0.1:1053, and forward upstream queries from dnsmasq to mihomo. Merge the snippet below into your existing configuration, and make sure the example upstream is reachable on your network.
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
On firmware with the common LuCI layout, go to Network → DHCP/DNS → General Settings and enter 127.0.0.1#1053 under DNS forwardings. Also check whether other upstream servers are still being used, as queries could bypass the intended path. Pointing mihomo's upstream back to dnsmasq creates a DNS loop.
Synthetic addresses returned by Fake-IP must be handled correctly by the transparent proxy path. During explicit proxy testing, don't rush to switch the entire network's DNS to this mode. If local domains, printers, or specific apps have compatibility issues, configure filters for the relevant domains or choose a suitable DNS mode instead of clearing all DNS settings.
The example upstream is plain DNS and only illustrates the listening and forwarding setup; it does not encrypt queries. Browser Secure DNS, in-app DoH, and Android Private DNS are not automatically intercepted just because dns-hijack is configured.
Troubleshoot in Layers: From the Process to IPv6
Keep one management device on its original gateway and save a copy of the current configuration. Check the proxy entry point, routes, DNS resolution, and rules in that order; it's easier to find the cause than by repeatedly switching nodes. The commands below show system status and do not configure the firewall.
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
| Symptom | Check first | How to confirm |
|---|---|---|
| Kernel exits immediately after startup | Configuration test, port conflicts, file permissions | Check startup logs for a listener failure or configuration error |
| Port 7890 works, but transparent proxying doesn't | Client gateway, forwarding path, policy routing | Check whether application traffic actually reaches the side router |
| External IPs are reachable, but domain names fail | Listeners on ports 53 and 1053, and upstream forwarding | Check for query timeouts or a DNS resolution loop |
| TCP works, but games or QUIC don't | UDP interception, node protocol, and server support | Check whether only TCP traffic is redirected |
| A few apps still use the original gateway | IPv6 default route, app-specific proxy, or VPN | Check whether the device has another working network path |
Changing the IPv4 gateway does not change IPv6 routing
Even if a device gets an IPv4 gateway pointing to the side router, it may still receive an IPv6 default route from the main router's RA. IPv6 connections can then bypass the side router and go directly through the main router. Check IPv4 and IPv6 routes, DNS, and firewall rules separately. Decide whether to route all IPv6 traffic through the side router or temporarily stop advertising IPv6 routes on a test network. Disabling an IPv6 option in mihomo alone does not remove routes already installed on client devices.
Measure Throughput, Not Just Latency
The side router's CPU, encryption protocol, Ethernet link speed, and virtual machine network adapter can all affect throughput. First test ordinary LAN transfers, then compare explicit and transparent proxy downloads to the same destination. Record CPU usage, the traffic path, and the node in use; a single latency test is not a bandwidth test. While troubleshooting, you can temporarily disable software or hardware flow offloading so existing fast paths don't interfere with rule checks.
Roll Out and Roll Back: Expand One Scope at a Time
- Save a baseline. Back up the OpenWrt network, firewall, DHCP, and mihomo configurations. Note the main router's original gateway and how it assigns DNS.
- Verify the explicit proxy. Confirm the kernel, subscription, proxy groups, and rules work before setting up transparent proxying.
- Test one device. Check websites, DNS, UDP, access to LAN devices, and IPv6—not just a single site.
- Test recovery after reboot. Confirm the service starts once the interfaces are ready, DNS does not depend on a proxy path that hasn't started, and firewall rules remain correct after a reload.
- Expand the DHCP scope. Once the setup is stable on one device, gradually assign the side router as the gateway to more devices. Keep a device that can still reach the main router directly for management.
To roll back, first restore 192.168.10.1 as the gateway on the test device or in the DHCP settings, restore a working DNS server, and renew the device's lease. Then stop the transparent proxy service and remove the rules it manages. Stopping mihomo while leaving DNS forwarding and transparent redirects pointed at it can still disconnect devices.
A successful side-router setup depends on a consistent traffic path: devices send traffic to the right gateway, DNS responses can be handled along that path, and the kernel's outbound connections are not intercepted again. Once these three points are in place, add rule sets, subscription updates, and monitoring. This makes the setup easier to reproduce and roll back. For the difference between clients and kernels, see the quick reference; for installation steps across platforms, see the cross-platform guide.