先決定部署拓撲:主路由還是旁路由

在 OpenWrt 上執行 Clash 系列核心,目前通常會部署 mihomo。mihomo 延續 Clash Meta 的設定格式與規則能力,可以直接讀取 YAML 設定,並提供 mixed-port、DNS、TUN、規則集與外部控制介面。路由器情境與桌面客戶端不同:桌面端只處理本機流量,路由器還必須辨識來自區域網路裝置的轉送流量,並處理 DNS、策略路由,以及 IPv4 與 IPv6 的回程路徑。

部署前先確認裝置在網路中的角色。主路由方案由 OpenWrt 負責撥號、DHCP、DNS 與預設閘道,資料路徑清楚,透明代理規則也最容易統一管理。旁路由方案保留現有主路由,OpenWrt 作為同一個區域網路中的第二台三層裝置,只接管指定終端或由 DHCP 分配的流量。旁路由需要修改的地方較少,但閘道、DNS 與回程路徑必須逐項核對。

主路由拓撲

  • 光纖數據機設為橋接模式時,由 OpenWrt 的 WAN 埠撥號;若光纖數據機採路由模式,OpenWrt WAN 埠則從上游網路取得位址。
  • 區域網路終端的預設閘道指向 OpenWrt,例如 192.168.10.1
  • DHCP 與 DNS 都由 OpenWrt 提供,終端不需要另外設定代理位址。
  • TUN 或 TProxy 規則可以涵蓋整個 LAN,也可以依來源位址、MAC 對應的固定租約或目標網段設定繞過。

旁路由拓撲

  • 主路由可以使用 192.168.1.1,旁路由則設定為同一網段的固定位址 192.168.1.2
  • 旁路由的預設閘道與上游 DNS 先指向主路由,避免自身更新訂閱時失去對外連線。
  • 需要代理的終端將閘道與 DNS 指向 192.168.1.2;其他終端繼續使用主路由。
  • 如果主路由的 DHCP 支援下發自訂閘道,可以統一下發旁路由位址。否則應在終端手動設定,或謹慎調整 DHCP 服務範圍。

硬體、架構與儲存空間

核心能否啟動取決於架構與執行函式庫是否相容;實際吞吐量則會受到 CPU 單核心效能、加密演算法、規則規模、連線數與網路驅動程式共同影響。若只供兩三台終端使用、頻寬約 100 Mbps,雙核心 ARM64 搭配 256 MB 記憶體即可完成基本規則代理。若目標是超過 500 Mbps,並同時啟用 TUN、DNS fake-ip 與較大的規則集,建議從四核心 ARM64、512 MB 記憶體起步。千兆線路還要檢查裝置的 NAT、網卡中斷與 CPU 軟中斷使用率。

一份包含數萬條規則與多個 rule-provider 的設定,mihomo 常見的常駐記憶體用量約為 80 至 180 MB;啟用大量網域規則、連線追蹤與面板查詢後還會繼續增加。OpenWrt 本身以及 dnsmasq、firewall4、日誌服務也需要記憶體,因此 128 MB 裝置通常只適合精簡設定。快閃記憶體方面,核心檔案、GeoIP、GeoSite、規則集與暫存下載檔案合計預留 100 MB 以上會比較穩妥。

確認 CPU 架構

透過 SSH 登入 OpenWrt,先讀取系統報告,不要只根據路由器商品名稱選擇執行檔。

uname -m
ubus call system board
cat /etc/openwrt_release

x86_64 對應 AMD64,aarch64 對應 ARM64。部分舊裝置會回傳 armv7lmipsmipsel。MIPS 另有大小端與浮點實作的區分,下載前必須逐項確認是否符合發佈檔案的架構標記。若執行檔架構錯誤,執行時通常會直接回傳 Exec format error

檢查 TUN 與透明代理模組

ls -l /dev/net/tun
opkg list-installed | grep -E 'kmod-tun|firewall4|nftables'
nft list ruleset | head

TUN 模式至少需要核心支援 TUN,OpenWrt 常用的套件為 kmod-tun。以 nftables 為基礎的 TProxy 方案還需要目前韌體提供相應的透明代理模組,例如 kmod-nft-tproxy。套件名稱會隨 OpenWrt 分支與目標平台而異,應以目前裝置的套件來源為準,不要混裝其他版本套件庫中的核心模組。

