策略組類型與實戰
策略組是配置檔案裡承上啟下的一層:規則決定「哪類流量交給哪個組」,策略組決定「這個組此刻用哪個節點」。分流做得是否順手,八成取決於策略組結構設計得是否合理。mihomo 核心支援五種基礎類型,行為差異如下。
五種類型的行為差異
| type | 行為 | 典型用途 |
|---|---|---|
| select | 手動選擇,選中項持久保留直到下次手動切換 | 總入口組、地區選擇組 |
| url-test | 週期性測延遲,自動切到延遲最低的節點 | 對速度敏感的日常流量 |
| fallback | 按清單順序取第一個測活通過的節點,前面的恢復後自動切回 | 主備結構,保證服務不中斷 |
| load-balance | 按雜湊或輪詢把連接分散到多個節點 | 大量並發連接、下載類流量 |
| relay | 流量按清單順序依次經過每個節點形成鏈 | 鏈式代理,特殊網路路徑需求 |
select 是最常用也最容易被低估的類型:它不做任何自動判斷,但正因如此行為完全可預期,適合做「人來拍板」的總入口。url-test 與 fallback 的區別經常被混淆——前者永遠追求「當前最快」,節點抖動時可能頻繁橫跳;後者追求「順位最靠前的可用」,只有當前節點失效才動,穩定性優先。對互動式應用(遠端桌面、語音通話)來說,fallback 往往比 url-test 體驗更好,因為切換意味著連接重建。
url-test 的三個關鍵參數
自動測速組的行為由三個參數控制。interval 是測速週期(秒),常見取 300;設得太短會產生大量探測請求,行動裝置端還會拖累電池。tolerance 是容差(毫秒):新的最快節點必須比當前節點快出這個數值才觸發切換,建議 50 起步,能顯著減少無意義的橫跳。lazy 設為 true 時,組在沒有流量經過的時候跳過測速,對節點數量多的配置能省下可觀的探測開銷。
實戰分組結構
推薦的結構是三層:頂層一個 select 總入口,中層按地區或用途分組,底層才是具體節點。規則永遠指向頂層或中層組,不直接指向節點——這樣換機場、換節點名都不需要動規則。範例:
proxy-groups:
- name: 節點選擇
type: select
proxies: [自動測速, 故障轉移, 香港節點, 日本節點, DIRECT]
- name: 自動測速
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
proxies: [HK-01, HK-02, JP-01]
- name: 故障轉移
type: fallback
url: https://www.gstatic.com/generate_204
interval: 300
proxies: [HK-01, JP-01, SG-01]
- name: 香港節點
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
proxies: [HK-01, HK-02]
測活位址選返回 204 狀態碼的輕量端點(如上例的 generate_204),回應內容為空、開銷最小。不要用完整網頁做測活,那測的是頁面載入而不是連線延遲。
巢狀引用與命名一致性
策略組之間可以互相引用:一個 select 組的 proxies 清單裡,既可以放具體節點,也可以放另一個 url-test 或 fallback 組的名字。這正是三層結構能成立的原因——頂層組把中層組當「節點」來選,中層組內部再自動測速。需要提醒的是,組名一旦被規則或其他組引用,就成了配置裡的「介面」:任何一處改名而引用方沒同步,核心載入時會直接報「proxy group not found」並拒絕啟動。批次調整分組時,養成「先全域搜尋組名再改」的習慣,能省掉大量因為一個字元對不上而反覆重載的時間。另外,組名盡量用能自解釋的中文或簡短英文,避免用純符號或極易混淆的名字(比如同時存在「香港」和「香港節點」兩個組),否則手動切換時很容易點錯,排查時也難以一眼對應。
DIRECT、REJECT 與內建策略的位置
除了自訂組和具體節點,配置裡還有三個內建策略必須理解:DIRECT 表示不經代理直接連接,REJECT 表示直接拒絕(常用於廣告與追蹤域名),PASS 表示跳過當前規則集交給後續規則繼續判斷。把 DIRECT 放進頂層 select 組的 proxies 清單是個實用技巧:遇到某個站點走代理反而更慢,或臨時需要以真實 IP 存取某服務時,面板上一鍵切到 DIRECT 即可,不必去改規則。REJECT 一般不放進可選清單,而是直接作為廣告類規則集的目標策略。理解這三者的語義,能避免「為什麼這條流量沒走代理」或「為什麼這個域名連不上」這類看似詭異、實則策略指向問題的困惑。
規則集訂閱化管理
把幾百上千條規則直接寫進主配置,是維護性災難的開始:訂閱一更新全部重來,想調一條規則要在長檔案裡翻找。規則集(rule-providers)把規則拆成獨立的遠端檔案,主配置裡只留參照,規則內容按週期自動更新,主配置保持十幾行的清爽。
behavior 三種類型
每個規則集必須宣告 behavior,它決定檔案內容的解析方式,三者不可混用。domain 類型的檔案只能包含域名(支援 +. 通配前綴),比對效率最高;ipcidr 只能包含 IP 段(CIDR 表示法);classical 則允許寫完整的規則語法(DOMAIN-SUFFIX、IP-CIDR、DST-PORT 等混排),靈活但比對開銷略大。原則是:能用 domain 或 ipcidr 就不用 classical,把 classical 留給確實需要混合條件的場景。
format 與更新週期
format 支援 yaml、text 與 mihomo 專有的二進位格式 mrs。mrs 是預先編譯產物,體積小、載入快,大體量的域名/IP 集合(比如整個地區的 IP 庫)優先選它;自己手寫維護的小規則集用 yaml 或 text 即可。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
- MATCH,節點選擇
引用語法是 RULE-SET,規則集名,策略。注意規則仍然是自上而下逐條比對、命中即停,RULE-SET 的排列順序和一般規則一樣重要:把命中率高的集合放前面,把 IP 類規則放在域名類規則之後(IP 規則會觸發 DNS 解析,提前觸發是浪費)。MATCH 兜底規則永遠放最後一行。
behavior 宣告與檔案實際內容不符是規則集最常見的故障:比如把 classical 語法的檔案宣告成 domain,核心解析會直接報錯或整個集合靜默失效。引用第三方規則集時,先確認發布方標註的 behavior 類型再抄。
規則比對順序的效能含義
很多人把規則順序只當成「邏輯對不對」的問題,其實它同樣是「跑得快不快」的問題。核心對每條連線都要自上而下逐條比對,直到命中為止;規則越靠後,命中它的連線前面白白比對的次數就越多。當規則總量上萬,順序不當帶來的比對開銷在高並發下會變成可感知的延遲。優化的思路有兩條:一是把高頻命中的規則集盡量前置,讓大多數連線在前幾條就出結果;二是善用 no-resolve 參數——IP-CIDR 規則預設會先觸發 DNS 解析拿到 IP 再比對,如果這條規則本意只針對已經是 IP 的直連流量,加上 no-resolve 就能跳過解析,既省時間又避免不必要的解析請求。
GEOIP 與 GEOSITE 的取捨
除了自建規則集,核心還內建支援 GEOIP 與 GEOSITE 兩類地理資料庫規則。GEOIP,CN,DIRECT 一行就能讓所有歸屬中國大陸的 IP 直連,GEOSITE,category-ads-all,REJECT 一行攔掉一大類廣告域名,寫法極簡。代價是資料庫檔案本身有體積、需要定期更新,而且分類的收錄範圍由資料庫維護方決定,偶爾會出現「某個站點被歸錯類」的情況。實踐中的平衡是:用 GEOSITE/GEOIP 兜住大面積的常規分流,再用少量精確的自訂規則集覆蓋那些資料庫判斷不準、或有個性化需求的域名,並把自訂規則放在 GEO 規則之前,保證個性化判斷優先生效。
DNS 配置優化
DNS 是分流品質的地基。域名解析被污染,IP 規則就會基於錯誤的 IP 做判斷;解析伺服器選擇不當,直連流量會繞遠、CDN 會分配到低速節點。核心自帶一套完整的 DNS 模組,理解各欄位的分工之後,大多數「規則明明寫對了卻不生效」的問題會自動消失。
nameserver 與 default-nameserver 的分工
nameserver 是主解析伺服器清單,負責所有業務域名的解析,推薦用 DoH(DNS over HTTPS)位址以規避明文 53 埠的干擾。這裡有個先有雞還是先有蛋的問題:DoH 位址本身是個域名,它自己也需要被解析——這就是 default-nameserver 存在的意義,它只負責解析 nameserver 清單裡出現的域名,必須填純 IP 的傳統 DNS。兩者職責不同,不能互相替代。
nameserver-policy 按域名分派
nameserver-policy 允許按域名模式指定專用解析伺服器:台灣本地域名走本地 DNS 拿到就近 CDN,其餘域名走可信的加密 DNS 避免污染。它支援 geosite 分類引用,一行就能覆蓋一大類域名,是目前推薦的分流解析方案,比舊式的 fallback + fallback-filter 組合更直觀、行為更可控。
dns:
enable: true
listen: 0.0.0.0:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://doh.pub/dns-query
- https://dns.alidns.com/dns-query
nameserver-policy:
"geosite:cn":
- https://doh.pub/dns-query
"geosite:geolocation-!cn":
- https://dns.cloudflare.com/dns-query
enhanced-mode 決定增強解析模式,取值 fake-ip 或 redir-host,與 TUN 的協同細節在下一章展開。listen 是核心 DNS 的監聽位址,TUN 模式下配合 dns-hijack 把系統 DNS 查詢劫持到這裡,保證解析全部經過核心。
驗證 DNS 配置是否生效,最直接的辦法是看連接面板裡域名解析出的 IP 歸屬:台灣本地站台解析出本地 CDN、其餘站台沒有出現明顯異常 IP,基本就配對了。解析行為異常時優先檢查 default-nameserver 是否可達。
TUN 與 Fake-IP
系統代理模式的天生短板是「只管遵守代理設定的程式」:命令列工具、遊戲、部分用戶端軟體根本不讀系統代理。TUN 模式在系統裡建立一塊虛擬網卡,把全部流量在網路層接進核心,從根上解決接管不全的問題。UWP 應用的迴環限制、終端裡的 git 與套件管理器,在 TUN 模式下都不再需要單獨處理。
啟用 TUN 與 stack 選擇
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,是 TUN 與 Fake-IP 協同的關鍵一環。stack 決定虛擬網卡的協定堆疊實作:system 直接用作業系統網路堆疊,吞吐好;gvisor 是使用者態實作,相容性好;mixed 取兩者折中,TCP 走 system、UDP 走 gvisor,桌面端可以從 mixed 開始試。各平台啟用前提不同:
| 平台 | 啟用前提 | 備註 |
|---|---|---|
| Windows | 以系統管理員權限執行,或安裝用戶端提供的系統服務 | Clash Verge Rev 提供服務模式,免每次提權 |
| macOS | 首次啟用需輸入系統管理員密碼授權 | 授權一次後續靜默生效 |
| Android | 走系統 VpnService 介面,授權 VPN 連接即可 | 無需 root,背景策略見下方提示 |
| Linux | root 權限或授予二進位檔案 CAP_NET_ADMIN 能力 | 伺服器場景建議 systemd 常駐 |
Fake-IP 原理與 fake-ip-filter
Fake-IP 是配合 TUN 的解析策略:程式發起域名查詢時,核心不等真實解析完成,立即從保留網段(預設 198.18.0.1/16)返回一個「假 IP」並記住映射關係。連接到達時憑假 IP 反查出域名,直接按域名規則比對——省掉一次串行的 DNS 等待,建連更快,規則命中也更準。代價是有些程式拿到假 IP 會出問題:區域網路發現、時間同步、網路連通性檢測這類「拿 IP 當真」的場景需要豁免,這就是 fake-ip-filter 的用途:
dns:
fake-ip-filter:
- "*.lan"
- "+.local"
- "time.windows.com"
- "+.msftconnecttest.com"
- "+.stun.*.*"
命中過濾清單的域名走真實解析、返回真 IP。清單宜精不宜濫:加得越多,Fake-IP 的收益被稀釋得越嚴重。另外注意 Fake-IP 與 redir-host 切換後,系統和瀏覽器裡可能殘留舊的解析快取,表現為一段時間內部分站台行為怪異,重啟用戶端或刷新系統 DNS 快取即可恢復。
行動裝置端長期開 TUN 對耗電有可感知的影響,背景保活與廠商省電策略的取捨見部落格《Clash 安卓耗電異常分析》;桌面端啟動即崩、TUN 啟用失敗一類問題在常見問題的故障排查分類裡有逐項處理辦法。
域名嗅探
規則裡寫得最順手的是域名規則,但有兩類流量到達核心時只有 IP、沒有域名:一是程式自己做了 DNS 解析後直連 IP(繞開了核心的解析環節),二是 Fake-IP 映射之外的場景。沒有域名,DOMAIN-SUFFIX 一類規則全部落空,流量只能掉進 IP 規則或兜底規則。域名嗅探(sniffer)的作用就是從流量本身把域名「讀」回來:TLS 交握的 SNI 欄位、HTTP 請求的 Host 標頭、QUIC 的交握封包裡都帶著目標域名,核心在建連初期解析這些協定特徵,把還原出的域名重新交給規則引擎比對。
配置結構
sniffer:
enable: true
sniff:
HTTP:
ports: [80, 8080-8880]
override-destination: true
TLS:
ports: [443, 8443]
QUIC:
ports: [443]
force-domain:
- "+.example-cdn.net"
skip-domain:
- "+.push.apple.com"
sniff 下按協定宣告嗅探的埠範圍,只嗅探宣告過的埠,範圍收得越窄開銷越小。override-destination 決定嗅探出域名後是否用它覆蓋連接的目標位址——開啟後連接會以域名形式繼續處理,規則比對與 DNS 分派都按域名走。force-domain 強制對命中的域名執行嗅探覆蓋,常用於某些拿到 Fake-IP 仍自行連接 IP 的應用;skip-domain 則是白名單,命中的域名跳過覆蓋,推播服務這類對連接目標敏感的長連接建議列入,避免嗅探干擾。
嗅探不是解密:它只讀取協定交握階段明文攜帶的元資料(SNI、Host),不觸碰加密載荷。對絕大多數配置,開啟 HTTP 與 TLS 兩類嗅探已經能覆蓋主要場景,QUIC 按需追加。
QUIC 嗅探與 HTTP/3 的現實取捨
越來越多的站點預設啟用 HTTP/3,而 HTTP/3 跑在 QUIC(UDP 443)之上。這帶來一個經常被忽略的連鎖反應:如果只嗅探 TLS 而不處理 QUIC,支援 HTTP/3 的瀏覽器會優先走 QUIC,核心拿到的是一條只有 IP、沒有 SNI 域名的 UDP 流量,域名規則隨之落空。應對方式有兩種,取捨取決於你更看重命中準確性還是鏈路效能。一種是打開 QUIC 嗅探,讓核心也能從 QUIC 交握裡還原域名;另一種更簡單粗暴——直接用規則攔掉 UDP 443,逼瀏覽器回退到 TCP 上的 HTTP/2,雖然損失了 HTTP/3 的部分效能,但換來了完全可預期的域名分流。家用環境如果發現「某些走了代理的站點偶爾抽風、時好時壞」,十有八九就是 QUIC 流量沒被正確接管導致的,這條經驗值得記住。
本機覆寫與多訂閱合併
直接在訂閱下發的配置檔案上改動,是新手最常見的維護陷阱:訂閱一更新,機場伺服器的範本會整體覆蓋本機檔案,所有手動修改瞬間歸零。部落格《Clash 訂閱更新失敗怎麼排查》裡相當一部分案例的根源就在這裡。正確做法是把「機場給的」與「自己寫的」分離:訂閱只當節點來源,個人化內容放進覆寫層或獨立的 provider。
用戶端覆寫:Merge 與 Script
Clash Verge Rev 提供兩級覆寫,都作用於訂閱更新之後、核心載入之前,因此永遠不會被訂閱覆蓋。Merge 覆寫是宣告式的:寫一段 YAML 片段,按欄位合併進最終配置,適合追加 DNS 配置、rule-providers、置頂幾條自訂規則這類結構化改動。Script 覆寫是一段 JavaScript 函式,接收完整配置物件、返回修改後的物件,適合需要邏輯的場景——按名稱正規表示式過濾節點、批量給策略組塞節點、根據節點數量動態產生分組。兩者可疊加使用,建議優先 Merge,確實需要程式設計能力再上 Script。Clash Plus 同樣提供訂閱與本機配置分離的管理方式,各用戶端在這方面的差異可參考用戶端對比。
proxy-providers 多訂閱合併
手裡有多家訂閱時,不必來回切換配置。proxy-providers 把每個訂閱宣告為一個節點來源,各自獨立更新,再透過策略組的 use 欄位把多個來源的節點匯入同一個組:
proxy-providers:
airport-a:
type: http
url: https://a.example.com/sub?token=xxxx
path: ./providers/airport-a.yaml
interval: 43200
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 600
airport-b:
type: http
url: https://b.example.com/sub?token=xxxx
path: ./providers/airport-b.yaml
interval: 43200
proxy-groups:
- name: 節點選擇
type: select
use: [airport-a, airport-b]
- name: 自動測速
type: url-test
url: https://www.gstatic.com/generate_204
interval: 300
use: [airport-a, airport-b]
use 與 proxies 可以在同一個組裡並存,前者引入 provider 的全部節點,後者追加手寫節點或其他組。health-check 讓 provider 自帶測活,url-test 組引用時能直接複用測活結果。interval 是訂閱拉取週期(秒),43200(半天)對多數機場足夠;某個 provider 拉取失敗不影響其他來源,這也是多訂閱結構天然的容災優勢。
用 provider 的 filter 欄位(正規表示式)可以只放行特定節點進組,例如按地區名篩選,配合 use 能做出「多機場同地區聚合測速」的結構,規則層完全無感知。
外部控制面板
核心執行時暴露一套 RESTful 控制介面,節點切換、延遲測試、連接查看、配置重載都透過它完成——桌面用戶端的介面本質上就是這套介面的封裝。直接使用外部控制,價值在兩類場景:一是軟路由、伺服器上跑裸核心,沒有 GUI;二是想用瀏覽器面板或腳本做自動化管理。
開啟介面與驗證授權
external-controller: 127.0.0.1:9097
secret: "your-strong-secret"
external-ui: ./ui
external-controller 宣告監聽位址與埠。只在本機使用就綁 127.0.0.1;需要區域網路內其他裝置存取(比如用手機管理軟路由上的核心)才綁 0.0.0.0,並且此時 secret 必須設定為足夠強的隨機字串——所有請求都要在 Authorization 標頭裡攜帶它。external-ui 指向一個靜態網頁面板目錄,核心會直接託管,瀏覽器存取控制位址即可開啟;主流的開源 Web 面板(metacubexd、yacd 系)解壓進該目錄就能用。
用 API 做自動化
介面是標準 HTTP + JSON,curl 就能驅動。查看全部策略組與節點狀態:
切換某個 select 組的選中節點,對組名發 PUT 請求:
常用端點還包括 /connections(即時連接清單,排查「這條流量到底走了哪個策略」的第一現場)、/logs(日誌串流)、/configs(執行時改埠與模式)。把這些端點接進腳本,就能實作定時測速、異常自動切換一類的無人值守邏輯。
控制介面擁有對核心的完全控制權。綁定非迴環位址而不設 secret,等於把代理控制權敞開給整個區域網路;暴露到公開網路則任何情況下都不可接受。範例裡的 secret 是佔位寫法,實際使用請替換為自己產生的隨機值。
面板與用戶端並存時的狀態一致性
桌面用戶端在執行時會連著同一套控制介面,因此當你同時開著用戶端介面又用瀏覽器面板或腳本操作時,雙方看到的是同一份核心狀態:在瀏覽器裡切了節點,用戶端介面刷新後也會顯示新的選擇。這一點在做自動化時尤其要留意——腳本切換節點屬於對核心的「真實操作」,會被持久記錄,不像單純測速那樣只讀。因此建議把自動化腳本的行為限定在明確的場景裡(比如偵測到當前節點連續測活失敗才切換),並在日誌裡留下切換記錄,避免出現「節點莫名其妙自己變了、又找不到是誰改的」的困惑。軟路由等無 GUI 環境更要如此,因為那裡沒有介面幫你直觀回看狀態。
埠與衝突排查
控制埠(範例裡的 9097)和核心的代理監聽埠(mixed-port、DNS 的 listen 埠等)是各自獨立的,它們之間不能撞車,也不能和系統裡其他常駐服務搶同一個埠。啟動失敗時,「address already in use」是最典型的報錯,含義就是某個埠被佔了。排查順序很簡單:先確認是不是上一個核心實例沒退乾淨(殘留行程佔著埠),再用系統的埠佔用查看命令定位到底是誰在用,最後要麼關掉佔用方,要麼把核心的埠改到一個沒人用的值。這類埠衝突在同時裝了多個代理用戶端、或用戶端異常退出後重啟時特別常見,理解了各埠的獨立性,就不會再把它誤當成「配置寫錯了」來反覆折騰配置檔案。
查閱路徑與延伸閱讀
七章內容之間有清晰的依賴關係:策略組與規則集是骨架,DNS 是地基,TUN、Fake-IP 與嗅探解決「接管得全不全、比對得準不準」,覆寫與合併解決長期維護,外部控制負責執行時觀測與自動化。建議按實際痛點單章切入,不必從頭通讀。配置裡遇到陌生名詞,術語表按「核心與用戶端 / 代理協定 / 規則與策略組 / DNS 與流量處理 / 配置檔案欄位」五個分類收錄了定義;改完配置出現報錯或行為異常,先查常見問題的故障排查分類;還沒決定用哪個用戶端承載這些配置,用戶端對比給了按平台與使用習慣的選型結論,首次安裝的完整檢查清單見部落格《Clash 用戶端首次安裝設定清單》。本頁會隨核心配置欄位的演進持續修訂,建議收藏備查。