Choose a deployment: decide where the gateway belongs, then how to route traffic

If your main router has enough capacity and you want to manage every device centrally, run mihomo directly on OpenWrt. If you want to keep your existing router and connect only selected devices, a side router makes it easier to test in stages. For a first deployment, verify the manual proxy first, add DNS next, and enable transparent proxying last. This makes it easier to pinpoint problems than changing all three at once.

mihomo is a proxy core that evolved from Clash Meta. It handles protocol connections, rule matching, DNS, and more. It is not router firmware and does not include a complete router management interface. OpenWrt plugins typically generate configuration, manage the process, install firewall rules, and provide a LuCI interface. Running the binary directly means handling those tasks yourself.

Deployment locationHow devices connectKey maintenance tasks
OpenWrt main routerRoute LAN traffic through the shared gatewayFirewall, DNS, and hardware flow offloading
OpenWrt side routerSet selected devices to use the side router as their gatewayReturn path, DHCP, and forwarding on the same subnet
Linux mini PCUse a manual proxy or configure it as a gatewayService management, forwarding, routing, and firewall
mihomo in a containerStart with an explicit proxy, then assess transparent routingNetwork namespaces, device mapping, and permissions

Hardware requirements: check architecture, available memory, and storage

Use the architecture reported by the operating system

First, run the commands below over SSH. A 64-bit-capable CPU does not mean the installed firmware is 64-bit. Match the binary to the architecture of the running system. On ARM, check the instruction-set level; on MIPS, check endianness. Builds requiring newer instruction sets will not run on older processors.

uname -m
cat /etc/openwrt_release
free -m
df -h /overlay
df -h /tmp

For example, aarch64 usually means ARM64, while x86_64 means 64-bit x86. If startup reports an illegal instruction, check the build requirements first. If the system says it cannot execute the file, check its architecture, execute permissions, and runtime environment instead of repeatedly changing subscriptions.

Plan for headroom

  • Devices with 256 MB of RAM: This is a tight fit. Keep rule sets and subscriptions small, and monitor free memory while rules update—not just after startup.
  • Devices with 512 MB of RAM: A reasonable starting point to assess for a lightweight home setup, but account for wireless services, file sharing, and other plugins.
  • Devices with 1 GB of RAM or more: Better suited to running multiple services or larger rule sets, though you should still monitor usage under your actual connection load.
  • Storage: As an initial planning estimate, reserve at least 100 MB of writable space for the core, configuration, rule data, and temporary update files. This is not a universal minimum for every setup.

OpenWrt's /tmp typically uses a RAM-backed filesystem. Large files there consume memory and may disappear after a reboot. Throughput also depends on CPU single-core performance, encryption protocol, network driver, and the transparent proxy path. A gigabit Ethernet port does not guarantee gigabit proxy throughput.

Installation options: plugin-managed, native service, or container

OpenWrt plugin: manage configuration from one place

Choose a plugin that supports your firmware version and firewall stack. Newer OpenWrt releases generally use firewall4 and nftables, while older systems may still use firewall3 and iptables. Check the plugin documentation before installing; do not apply legacy firewall scripts to a newer system.

  1. Back up your network, DHCP, and firewall settings. Note the router's LAN address and how to connect over SSH.
  2. Install mihomo through the plugin or choose a binary that matches your architecture, then add a subscription configuration supported by that core.
  3. Disable transparent routing initially. Confirm the configuration loads and nodes connect, then enable DNS and traffic routing one at a time.
  4. Check whether the plugin regenerates its configuration. Put persistent changes in the plugin's supported override or additional-configuration section.

Menu names vary by plugin and version, so do not assume desktop-client settings paths apply. Avoid having two proxy plugins handle DNS or transparent routing at the same time; this can cause port conflicts, overlapping rules, and double proxying.

Native binary: manage the process and startup yourself