放置 mihomo 核心與最小設定

獨立部署時,建議將可執行檔放在 /usr/bin/mihomo,設定與執行資料放在 /etc/mihomo。對於快閃記憶體空間緊張的裝置,也可以將規則集目錄放到已掛載的 USB 儲存裝置中,但啟動腳本必須等待掛載完成。以下指令假設執行檔已透過 SCP 上傳至 /tmp/mihomo

mkdir -p /etc/mihomo
install -m 0755 /tmp/mihomo /usr/bin/mihomo
/usr/bin/mihomo -v

先建立一份能夠啟動的 /etc/mihomo/config.yaml。代理節點與策略群組應來自實際服務設定,以下僅展示路由器相關的監聽、控制介面與 DNS 結構。

mixed-port: 7890
redir-port: 7892
tproxy-port: 7893
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
ipv6: false

external-controller: 127.0.0.1:9090
secret: "change-this-controller-secret"

profile:
  store-selected: true
  store-fake-ip: true

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "localhost.ptlogin2.qq.com"
  nameserver:
    - https://1.1.1.1/dns-query
    - https://8.8.8.8/dns-query

proxies: []
proxy-groups:
  - name: PROXY
    type: select
    proxies:
      - DIRECT

rules:
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

allow-lan: true 允許區域網路終端存取代理監聽埠,因此 OpenWrt 防火牆應只允許受信任的 LAN 區域存取 7890、7892、7893 與 DNS 監聽埠。外部控制介面的範例僅繫結至 127.0.0.1:9090;如果面板部署在另一台裝置上,則需要改為區域網路監聽位址,並設定高強度的隨機 secret 與明確的防火牆來源限制。

儲存後先進行語法驗證,再以前景模式啟動。-d 用於指定執行目錄,mihomo 會從該目錄讀取 config.yaml 並存放快取資料。

/usr/bin/mihomo -t -d /etc/mihomo
/usr/bin/mihomo -d /etc/mihomo

看到設定載入完成後,在另一個 SSH 工作階段中檢查埠:

ss -lntup | grep -E '7890|7892|7893|9090|1053'
logread -f

TUN 與 TProxy 的取捨

TUN 與 TProxy 都能讓終端無感接入,但處理路徑不同。TUN 由 mihomo 建立虛擬網卡,將進入虛擬介面的 IP 流量交給使用者空間協定堆疊。TProxy 依靠防火牆標記、策略路由與透明通訊端,將 TCP 或 UDP 流量送至指定監聽埠,同時保留原始目標位址。兩者都不是簡單開啟一個設定選項;路由器還需要配合目前 OpenWrt 的轉送與防火牆架構。

TUN:部署路徑較集中

mihomo 的 TUN 設定可以直接寫入 YAML。OpenWrt 上通常使用 system 堆疊,搭配自動路由與自動識別出口介面:

tun:
  enable: true
  stack: system
  device: mihomo
  auto-route: true
  auto-detect-interface: true
  strict-route: true
  dns-hijack:
    - any:53
  mtu: 1500

TUN 的優點是規則主要集中在核心設定中,TCP 與 UDP 的處理方式一致,對遊戲主機、電視與不支援手動代理的應用程式更友善。代價是資料會進入使用者空間的虛擬網卡,低效能路由器上的 CPU 使用率可能高於針對性設定的 TProxy。若部分網站逾時但小封包正常,可以將 MTU 從 1500 逐步降至 1480、1460 或 1400 進行測試,但最終值應根據 PPPoE、通道與上游網路決定。

TProxy:控制粒度較細

TProxy 更適合熟悉 nftables、策略路由與 OpenWrt firewall4 的維護者。典型資料路徑包括:在 prerouting 鏈篩選 LAN 流量、略過區域網路與保留位址、為目標連線設定防火牆標記、使用 ip rule 將帶有標記的流量送入本機路由表,再轉至 mihomo 的 tproxy-port: 7893。UDP 也必須單獨納入規則。

