平台部署 預計閱讀 15 分鐘

OpenWrt 旁路由部署 mihomo:透明代理設定教學

整理主路由與旁路由的閘道分工、mihomo 核心的檔案路徑與服務設定、透明代理和 DNS 接管重點,以及斷線時的復原方式。

一、網路拓樸:先讓一台裝置經過旁路由

在 OpenWrt 旁路由部署 mihomo,包含三個獨立環節:終端裝置將流量送往旁路由、防火牆將連線導入核心,再由核心依規則選擇出口。只啟動 mihomo,或只修改 DNS,都不代表透明代理已設定完成。

本文採用單網路埠、同網段的 IPv4 測試拓樸,以 OpenWrt 23.05、24.10 系列常見的 firewall4 與 nftables 環境為基礎。以下地址為完整範例,執行前請逐項確認是否符合實際網段。已執行 OpenClash、其他透明代理外掛或自訂策略路由的裝置,不應直接套用這些規則。

裝置地址或設定用途
主路由192.168.10.1/24寬頻撥號、出口 NAT,並繼續提供 DHCP
OpenWrt 旁路由192.168.10.2/24執行 mihomo,接收測試終端流量
旁路由預設閘道192.168.10.1供核心連線至節點及直連上游
測試終端192.168.10.100/24閘道與 DNS 均設為 192.168.10.2
旁路由 LAN 介面br-lan接收同一區域網路內的測試流量

閘道與 DHCP 的分工

  1. 在 OpenWrt 的「網路」→「介面」→「LAN」→「編輯」中設定靜態地址、IPv4 閘道和 DNS,並確認旁路由本身可以連上網路。
  2. 在同一頁面的「DHCP 伺服器」→「一般設定」中勾選「忽略此介面」,避免主路由和旁路由同時派發 IP 位址。
  3. 先只修改測試終端的 IPv4 閘道和 DNS。不要立刻將主路由 DHCP 的閘道選項改成旁路由地址。
  4. 檢查「網路」→「防火牆」中的 LAN 區域政策。本文假設常見的 LAN 輸入、輸出及區域內轉送皆允許;受限制的網路則需另外規劃放行規則。

同網段旁路由的直連回應可能由主路由直接傳回終端,不一定會再次經過旁路由。這種非對稱路徑會影響連線統計與狀態防火牆判斷。初次測試請保留主路由原有的出口 NAT,不要為了讓「路徑對稱」而直接在整個 LAN 上新增位址偽裝。

二、核心檔案:先確認執行檔與基本設定

mihomo 是由 Clash Meta 延續發展的代理核心,並非 OpenWrt 管理外掛。直接執行核心,代表設定目錄、程序守護、訂閱更新及防火牆規則都需由管理員維護。請依 CPU 架構選擇 Linux 執行檔,不要只憑裝置商品名稱判斷。

ubus call system board
uname -m
df -h /overlay
free -m

mkdir -p /etc/mihomo
chmod 700 /etc/mihomo
chmod 755 /usr/bin/mihomo
/usr/bin/mihomo -v

以下指令假設已將解壓縮的核心放在 /usr/bin/mihomo。例如 aarch64 通常對應 ARM64,但 ARMv7、MIPS 裝置還需確認指令集、位元組順序及浮點 ABI。若出現 Exec format error,請優先檢查架構,而非修改防火牆。版本號以本機 mihomo -v 的輸出為準,並保留這段輸出以便後續排查。

設定檔:先用 DIRECT 驗證接管流程

將以下內容儲存為 /etc/mihomo/config.yaml。這是可供測試的直連基礎設定,未設定代理節點,因此不會將流量送往代理伺服器。先確認流量能進入核心,再加入自己的節點和策略組,可將網路問題與訂閱問題分開排查。

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

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: redir-host
  nameserver:
    - udp://223.5.5.5:53
    - udp://119.29.29.29:53

rules:
  - MATCH,DIRECT

7890 是 HTTP/SOCKS 混合代理連接埠,7893 是 TPROXY 連接埠,1053 是 mihomo 的 DNS 監聽連接埠。此處使用 redir-host,避免初次部署時同時引入 Fake-IP 位址池與額外路由。兩個上游 DNS 是範例中的直連解析器,並不代表加密 DNS。

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