The example below assumes the core is installed at /usr/bin/mihomo and the configuration is saved to /etc/mihomo/config.yaml. Check the syntax first, then start it in the foreground to inspect the logs:

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

A successful configuration check does not prove that remote nodes are reachable or that transparent routing is working. After testing in the foreground, use procd to manage the service on OpenWrt. On Linux with systemd, create a service unit with a working directory and restart policy. Avoid launching it in the background from SSH alone; the service may stop when you disconnect or reboot.

Containers: an explicit proxy is easier than a transparent gateway

A standard bridge network with port mapping can provide an HTTP or SOCKS proxy as a first step. TUN usually also requires access to /dev/net/tun, network administration capabilities, and an appropriate network mode. Routes inside a container affect only its network namespace; they do not automatically take over the host or the entire LAN. Do not grant every permission just to troubleshoot. First identify where the traffic needs to enter the core.

Side-router topology: check the gateway and DNS separately

Consider this example network: the main router is 192.168.50.1, the side router has a fixed address of 192.168.50.2, and both use the subnet mask 255.255.255.0. The side router's default gateway points to the main router. For the first test, change settings on one computer only and leave all other devices as they are.

Test modeDevice settingsWhat to verify
Manual proxyKeep the gateway at .1; set the app's proxy to .2:7890Core, subscription, and node connectivity
Transparent proxySet the default gateway to .2 and DNS to the configured LAN DNS serviceForwarding, rules, and DNS routing
Restore the original networkRestore the gateway and DNS to .1 or the original DHCP settingsTell side-router issues apart from upstream issues

Changing DNS alone does not route every connection through the side router; changing the gateway alone does not guarantee that domain lookups behave as expected. Transparent proxying also requires IP forwarding to be enabled, with the correct firewall rules and return path. On a single-port side router, direct traffic may go from the side router to the main router while replies travel straight from the main router to the device, creating an asymmetric path.

Some setups use source NAT to stabilize the return path. This changes the source address visible upstream, so do not copy a NAT command without understanding its effects. Follow the topology instructions for your plugin. Once one device works, consider distributing gateway option 3 and DNS option 6 through DHCP. Do not casually enable a second DHCP server on the same broadcast domain.

Configuration: start with a restricted LAN proxy

This basic snippet for the network above is not a complete subscription. It illustrates how the listening address, mixed proxy port, and DNS entry point fit together. Nodes, proxy groups, and rules must come from a valid configuration. With a plugin, use its supported configuration methods rather than editing generated files directly.

mixed-port: 7890
allow-lan: true
bind-address: 192.168.50.2
mode: rule
log-level: info
ipv6: false

dns:
  enable: true
  listen: 192.168.50.2:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 1.1.1.1
  • mixed-port: 7890 provides both HTTP and SOCKS proxy access on the same port. It is not a transparent proxy port; devices must be explicitly configured to use it.
  • allow-lan: true permits LAN access, but the firewall should still restrict it to trusted devices. Do not forward port 7890 to the public internet.
  • bind-address binds to the example side-router address. In your deployment, this address must exist on a local interface.
  • 1053 is the example DNS upstream listening port. Devices normally send DNS queries to port 53; DHCP cannot specify port 1053 on its own.

On OpenWrt, dnsmasq can continue serving LAN clients on port 53 and forward queries to mihomo on port 1053. Check the forwarding chain: dnsmasq should point to mihomo, and mihomo's upstream must not point back to the same dnsmasq instance, or DNS will loop. The public resolvers in the example illustrate the format only; choose upstreams based on reachability from your network and your routing needs.

Transparent proxy and TUN: do not route the same traffic twice

Common transparent proxy approaches include firewall redirection, TProxy, and TUN. Redirection is generally used for TCP. TProxy can handle TCP and UDP, but requires compatible kernel support, policy routing, and firewall rules. TUN passes traffic to the core through a virtual network interface; it does not automatically solve every routing or DNS issue.