OpenWrt 22.03 之後預設使用 firewall4 與 nftables。舊教學中的 iptables 指令、鏈名稱與啟動時機不能直接套用到 nftables 環境。手動撰寫 TProxy 規則時,還要避免重複處理路由器自身發起的訂閱下載、NTP、套件更新與節點連線,否則可能形成代理迴圈。實際部署較適合使用與目前 OpenWrt 版本相符的管理元件產生規則,再透過 nft list ruleset 檢查結果。

選擇依據

  • 需要快速涵蓋 TCP、UDP 與多數區域網路裝置:優先評估 TUN。
  • 裝置 CPU 效能較弱,但維護者能精確管理 nftables:可以評估 TProxy。
  • 只代理瀏覽器與少量電腦:先使用 mixed-port: 7890,不必立即增加透明代理的複雜度。
  • 需要依終端分流:兩種方案都可以依來源 IP 控制,前提是 DHCP 為終端分配固定位址。
  • 網路啟用 IPv6:必須同步設計 IPv6 DNS、路由與防火牆策略,不能只處理 IPv4 後便假設所有連線都會經過代理。

訂閱更新:下載、驗證設定語法、原子替換

路由器上的訂閱不是把 URL 填入圖形介面就結束。更新流程至少應包含下載至暫存檔、測試 YAML、替換正式設定與重新載入服務四個步驟。直接覆寫正在使用的 config.yaml,一旦下載中斷或伺服器回傳 HTML 錯誤頁面,下次重新啟動就可能無法載入設定。

以下腳本使用 uclient-fetch 下載完整設定。訂閱位址應寫入只有 root 可讀取的檔案或腳本,不應輸出至公開日誌。將腳本儲存為 /usr/bin/update-mihomo,並執行 chmod 700 /usr/bin/update-mihomo

#!/bin/sh
set -eu

CONFIG_DIR="/etc/mihomo"
TEMP_FILE="/tmp/mihomo-config.yaml"
SUB_URL="https://subscription.example/path"

uclient-fetch -q -O "$TEMP_FILE" "$SUB_URL"

/usr/bin/mihomo -t -f "$TEMP_FILE"

cp "$CONFIG_DIR/config.yaml" "$CONFIG_DIR/config.yaml.bak"
mv "$TEMP_FILE" "$CONFIG_DIR/config.yaml"

/etc/init.d/mihomo reload || /etc/init.d/mihomo restart

mihomo -t -f 會解析指定的設定檔,可以攔截 YAML 縮排、欄位結構與部分規則錯誤。它無法確認所有遠端節點都能連線,因此更新後仍要查看服務日誌與策略群組狀態。若訂閱依賴特定 User-Agent 或重新導向,可依服務提供者的要求調整下載指令。

確認手動更新穩定後,再寫入 cron。例如每天 04:17 更新一次:

17 4 * * * /usr/bin/update-mihomo >> /tmp/mihomo-update.log 2>&1

OpenWrt 的 /tmp 位於記憶體檔案系統中,更新日誌會在重新啟動後清空,適合用來避免長期寫入快閃記憶體。排除故障階段要限制日誌大小;長期執行時不宜讓除錯等級的日誌持續寫入快閃記憶體。

使用 procd 設定開機自動啟動

OpenWrt 服務應交由 procd 管理,而不是把背景指令直接追加到 /etc/rc.local。procd 可以追蹤程序、在異常結束後重新啟動,並統一處理啟動、停止與重新載入。建立 /etc/init.d/mihomo

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

START=99
STOP=10
USE_PROCD=1

start_service() {
  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
}

reload_service() {
  procd_send_signal mihomo HUP
}

service_triggers() {
  procd_add_reload_trigger "network"
}

授予執行權限並啟用服務:

chmod 755 /etc/init.d/mihomo
/etc/init.d/mihomo enable
/etc/init.d/mihomo start
/etc/init.d/mihomo status
logread -e mihomo

respawn 3600 5 5 表示在觀察視窗內處理異常結束並延遲重新啟動,避免程序頻繁崩潰時形成緊密迴圈。如果設定中的遠端規則集必須透過網路下載,首次啟動可能會受到 WAN 尚未就緒的影響。可以預先將必要的規則檔案放入本機,或讓更新工作在網路連通後單獨執行,不要依賴每次啟動都即時取得所有遠端資源。