請先通過設定檔測試,再啟用流量接管。本文的基礎設定不依賴 GEOIP、GEOSITE 或規則集;若改用訂閱設定,還需確認相關資料檔、規則提供者的下載網址及策略組引用。為桌面用戶端產生的訂閱,也可能包含不適用於路由器的 DNS、TUN 或控制介面設定。

三、程序守護:使用 procd 啟動 mihomo

OpenWrt 使用 procd 管理服務。不要讓長時間執行的程序依附在 SSH 工作階段中,也不要在排程工作中每分鐘重複啟動。以下指令碼負責啟動、異常結束後重新啟動及整合記錄,不負責安裝透明代理規則。

將以下內容儲存為 /etc/init.d/mihomo:

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

START=95
STOP=10
USE_PROCD=1

start_service() {
    /usr/bin/mihomo -t -d /etc/mihomo \
        -f /etc/mihomo/config.yaml || return 1

    procd_open_instance
    procd_set_param command /usr/bin/mihomo \
        -d /etc/mihomo -f /etc/mihomo/config.yaml
    procd_set_param respawn 3600 5 5
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_set_param file /etc/mihomo/config.yaml
    procd_close_instance
}
chmod 755 /etc/init.d/mihomo
/etc/init.d/mihomo enable
/etc/init.d/mihomo start
logread -e mihomo
ss -lnptu | grep -E ':(7890|7893|1053)\b'

若系統沒有 ss,可使用 netstat -lnptu 檢查監聽狀態。若記錄顯示連接埠已被占用,請先找出舊代理程序、重複服務或 DNS 外掛;不要隨意更換連接埠,卻忘了同步修改防火牆。

四、透明代理:TPROXY、策略路由與防火牆的分工

Linux 的 TPROXY 可接收 TCP 和 UDP,並保留原始目標地址。這項功能需要三個部分共同運作:nftables 選取連線、策略路由將帶有標記的封包導向本機,以及 mihomo 的透明監聽接收連線。只設定 tproxy-port,卻沒有前兩項,終端流量不會自動進入核心。

以下範例只比對 192.168.10.100,僅適用於已確認沒有衝突的測試環境。執行前請使用 ip -4 rule show、ip -4 route show table 100 和 nft list ruleset,確認路由表 100、規則優先順序 100 及標記位元 0x1 未被其他服務使用。多 WAN、VPN 與其他代理通常已占用這些資源。

核心模組與轉送設定

請使用相應韌體套件來源,安裝提供 nftables TPROXY 支援的模組;採用 opkg 的韌體通常可檢查 kmod-nft-tproxy。套件必須與執行中的核心版本相符。若出現 Operation not supported 或找不到 TPROXY 表達式,請先處理模組問題。

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv4.conf.br-lan.send_redirects=0

ip -4 rule add priority 100 fwmark 0x1/0x1 lookup 100
ip -4 route add local 0.0.0.0/0 dev lo table 100

關閉 ICMP Redirect 傳送,可避免旁路由建議終端改走同網段的主路由。也別漏掉介面層級的設定。若裝置啟用了嚴格反向路徑過濾,還需檢查 net.ipv4.conf.all.rp_filter 與 net.ipv4.conf.br-lan.rp_filter;在策略路由環境中,嚴格模式可能會丟棄合法封包,請依網路安全需求調整為寬鬆模式或停用。

只接管單一來源地址的 nftables 規則

將以下內容儲存為 /etc/mihomo/test-tproxy.nft。這是獨立的測試表,不應直接貼入 firewall4 的表格 include 檔案。首次載入前請先檢查語法,再實際安裝;若已存在同名表格,請勿重複載入。