Check these three areas together

  1. Ingress: Does forwarded LAN traffic enter the expected chain or TUN route? Routing only the router's own traffic does not prove that LAN devices are included.
  2. Exclusions: Are traffic to proxy node servers, LAN addresses, and the core's own outbound connections excluded correctly? Otherwise, traffic can re-enter the proxy and create a loop.
  3. Return path: Do policy routing, firewall marks, and connection tracking agree? Do both UDP and TCP follow the intended path?

mihomo TUN can use options such as auto-route to help set up routes. On supported Linux systems, auto-redirect can also help redirect traffic. Follow the plugin's design when deciding whether to enable them. Do not enable the plugin's TProxy routing and a separate TUN auto-routing setup at the same time and expect them to coordinate automatically.

For troubleshooting, temporarily disable software or hardware flow offloading and compare the results. Some acceleration paths may bypass the processing chain you need. If only QUIC video or games are affected, check UDP forwarding and node protocol support separately. One web page loading in a browser does not prove all traffic is working.

DNS, Fake-IP, and IPv6: keep resolution and connection paths aligned

Fake-IP returns a mapped address for a domain; this example uses 198.18.0.0/16. mihomo must recognize these addresses and map them back to domains. They cannot be sent to the upstream router as ordinary public destinations. Connections from a device using a Fake-IP must therefore follow the same proxy-routing path.

  • LAN hostnames: Preserve local DNS resolution for printers, NAS devices, and router management names. If needed, combine Fake-IP filtering with DNS policies; do not ignore where local DNS answers come from after adding a filter.
  • Encrypted DNS built into apps: A browser's DoH may bypass system DNS. Intercepting traditional port 53 queries does not cover these lookups, so check whether the browser has a separate resolver configured.
  • IPv6: Devices may receive a different default route through router advertisements. Changing only the IPv4 gateway can leave IPv6 connections going direct.
  • Restore settings: After disabling Fake-IP or changing DNS, clear device and app caches to avoid continued use of stale mapped addresses.

The example disables IPv6 use and AAAA responses in mihomo, but that does not disable IPv6 across the LAN. Before deployment, choose a clear approach: configure IPv6 routing for proxy traffic, or temporarily disable IPv6 router advertisements and related services on the test network. Do not mistake an overlooked IPv6 path for rules failing at random.

Verify and roll back: trace the connection path layer by layer

Change one variable at a time and record settings before and after each change. The commands below check process logs, listening ports, routes, and DNS. Use the tools already available on your system; there is no need to install everything for a single troubleshooting session.

logread | grep -i mihomo
ss -lntup
ip route show
ip rule show
nslookup example.com 192.168.50.2
curl -I -x http://192.168.50.2:7890 https://example.com

nslookup tests the side router's LAN DNS service on port 53, not the example listener on port 1053. If you have not set up a front-end DNS service, this does not tell you whether mihomo's DNS module is faulty. curl tests an explicit HTTP proxy, which is a different path from transparent proxying.

SymptomCheck firstNext step
Configuration fails to loadIndentation, field types, and core compatibilityRun the configuration check and locate the reported line
Manual proxy cannot connectListening address, LAN firewall, and node reachabilityGet one proxy entry working first
Manual proxy works, but changing the gateway breaks accessForwarding, routing rules, and return pathCheck routes and firewall counters
Some domains failDNS cache, Fake-IP, and local name resolutionCompare where the system and app get DNS answers
IPv4 works, but some connections go directIPv6 default route and routing coverageTest IPv4 and IPv6 paths separately

Enable startup on boot only after verification, then reboot once to confirm that configuration, rule data, and firewall rules are restored in the right order. If testing fails, first restore the device's gateway and DNS to the original main router. Then disable routing through the plugin and restore the relevant firewall configuration; stopping the core alone may leave rules pointing to an inactive interface. Keep one management path that does not rely on the side router to reduce the risk of locking yourself out of the whole network.