分流、安全邊界與常見故障

保留位址必須直連

透明代理規則應略過本機回環、區域網路、群播與保留位址,例如 127.0.0.0/810.0.0.0/8172.16.0.0/12192.168.0.0/16224.0.0.0/4。如果家庭網路使用多個私有網段,還要明確哪些網段可透過靜態路由互相存取。盲目代理 NAS、印表機與管理頁面會造成存取繞路,甚至讓路由器後台無法開啟。

控制介面只開放給管理網路

9090 控制介面可以切換策略、讀取連線與修改執行狀態,預設應繫結至回環位址。若需要從 LAN 使用面板,可以繫結至路由器的 LAN 位址,例如 192.168.10.1:9090,同時設定 secret,再由防火牆限制來源。代理埠也只應在 LAN 防火牆區域開放,不應接受來自 WAN 的連線。

核心啟動後終端仍無法上網

  1. 在路由器上執行 ip route,確認預設路由指向實際的 WAN。
  2. 執行 nslookup openwrt.org 127.0.0.1,確認基本 DNS 正常。
  3. 讓電腦手動連線至路由器的 7890 埠,排除節點與訂閱問題。
  4. 執行 nft list ruleset,確認透明代理鏈確實存在且計數器持續增加。
  5. 檢查終端的閘道與 DNS 是否都指向規劃中的主路由或旁路由位址。

存取中國大陸網站正常,部分境外網站逾時

先檢查策略群組是否選用了可用節點,再比較網域解析結果與規則命中情況。若只有大型頁面、上傳或影片連線失敗,請測試 MTU。PPPoE 連線通常比乙太網路少 8 個位元組,疊加其他通道後還會下降。可以逐步減小封包長度觀察,但不要將所有故障都歸因於 MTU。

路由器可以存取,區域網路終端無法存取

這種情況通常表示 mihomo 本身的對外連線正常,但 LAN 轉送路徑沒有進入透明代理。主路由請檢查 LAN 到 WAN 的轉送與透明代理規則;旁路由請檢查 net.ipv4.ip_forward、防火牆區域與終端閘道。如果終端仍以主路由作為閘道,流量自然不會經過旁路由。

重新啟動後服務存在但規則未生效

服務啟動與防火牆載入之間存在順序差異。如果 TProxy 規則由獨立腳本產生,應接入 firewall4 的 include 或熱插拔機制,並確保重複執行不會建立重複鏈。如果使用 TUN 的自動路由,請檢查啟動日誌中是否存在介面建立、路由表或權限錯誤,同時確認 /dev/net/tun 在啟動時已可用。

部署驗收清單

路由器直接執行核心的重點,不是讓程序顯示為「執行中」,而是讓整條資料路徑可預測、可復原。在正式接管家庭網路前,可以依照以下清單逐項驗收:

  • 核心架構與裝置一致,mihomo -v 能正常回傳版本資訊。
  • mihomo -t 能通過設定檢查,訂閱更新失敗時不會覆蓋現有設定。
  • 7890 一般代理埠已單獨驗證,節點與策略群組可以建立連線。
  • 主路由或旁路由的閘道、DHCP、DNS 職責明確,沒有兩個 DHCP 服務互相衝突。
  • TUN 或 TProxy 只啟用一種主要接管路徑,避免對同一連線重複重新導向。
  • 區域網路、路由器管理位址、群播與必要的保留網段都已繞過代理。
  • 控制介面已設定存取金鑰,並由防火牆限制至受信任的管理網路。
  • 重新啟動裝置後,WAN、時間、DNS、mihomo 與透明代理規則依序恢復。
  • 分別測試網頁、影片、UDP 應用程式、區域網路 NAS 與印表機存取。
  • 測速時記錄 CPU、記憶體、軟中斷與溫度,而不是只看單次頻寬結果。

首次部署建議先從一般 mixed-port 與單台測試終端開始,再擴充至 TUN 或 TProxy。主路由方案的路徑較直接,適合統一接管;旁路由方案便於逐步遷移,適合先涵蓋少量裝置。無論選擇哪種拓撲,設定語法、DNS 路徑、防火牆規則與開機復原都應能分別驗證。