table inet mihomo_test {
    chain ingress_proxy {
        type filter hook prerouting priority mangle; policy accept;

        iifname != "br-lan" return
        ip saddr != 192.168.10.100 return

        meta l4proto { tcp, udp } th dport 53 return

        ip daddr {
            0.0.0.0/8,
            10.0.0.0/8,
            100.64.0.0/10,
            127.0.0.0/8,
            169.254.0.0/16,
            172.16.0.0/12,
            192.168.0.0/16,
            224.0.0.0/4,
            240.0.0.0/4
        } return

        meta l4proto { tcp, udp } counter \
            tproxy to :7893 meta mark set 0x1 accept
    }

    chain ingress_dns {
        type nat hook prerouting priority dstnat; policy accept;

        iifname "br-lan" ip saddr 192.168.10.100 \
            meta l4proto { tcp, udp } th dport 53 \
            counter redirect to :1053
    }
}
nft -c -f /etc/mihomo/test-tproxy.nft
nft -f /etc/mihomo/test-tproxy.nft
nft list table inet mihomo_test

DNS 的 53 連接埠會先從透明代理鏈返回,再由後續的 NAT 鏈重新導向至 1053,避免一般 DNS 請求先被 TPROXY 接走。私有地址和多點傳送地址會直接放行,以保留路由器管理、存取區域網路裝置等基本功能;若組織內部另有公網位址範圍或專用路由,也應納入排除清單。

nftables 測試鏈中的 accept 不會略過 firewall4 後續的其他基礎鏈。TPROXY 封包會保留原始目標連接埠,不能只放行「目標連接埠 7893」來取代輸入政策。本文使用允許 LAN 輸入的測試環境;若採用拒絕 LAN 輸入的政策,需在 firewall4 中為來自 LAN、具有相應標記的 TCP/UDP 封包設定受限的輸入放行規則,並另外允許 DNS 1053。

五、DNS 接管:區分傳統解析、加密 DNS 與解析迴圈

即使終端的閘道和 DNS 都指向旁路由,也不代表所有網域解析都會進入 mihomo。上述規則接管的是經過旁路由的 TCP/UDP 53 請求;瀏覽器的安全 DNS、系統的 Private DNS,以及應用程式內建的 DoH,可能透過 443 或 853 連接埠存取其他解析器。

  • 基本測試:暫時關閉測試終端的加密 DNS,明確檢查傳統 DNS 流程,再重新啟用相關功能並確認策略。
  • 連接埠分工:保留 OpenWrt dnsmasq 使用的 53 連接埠,mihomo 使用 1053。不要讓兩個程序搶用相同的監聽地址和連接埠。
  • 上游迴圈:不要將 mihomo 的上游指向 dnsmasq,同時又把 dnsmasq 的上游指回 mihomo,否則會造成解析迴圈或逾時。
  • 節點網域:加入代理節點後,請檢查節點伺服器網域的解析流程。使用 proxy-server-nameserver 可為節點網域指定獨立解析器,避免建立代理連線前還得依賴該代理。
  • 區域網路網域:若需解析 DHCP 主機名稱,應為內部網域設定專用解析策略,並確認不會形成上述迴圈。

範例只依測試終端的來源地址接管 DNS,因此旁路由自行送出的 DNS 不會被同一規則再次攔截。若之後將規則擴大至所有來源地址,必須重新檢查核心上游、節點連線與裝置本機流量的排除條件,不可直接移除來源地址限制。

為什麼 TUN 模式不是多開一個選項就好

mihomo 也支援 TUN,但 TUN 需要相應的核心裝置支援,以及路由與 DNS 接管規劃。auto-route、auto-redirect 等設定可能改變現有路由與 nftables 規則,不能直接與本文的手動 TPROXY 方案疊加。單網路埠旁路由還需確認轉送流量確實進入 TUN,而不只是測試路由器本機請求。

若要使用 TUN,請先撤除本文的測試表與策略路由,再依目前 mihomo 版本的 TUN 設定重新部署。兩種方式的目的相同,都是將需要處理的連線送入核心;排查問題時,維持單一路徑會比同時啟用多個入口更容易找出原因。

六、驗收順序:從直連基礎設定到代理策略

