CH-01
策略組類型與實戰
策略組(proxy-groups)是分流規則與具體節點之間的中間層:規則命中後交給策略組,策略組再依自身邏輯決定實際走哪個節點。理解每種類型的判定機制,是把設定從「能用」改到「好用」的第一步。mihomo 支援的常用類型有五種,判定邏輯差異很大,選錯類型是延遲抖動與頻繁斷線的常見根源。
五種類型的判定邏輯
url-test 的三個關鍵參數
url 是測速目標,通常選一個回傳 204 空回應的位址,流量開銷可以忽略;interval 是測速週期(秒),太短會放大訂閱節點的測速流量,太長則節點劣化後遲遲不切換,日常取 300 左右比較平衡;tolerance 是切換容差(毫秒)——只有新節點比目前節點快出這個差值才會切換。不設 tolerance 時,兩個延遲 60ms 與 65ms 的節點會來回跳動,每次切換都可能中斷正在傳輸的連線,建議至少設為 50。
proxy-groups:
- name: 自動測速
type: url-test
proxies: [HK-01, HK-02, JP-01]
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
- name: 故障轉移
type: fallback
proxies: [主力-HK, 備用-JP, 兜底-US]
url: https://www.gstatic.com/generate_204
interval: 180
- name: 均衡下載
type: load-balance
strategy: consistent-hashing
proxies: [SG-01, SG-02, SG-03]
load-balance 的兩種 strategy
consistent-hashing 依目標位址雜湊,同一網站的請求固定落在同一節點,兼顧分攤與工作階段穩定,是預設建議;round-robin 逐連線輪替節點,分攤最徹底,但同一網站的不同請求會從不同 IP 發出,遇到工作階段驗證嚴格的服務容易被登出,只建議用在純下載類分組。
分組的組合套路
實戰裡通常做兩層:底層建「HK 自動」「JP 自動」等依地區分的 url-test 組,上層建一個 select 組把這些地區組與「手動選擇」並列收進來,規則統一指向上層 select 組。這樣日常交給自動測速,需要固定地區時在客戶端面板一鍵切到對應地區組,不必改任何規則。策略組還可以巢狀引用其他策略組(proxies 清單裡寫組名即可),但不要造出循環引用——核心會拒絕載入這樣的設定。三種自動類型的更細對比與參數實驗,可以參考部落格的 策略組類型對比 一文;不知道該把哪些節點收進組,先看 節點挑選的四個維度。
提示
訂閱提供的節點名會變(如「HK-01」改名「香港 01」),proxies 裡寫死節點名的分組會隨之失效。改用 include-all: true 搭配 filter: "(?i)hk|港" 依正規表達式收節點,訂閱更新後分組自動跟進,不必再手動維護清單。
可用性判定與 lazy 惰性測速
url-test 與 fallback 都依賴健康檢查來判斷節點是否「可用」,這背後是核心對 url 目標發起的週期性探測請求。預設情況下,只要一個策略群組被建立,核心就會持續對群組內全部節點測速——即便這個群組當前根本沒被規則命中。節點數量多、訂閱巢狀層級深時,這些後台探測會累積成一筆可觀的固定流量,甚至拖慢核心啟動。給 url-test 群組加上 lazy: true 可以開啟惰性模式:只有當群組真正被選中並承載流量時才觸發測速,長期閒置的備用地區群組不再空轉,這在收進十幾個地區分組的大型設定裡節流效果很明顯。需要注意的是,lazy 模式下節點的延遲數字要等第一次被使用後才出現,用戶端面板初始顯示為空是正常現象,並非節點失效。
測速目標該選誰
url 目標的選擇常被忽視,卻直接影響測速結果的可信度。理想的目標應滿足三個條件:回應體極小(最好是 204 空回應,避免測速本身消耗頻寬)、全球部署且不針對代理流量做特殊處理、穩定可達不會因區域封鎖而全組判失敗。常用的 https://www.gstatic.com/generate_204 與 http://cp.cloudflare.com/generate_204 都符合。切忌用某個具體網站首頁當測速目標——它可能因 CDN 就近調度讓不同節點測出的延遲失去可比性,也可能因該站臨時故障導致整組節點被誤判為不可用而集體切走。若發現某地區節點延遲數字異常一致或整齊地測不出,先懷疑測速目標在該地區被干擾,換一個再看。
CH-02
規則集訂閱化管理
把幾千條分流規則直接堆在 rules 段,是設定難以維護的主要原因:訂閱一更新,手動加的規則就被覆蓋掉;想調整一類網站的走向,要在長清單裡逐條找。rule-providers 把規則依用途拆成獨立檔案、以訂閱方式引入,rules 段只留十幾行「骨架」,可讀性與可維護性都會明顯改善。
rule-providers 的欄位含義
type 取 http(遠端訂閱,依 interval 自動更新)或 file(本地檔案,自行維護);behavior 宣告這份規則檔案的內容形態——domain 是純網域清單,ipcidr 是純 IP 段清單,classical 則允許混寫各種規則類型,通用性最強但比對開銷略高;format 支援 yaml、text 與 mihomo 的二進位 mrs 格式,mrs 體積小、載入快,大規則集優先選它;path 是本地快取路徑;interval 是自動更新週期(秒),規則集變動不頻繁,86400(一天)已足夠。
rule-providers:
streaming:
type: http
behavior: classical
format: yaml
url: https://example.com/rules/streaming.yaml
path: ./rule-sets/streaming.yaml
interval: 86400
cn-ip:
type: http
behavior: ipcidr
format: mrs
url: https://example.com/rules/cn-ip.mrs
path: ./rule-sets/cn-ip.mrs
interval: 86400
rules:
- RULE-SET,streaming,串流媒體分組
- RULE-SET,cn-ip,DIRECT
- GEOIP,CN,DIRECT
- MATCH,自動測速
規則順序與兜底
rules 段自上而下比對、命中即停,順序就是優先順序:個人的例外規則放最前,大規則集居中,GEOIP,CN,DIRECT 之類的地理規則靠後,最後一行必須是 MATCH 兜底——沒有兜底時,未命中的流量走向取決於核心預設行為,排查問題時會非常困惑。另一個常見坑是把 IP 類規則(GEOIP/IP-CIDR)放在網域規則前面:IP 規則會觸發一次 DNS 解析來取得目標 IP,既拖慢比對又可能產生不期望的解析行為,如確有需要且不想觸發解析,替規則加上 no-resolve 參數。
GeoIP 與 GeoSite 資料庫
GEOIP,CN 依賴核心載入的 GeoIP 資料庫,GEOSITE 規則依賴 GeoSite 資料庫,兩者都會隨時間過時:資料庫太舊時,一些實際位於中國大陸的 IP 會被判成境外而錯誤走代理。多數持續維護的客戶端在設定裡提供「更新 Geo 資料庫」入口,建議每一兩個月手動點一次;mihomo 也支援在設定裡宣告 geo-auto-update: true 與更新週期,讓核心自行拉取。資料庫檔案存放在客戶端的工作目錄,與設定檔同層,更新後需重新載入設定才會生效。
注意
RULE-SET 引用的名稱必須與 rule-providers 裡定義的鍵完全一致,且區分大小寫;引用了未定義的規則集,整份設定會載入失敗,客戶端日誌裡會給出具體的名稱,報錯後先核對這一點。
CH-03
DNS 設定最佳化
分流的準確性一半取決於 DNS:網域解析被污染,GEOIP 規則拿到的就是錯誤的 IP,分流隨之全盤出錯;解析走了不合適的伺服器,還會拿到遠離目前線路的 CDN 節點,表現為「節點延遲不高但網頁就是慢」。dns 段是設定裡最值得花時間調整的一節。
enhanced-mode:redir-host 與 fake-ip
作為代理客戶端的預設選擇,fake-ip 整體體驗更好,尤其在 TUN 模式下幾乎是標配(見第四章)。fake-ip-filter 用來列出必須拿到真實 IP 的網域:區域網路裝置發現、NTP 時間同步、部分遊戲平台的連通性偵測等情境拿到假 IP 會運作異常,常見寫法如下例。切換 enhanced-mode 後,建議清空一次客戶端的 DNS 快取(多數客戶端在設定裡提供按鈕,或直接重新啟動核心),避免新舊映射混用。
dns:
enable: true
listen: 0.0.0.0:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- "*.lan"
- "+.local"
- time.windows.com
- "+.ntp.org"
nameserver:
- https://223.5.5.5/dns-query
- https://doh.pub/dns-query
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
geoip-code: CN
nameserver、fallback 與分組解析
nameserver 是主解析組,建議填中國大陸可直連的 DoH 伺服器,確保中國大陸網域解析快且拿到鄰近 CDN;fallback 是驗證組,填中國大陸以外的 DoH:核心會把兩組結果做比對,當 nameserver 回傳的 IP 落在 fallback-filter 宣告的範圍(如 geoip-code 為 CN)之外時,判定可能被污染,改用 fallback 的結果。這套機制兼顧了中國大陸解析速度與境外解析純淨度。更進一步可以用 nameserver-policy 依網域指派解析伺服器,例如把某個規則集裡的網域全部交給境外 DoH,精度最高但設定量也大,依需求使用即可。
解析協定的選擇
DNS 伺服器位址支援多種協定前綴:純 UDP(223.5.5.5)最快但明文可被竄改;DoT(tls://)與 DoH(https://)加密傳輸,抗污染能力強,建議所有伺服器都寫成 DoH 形式。注意 DoH 伺服器網域本身也需要解析,核心用 default-nameserver(應填純 IP 的 UDP 伺服器)完成這一步引導,忘記寫會導致啟動時全部解析失敗。懷疑降速與 DNS 有關時,可依 三層定位法 的本地設定層逐項排除;更多解析類問題收錄在 常見問題 的故障排查分類。
常見的 DNS 自鎖與解析迴圈
DNS 設定最隱蔽的坑是「自鎖」:核心要解析 DoH 伺服器的網域,而解析這一步又依賴尚未就緒的 DNS 服務,形成雞生蛋的死結,表現為用戶端啟動後所有網站都打不開、日誌裡刷滿解析逾時。規避辦法是把 default-nameserver 填成純 IP 的 UDP 伺服器(如 223.5.5.5 與 119.29.29.29),它專門負責引導階段解析那些寫成網域的 DoH 位址,只應填 IP、絕不能再填網域。另一類問題是解析迴圈:開啟 TUN 且 dns-hijack 生效後,核心自己發出的 DoH 查詢若又被虛擬網卡接回核心,就會打轉,通常靠 auto-detect-interface 正確識別實體出口來避免,手動指定出口網卡的場景要額外確認 DNS 查詢走的是真實鏈路而非代理鏈路。
proxy-server-nameserver 的作用
還有一個容易漏設的欄位是 proxy-server-nameserver:它專門用來解析各個代理節點自身的伺服器網域。如果訂閱裡的節點位址寫成網域(而非 IP),核心在撥號到節點前必須先解析這個網域——這一步若混用了普通 nameserver 的分流邏輯,可能因為把節點網域誤判為需要代理而再次陷入迴圈。把節點伺服器網域的解析單獨交給 proxy-server-nameserver(通常指向可直連的境內 DoH),既保證解析速度,也讓這條解析路徑與業務流量的解析徹底隔離,是使用網域型節點時的推薦做法。
CH-04
TUN 與 Fake-IP
系統代理只對「尊重代理設定」的應用程式生效,命令列工具、遊戲客戶端、部分 IM 的 UDP 流量都會繞開它。TUN 模式在系統裡建立一塊虛擬網卡,把全部三層流量接進核心處理,是覆蓋範圍最完整的接管方式,也是處理 UDP 與非常規連接埠流量的正解。
核心參數
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
auto-route 自動寫入路由表,把預設路由指向虛擬網卡,關掉就需要手動設路由,一般保持開啟;auto-detect-interface 讓核心自動識別真實實體出口網卡,避免代理流量迴圈打轉,多網卡裝置(有線+無線、虛擬機器網卡)必須開啟;dns-hijack 把發往 53 連接埠的明文 DNS 請求劫持給核心 DNS 處理,搭配 fake-ip 才能確保 TUN 下的網域分流準確——這也是為什麼 TUN 與 Fake-IP 幾乎總是成對出現:應用程式透過虛擬網卡發出的 DNS 查詢被核心接住,立即回覆假 IP,後續連線命中假 IP 段時核心反查出原始網域,依網域規則精確分流,全程不依賴系統解析器。
stack 三種協定堆疊
各平台的授權差異
TUN 需要建立網卡的系統權限,各平台路徑不同:Windows 上以系統管理員身份執行客戶端,或在客戶端設定裡安裝系統服務,由服務代持權限,日常免提權;macOS 首次啟用會彈出系統延伸/網路延伸授權,到「系統設定 → 隱私權與安全性」放行後重新開啟;Linux 需要 root 或給核心二進位檔授予 cap_net_admin 能力;Android 不叫 TUN 而是 VpnService,首次開啟彈出 VPN 連線授權,同意即可,但廠商省電策略常會終止背景服務導致斷線,需要把客戶端加入省電白名單,具體路徑見 Android 端使用要點;iOS 客戶端(如 App Store 版 Clash Plus)基於 Network Extension,授權流程由系統統一接管。各平台客戶端的取得方式見 下載頁。
注意
TUN 與系統代理同時開啟並不衝突,但排查問題時建議只保留一種接管方式,否則難以判斷流量走的是哪條路徑。關閉 TUN 後若網路異常,多為路由表殘留,重新啟動一次核心或系統網路即可恢復。
CH-05
網域嗅探
並非所有連線都天然攜帶網域:應用程式自帶 DNS(如瀏覽器內建 DoH)時,核心看到的只是一個目標 IP,網域規則全部失配,只能退化到 GEOIP 判斷;fake-ip-filter 放行的網域同樣以真實 IP 形態出現。網域嗅探(sniffer)從流量本身還原網域——HTTP 請求的 Host 標頭、TLS 交握的 SNI 欄位、QUIC 初始封包裡都帶有明文網域,核心讀出後用它重寫連線元資料,再走一遍網域規則,把這類「只見 IP」的連線重新納入精確分流。
設定範例
sniffer:
enable: true
sniff:
HTTP:
ports: [80, 8080-8880]
override-destination: true
TLS:
ports: [443, 8443]
QUIC:
ports: [443]
skip-domain:
- "+.push.apple.com"
force-domain:
- "+.v2ex.com"
sniff 下依協定宣告嗅探的連接埠範圍,三種協定覆蓋了絕大多數情境;override-destination 決定是否用嗅探出的網域覆蓋連線的目標位址,開啟後分流與日誌都以網域呈現;skip-domain 排除嗅探後反而出問題的網域——個別推播服務、憑證驗證嚴格的客戶端在目標被改寫後會連線失敗,遇到時把對應網域加進來;force-domain 則相反,強制對命中的網域執行覆蓋。
何時需要、何時不需要
已啟用 fake-ip 且應用程式都透過核心 DNS 解析時,連線本身就帶網域,嗅探的增益有限;真正受益的是 TUN 下自帶 DoH 的瀏覽器流量、繞過系統解析的行動應用程式,以及 redir-host 模式下的分流精度補償。嗅探會對每條新連線的首包做一次解析,CPU 開銷很小,常開無礙;但若某類應用程式啟用嗅探後出現異常斷線,優先懷疑目標覆蓋行為,用 skip-domain 定點排除,而非整體關閉。日誌(見第七章)裡連線條目從 IP 變成網域,就說明嗅探已生效。
CH-06
本地覆寫與多訂閱合併
直接編輯訂閱下發的設定檔是最常見的維護誤區:訂閱一刷新,所有手動修改全部丟失。正確做法是把「訂閱提供的節點」與「自己維護的規則、DNS、策略組」分離——訂閱負責節點,本地覆寫負責其餘一切,更新訂閱只更新節點,個人設定永遠不動。
客戶端層的覆寫機制
持續維護的桌面客戶端普遍內建覆寫能力:Clash Verge Rev 提供「全域擴充設定」與腳本覆寫,可以用 YAML 合併或 JavaScript 函式在訂閱設定落地前改寫任意欄位;Clash Plus、FlClash 也提供各自的覆寫/混合入口。以 Verge Rev 的 Merge 覆寫為例,前綴語意為:prepend- 插到原清單最前,append- 追加到最後,直接寫欄位名則整段替換。
prepend-rules:
- DOMAIN-SUFFIX,internal.example.com,DIRECT
append-rules:
- MATCH,自動測速
dns:
enable: true
enhanced-mode: fake-ip
上例把一條內網直連規則插到所有訂閱規則之前(確保優先命中),補一條兜底規則,並整體替換 dns 段。規則類覆寫優先用 prepend,因為 rules 是依順序比對,插在前面才能確保生效。
核心層的 proxy-providers 合併多訂閱
同時持有多家訂閱時,不必在客戶端裡來回切換設定,用 proxy-providers 把多個訂閱作為節點來源統一收進一份設定:
proxy-providers:
sub-a:
type: http
url: https://example.com/sub-a
path: ./providers/sub-a.yaml
interval: 43200
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
sub-b:
type: http
url: https://example.com/sub-b
path: ./providers/sub-b.yaml
interval: 43200
proxy-groups:
- name: 全部節點
type: select
use: [sub-a, sub-b]
- name: 香港自動
type: url-test
use: [sub-a, sub-b]
filter: "(?i)hk|香港"
url: https://www.gstatic.com/generate_204
interval: 300
策略組用 use 引用 provider 而非逐個寫節點名,搭配 filter 正規表達式篩選,兩家訂閱的香港節點會自動彙入同一個測速組;訂閱各自依 interval 更新,互不影響。health-check 讓 provider 內的節點獨立保活探測,避免失效節點滯留在分組裡。兩家訂閱出現同名節點時核心會回報衝突,可用 provider 的 override.additional-prefix 給節點名統一加前綴區分。
建議
把覆寫檔案納入自己的備份習慣:換機、重裝或更換客戶端時,節點靠訂閱連結即可還原,真正不可再生的是這些本地規則與 DNS 調校。客戶端停止更新需要遷移時,覆寫檔案同樣是最先要匯出的資產,遷移路線見部落格 停更遷移方案。
CH-07
外部控制面板
mihomo 核心暴露一套 RESTful 控制介面(通稱 external controller),客戶端面板本身就是它的消費者;把介面開啟後,還可以接入獨立的 Web 面板,或直接用命令列查詢與操控核心——遠端管理路由器上的核心、寫自動化腳本都靠它。
開啟介面
external-controller: 127.0.0.1:9090
secret: "your-secret"
external-ui: ./ui
external-ui-url: https://example.com/panel.zip
external-controller 宣告監聽位址:只在本機使用寫 127.0.0.1:9090;要從區域網路其他裝置存取(如管理路由器)才改成 0.0.0.0:9090,此時 secret 必須設為高強度密碼——介面能讀取全部連線記錄並切換節點,裸奔等於把控制權交給區域網路裡的任何人。external-ui 指向一個靜態面板目錄,核心會在同連接埠的 /ui 路徑下代管它;external-ui-url 則讓核心自動下載面板壓縮檔解壓到該目錄,省去手動部署。
常用介面速查
用命令列驗證介面是否可用,並做一次手動切換節點:
curl -H "Authorization: Bearer your-secret" \
http://127.0.0.1:9090/proxies
curl -X PUT \
-H "Authorization: Bearer your-secret" \
-H "Content-Type: application/json" \
-d '{"name":"香港自動"}' \
http://127.0.0.1:9090/proxies/手動選擇
用連線視圖排查分流
這套介面最實用的日常價值是排查「某個網站到底走了哪條規則」:打開面板的連線頁(或 GET /connections),依網域過濾,每條連線都標註了命中的規則與最終出口節點。分流不符合預期時,先看這裡確認是規則寫錯、順序不對,還是 DNS/嗅探層沒拿到網域(條目顯示為純 IP 即是訊號,回到第三、五章處理),比盲目改設定高效得多。日誌等級可在設定裡用 log-level: info 調整,排查階段暫時改為 debug,定位完記得改回,避免日誌洗版影響效能。
延伸
本頁各章範例可自由組合進同一份覆寫。仍未覆蓋的問題,先查 常見問題 的分類索引;完全從零開始的讀者,回到 快速上手 依主線走一遍,再回本頁逐章加深。
介面安全的幾條底線
外部控制介面的能力等同於對核心的完全控制,因此暴露它必須謹慎。第一條底線是監聽位址:除非確有遠端管理需求,一律用 127.0.0.1 只對本機開放,絕不輕易改成 0.0.0.0;確需區域網路存取時,也應透過防火牆把來源限制到具體的管理機 IP,而不是對整個網段敞開。第二條是口令:一旦監聽位址不是回環,secret 必須設為足夠長的隨機串,並且不要在部落格、截圖、設定分享裡連同真實口令一起貼出——很多人排查問題時隨手把整份設定發到論壇,secret 就這樣洩露。第三條是絕不把控制連接埠直接映射到公網:軟路由使用者尤其容易為了「在外面也能管」而做連接埠轉發,這等於把核心控制台掛到網際網路上,正確做法是透過 VPN 或 SSH 隧道回到內網再存取。
面板與核心的版本匹配
獨立 Web 面板(如各類基於該介面的開源面板)與核心之間存在介面版本差異:核心迭代時偶爾會調整介面欄位或新增鑑權要求,過舊的面板可能出現節點清單載入不全、切換無回應、流量圖不刷新等現象。遇到面板行為異常而命令列 curl 直連介面一切正常時,基本可以判定是面板側過時,升級面板或換用用戶端自帶面板即可,不必懷疑核心設定。反過來,若 curl 直連也失敗,才需要回到 external-controller 與 secret 的設定本身逐項核對。