先確認旁路由本身可以連上網路,再驗證終端流量。範例基礎設定的最終規則是 MATCH,DIRECT,出口 IP 與一般直連相同是正常現象,不能據此判定流量未被接管。請搭配計數器和核心記錄判斷。

  1. 設定檢查:執行 mihomo -t,確認沒有 YAML 縮排錯誤、未知策略組或規則提供者載入失敗。
  2. 明確代理檢查:在測試終端執行下方的 curl 指令。此步驟只驗證 7890 入口,不會測試透明接管。
  3. DNS 檢查:向 192.168.10.2 查詢網域,觀察 DNS NAT 計數器是否增加。NAT 鏈計數反映的是新連線比對次數,不等於 DNS 封包數量。
  4. 透明連線檢查:關閉終端上的明確代理,再瀏覽公開網站,檢查 TPROXY 計數器及 logread -e mihomo 中的連線記錄。
  5. 代理出口檢查:匯入有效節點、設定實際策略組並替換最終規則後,重新執行請求。確認記錄中的出口名稱符合預期,再測試大型檔案、影片和 UDP 應用程式。
# 在測試終端執行
curl -I --proxy http://192.168.10.2:7890 https://example.com/
nslookup example.com 192.168.10.2
curl -I --noproxy '*' https://example.com/

# 在旁路由執行
ip -4 rule show
ip -4 route show table 100
nft list table inet mihomo_test
logread -e mihomo

瀏覽器正常但遊戲異常,常見原因包括 UDP 未接管、節點不支援 UDP,或應用程式使用不同的位址家族。小型網頁正常但大型連線停頓,則應進一步檢查 MTU、路徑 MTU 探索及鏈路封包遺失。不要一概將這些問題歸咎於 DNS 故障,也不要在沒有記錄的情況下任意調整核心參數。

測試期間可在「網路」→「防火牆」中暫時關閉軟體與硬體流量卸載,減少快速路徑對觀察結果的干擾。確認方案穩定後,再逐項重新啟用並複測。本文未提供實測吞吐量數據:裝置 CPU、節點通訊協定、加密演算法與出口頻寬都會影響結果,請以本機相同條件下的多次測試為準。

七、斷線復原:先還原閘道,再撤除接管規則

將全網 DHCP 閘道改為旁路由後,旁路由斷電時用戶端不會自動切回主路由。procd 能處理程序異常結束,卻無法修復硬體斷電、錯誤規則或上游斷線。因此,擴大部署範圍前就應準備好復原方案。

單一終端測試的復原步驟

  1. 將測試終端的 IPv4 閘道和 DNS 改回 192.168.10.1,或恢復由主路由 DHCP 自動取得設定。
  2. 在旁路由刪除測試 nftables 表,停止攔截連線。
  3. 只刪除這次建立的策略路由與本機路由,再停止核心。
  4. 重新建立網路連線或清除終端的 DNS 快取,再確認直連已恢復。已建立的代理連線通常需要重新連線。
nft delete table inet mihomo_test
ip -4 rule del priority 100 fwmark 0x1/0x1 lookup 100
ip -4 route del local 0.0.0.0/0 dev lo table 100
/etc/init.d/mihomo stop
/etc/init.d/mihomo disable

只有確認這些項目是本文實驗建立的,才執行刪除指令。不要使用 nft flush ruleset 清除整台裝置的規則,也不要清空整張策略路由表,否則會影響 firewall4、VPN 及其他網路服務。

擴大至全網前的維護清單

  • 保存主路由原有的 DHCP 閘道和 DNS 設定,並記錄租約更新時間;還原選項後,租約尚未更新的終端仍可能繼續使用旁路由。
  • 保留不依賴旁路由的管理入口,例如使用固定地址的維護電腦,以及主路由的管理地址。
  • 更新訂閱時依序「下載至暫存檔 → 測試設定 → 取代檔案 → 重新啟動」,若失敗則保留上一份可用設定。
  • 檢查磁碟空間與記錄量,避免長時間啟用 debug,耗盡有限的快閃記憶體空間。
  • 實際演練一次停止核心及旁路由斷電,確認用戶端的復原步驟可行,而不只是測試正常啟動。

判斷部署是否穩定,不應只看服務是否顯示「執行中」;還需分別驗證閘道、DNS、透明接管、規則出口與故障復原。先以一台終端完成完整流程,再逐步擴大範圍,可大幅縮小每次變更的影響。

下載Clash