HANDBOOK

Clash 進階設定手冊

這是本站資訊量最大的一頁。快速上手教學負責主線——下載、匯入訂閱、選模式、驗證連通;本手冊負責主線之外的一切:策略群組怎麼編排、規則集怎麼外置、DNS 為什麼要接管、TUN 與 Fake-IP 在做什麼、嗅探補哪一環、覆寫如何不被訂閱更新蓋掉、外部控制 API 怎麼用。八章各自獨立,按需查閱即可,不必從頭讀到尾。

所有範例以 mihomo 核心的 YAML 語義為準。iOS 上首推 Clash Plus,桌面端可搭配 Clash Verge Rev 或 FlClash,用戶端入口統一見下載中心

8 章 · mihomo · YAML 範例可直接套用 · 每章帶獨立錨點

CH-00

閱讀前提與設定檔結構

繼續之前,請確認兩件事:用戶端已經能正常連網(教學頁的主線走完了),並且你知道自己目前用的設定來自哪份訂閱。進階設定的每一處改動都建立在「有一份能跑的基線」之上,基線不穩,後面的調整無從驗證。

mihomo 的設定檔是一份 YAML,頂層鍵可以按職責分成五塊,本手冊的章節安排與之一一對應:

  • 入站:portsocks-portmixed-porttun——流量從哪裡進來;
  • 出站:proxiesproxy-providersproxy-groups——流量可以從哪裡出去;
  • 路由:rulesrule-providers——哪類流量走哪個出口;
  • 解析:dnssniffer——網域如何變成位址,位址如何還原成網域;
  • 控制:external-controllerexternal-uisecret——執行狀態如何對外暴露。

最小可執行骨架

剝掉所有可選項,一份能啟動的設定長這樣。後續各章的範例片段,都預設掛在這副骨架的對應位置上:

mixed-port: 7890
mode: rule
log-level: info

proxies: []        # 通常由訂閱提供

proxy-groups:
  - name: 節點選擇
    type: select
    proxies:
      - DIRECT

rules:
  - GEOIP,CN,DIRECT
  - MATCH,節點選擇

YAML 對縮排極其敏感:統一用兩個空格,禁止 Tab;值裡含冒號、井號或以特殊字元開頭時要加引號。啟動閃退的第一嫌疑人永遠是縮排,排查思路可參考部落格《Clash 啟動閃退怎麼辦》

平台差異:iOS 與桌面端

iOS 上的 Clash Plus 基於 Network Extension 運行,設定管理方式是「訂閱為底 + 覆寫為增量」——你一般不直接改訂閱原文,而是在用戶端裡疊加自己的修改(詳見第六章)。桌面端的 Clash Verge Rev、FlClash 則允許直接編輯設定全文。無論哪個用戶端,本手冊討論的都是核心層語義,寫法通用。

最後是一個值得養成的習慣:每次改動設定後,固定走「重新載入設定 → 觀察日誌 → 驗證行為」三步。日誌各層級的閱讀順序與高頻錯誤含義,部落格《Clash 運行日誌怎麼看》有逐條解釋,本手冊後面幾章會反覆用到這套驗證方法。

設定來源、備份與回復

進階設定的另一半功課是版本管理。手冊裡的每一章都會讓你往設定裡加東西,而加錯東西的代價往往不是立刻報錯,而是三天後某個站點突然打不開。因此在動手之前,先給目前能跑的設定留一份副本:桌面端可以直接把設定目錄複製成帶日期的資料夾,iOS 上則把覆寫內容單獨抄到備忘錄或私有倉庫裡。每次只改一個主題——這一次只動 DNS,下一次只動策略群組——改完立刻驗證,確認無誤再疊加下一項。這樣即使出問題,你也能準確說出是哪一處改動帶來的,回復一步即可恢復,而不必推翻整份設定重來。

還要區分清楚三類「設定來源」:訂閱服務商下發的原文、用戶端自動產生的執行時設定、以及你自己維護的覆寫片段。真正需要你長期保管的只有第三類,前兩類隨時可以重新拉取或重新產生。把這條界線記牢,後面第六章講覆寫時你會更容易理解「為什麼不要直接改訂閱原文」。

CH-01

策略群組類型與實戰編排

策略群組(proxy-groups)是規則與節點之間的中間層。規則命中後,目標可以是單個節點、內建出口(DIRECT / REJECT),也可以是一個策略群組;而策略群組的成員,又可以是節點或另一個策略群組。理解「群組可以套群組」這一點,是編排一切複雜分流的前提。

mihomo 提供五種群組類型,選擇邏輯各不相同:

類型選擇邏輯典型場景
select手動選擇,保持不變直到使用者再次切換總入口群組、地區手選群組
url-test週期性測速,自動鎖定延遲最低的成員同地區節點自動擇優
fallback按清單順序取第一個可用成員,失效才後移主備切換、保底出口
load-balance按雜湊或輪詢把連線分散到多個成員多節點分攤大流量
relay成員按順序串聯成鏈式轉發特殊鏈路需求,日常少用

自動測速群組的四個關鍵參數

url-testfallback 依賴健康檢查,行為由四個參數決定。url 是測速目標,慣例用回傳 204 的輕量地址;interval 是檢查週期(秒),300 是穩妥值,壓得太低會白白消耗節點流量;tolerance 是切換容差(毫秒)——新舊節點延遲差距小於該值時不切換,用來防止兩個延遲接近的節點來回抖動;lazy: true 表示群組未被使用時暫停測速,行動裝置上建議開啟以省電省流量。

實戰:三層結構

大多數場景下,一份清晰的設定只需要三層:手動總入口在最上,自動測速與故障轉移在中間,訂閱節點在最下。規則一律指向總入口,日常切換只碰這一個群組:

proxy-groups:
  - name: 節點選擇
    type: select
    proxies:
      - 自動測速
      - 故障轉移
      - DIRECT

  - name: 自動測速
    type: url-test
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50
    lazy: true
    use:
      - main-sub

  - name: 故障轉移
    type: fallback
    url: https://www.gstatic.com/generate_204
    interval: 300
    use:
      - main-sub

範例裡的 use 欄位引用的是代理集合(proxy-providers,第六章展開),讓群組的成員隨訂閱更新自動同步,不必手寫節點名。兩個注意點:群組名在 rules 裡引用時必須一字不差,多一個空格都會導致啟動失敗;群組與群組互相引用時不能形成環,核心會在啟動時直接報錯拒絕載入。

需要按業務再細分(比如串流媒體單獨走一組)時,照同樣的模式加一個 select 群組、把「自動測速」「節點選擇」放進成員即可——先有骨架再做加法,比一開始就堆十幾個群組好維護得多。

負載平衡與鏈式轉發的取捨

表格裡的 load-balancerelay 日常用得少,但值得知道它們的適用邊界。load-balance 有兩種雜湊策略:按連線雜湊會把每條新連線分給不同成員,吞吐更均勻,但同一站點的多個請求可能來自不同出口 IP,登入狀態敏感的網站會因此頻繁要求重新驗證;按網域雜湊則保證同一網域始終落在同一成員上,相容性更好,是日常首選。relay 把多個節點串成一條鏈路,每多一跳就多一段延遲與一處故障點,只有在「必須先落地到某個中轉再出網」的特殊需求下才考慮。

群組的命名同樣值得花一分鐘規劃。群組名會同時出現在規則裡、用戶端介面上、以及外部控制 API 的路徑中,後期改名意味著所有引用處一起改,還可能撞上 URL 編碼問題。建議一開始就用短、穩、語義明確的名字,避免使用空格開頭結尾與容易混淆的全角符號;把節點的地區、倍率資訊留在節點名裡,不要塞進群組名。若某個群組的成員需要按關鍵詞篩選,用 filter 欄位搭配正規表示式從集合裡挑選,比手寫成員清單更能扛住訂閱變動。

CH-02

規則集訂閱化管理

把幾千行規則直接寫進 rules 有兩個代價:設定本體臃腫難讀,規則一變就得改主設定。rule-providers 的思路是把規則外置成獨立檔案,核心按週期自動拉取更新,主設定裡只留一行引用。

rule-providers:
  streaming:
    type: http
    behavior: domain
    format: yaml
    url: https://example.com/rules/streaming.yaml
    path: ./rule-sets/streaming.yaml
    interval: 86400

rules:
  - RULE-SET,streaming,節點選擇
  - GEOIP,CN,DIRECT
  - MATCH,節點選擇

欄位逐個說:typehttp(遠端拉取)或 file(本地檔案);urlpath 分別是遠端位址和本地快取路徑;interval 是自動更新週期(秒),規則集內容變化不頻繁,86400(一天)足夠。format 支援 yamltextmrs——mrs 是 mihomo 的二進位規則格式,體積小、載入快,規則來源提供時優先選它。

behavior:最容易踩的一個欄位

behavior 聲明這份規則集的內容形態,必須與檔案實際內容匹配:

behavior內容形態範例行
domain純網域清單(支援 +. 萬用)+.example.com
ipcidr純 IP 段清單203.0.113.0/24
classical完整規則行(自帶匹配類型)DOMAIN-SUFFIX,example.com

behavior 與內容不匹配時,規則集往往靜默失效——不報錯,只是永遠不命中。分流「看起來配了但不生效」時,先核對這裡。另外,ipcidr 類規則集在 RULE-SET 行末尾可加 no-resolve,避免為純 IP 匹配觸發一次額外的網域解析。

與 GeoSite / GeoIP 的關係

GEOSITEGEOIP 規則背後是另一種「打包好的規則集」——兩個二進位資料庫,按國家或站點分類收錄網域與 IP 段。它們與 rule-providers 並不衝突:geo 資料庫覆蓋通用大類,rule-providers 補充個人化條目。資料庫過舊會直接導致分流失準,更新方式見部落格《GeoIP 與 GeoSite 資料庫更新指南》;至於 rules 裡各類型的語法與自上而下的優先權原則,部落格《Clash 自訂規則寫法詳解》有完整展開,此處不重複。

規則集的更新失敗與本地兜底

rule-providers 依賴網路拉取,而拉取本身也可能失敗:規則來源網域解析被污染、來源站臨時不可用、或者拉取時機恰好在代理還沒建立的啟動瞬間。核心的處理策略是「拉不到就用本地快取」,因此 path 指向的快取檔案其實是一道兜底防線,首次成功拉取之後就不要隨手刪掉它。日誌裡出現規則集拉取逾時的警告,而分流依然正常,說明正在吃快取;此時不必驚慌,但要留意規則內容是否已經過期。

如果某個規則來源長期不穩定,更穩妥的做法是把它固定成 type: file 的本地規則集,自己定期手動更新一次。這種方式犧牲了自動化,換來的是啟動階段的確定性——對路由器等無人值守場景尤其重要。

規則條數、順序與效能

很多人擔心規則太多會拖慢速度,實際瓶頸幾乎從不在這裡:網域類規則在核心裡以前綴樹等結構組織,幾萬條的匹配開銷依然可以忽略。真正值得關注的是順序解析代價。順序方面,越具體的規則越要往前放,兜底的 MATCH 永遠在最後一行;把 GEOIP,CN,DIRECT 誤放在自訂網域規則前面,是「規則明明寫了卻不生效」的經典原因。解析代價方面,所有 IP 類規則(GEOIPIP-CIDR)在遇到網域目標時都需要先解析一次,若不加 no-resolve,一條位置靠前的 IP 規則會給每個新網域連線都引入一次解析等待。因此慣例是:網域規則集中放在前半段,IP 規則放在後半段,並對無需解析的場景明確聲明 no-resolve

最後給一個可長期維護的規則佈局範本:第一段是本地與內網直連(DOMAIN-SUFFIX,lan、私有位址段),第二段是自己的強制規則(prepend 上來的白名單黑名單),第三段是各類訂閱化規則集,第四段是 geo 大類,最後一行 MATCH 指向總入口群組。按這個分段組織,任何一條新規則都能立刻找到自己該待的位置。

CH-03

DNS 設定最佳化

先回答「為什麼核心要自己管 DNS」。規則分流大量依賴解析結果:GEOIP,CN,DIRECT 要先把網域解析成 IP 才能判斷歸屬。如果解析交給系統、而系統拿到的是被污染的位址,GEOIP 會把本該走代理的流量誤判成直連,表現為「規則沒錯但就是打不開」。讓核心用可信的加密 DNS 自己解析,是分流準確性的地基。

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
  nameserver:
    - https://doh.pub/dns-query
    - https://dns.alidns.com/dns-query
  proxy-server-nameserver:
    - https://doh.pub/dns-query
  nameserver-policy:
    "geosite:cn":
      - https://doh.pub/dns-query

三組 nameserver 各管一段

這套欄位容易混,按「誰被解析」來記:default-nameserver 只能填純 IP,專門用來解析 nameserver 裡 DoH 位址自己的網域——雞生蛋問題的引導器;nameserver 是主力解析器,承擔所有常規查詢,推薦 DoH(https:// 前綴)或 DoT(tls:// 前綴)寫法,明文 53 埠在部分網路環境下會被劫持;proxy-server-nameserver 單獨負責解析代理節點自身的伺服器網域,把它固定到中國大陸直連 DoH,可以避免「節點網域解析要走代理、代理又依賴節點」的死結。

nameserver-policy:按網域分派解析器

nameserver-policy 允許按網域模式指定解析器,最常用的一條就是範例裡的 geosite:cn:中國大陸站點固定用當地 DoH 解析,拿到就近的 CDN 位址;其餘網域交給 nameserver 主力。鍵也可以寫普通網域模式(如 "+.internal.example.com" 指向內網 DNS),適合辦公網場景。

驗證 DNS 設定是否生效,最直接的辦法是看日誌裡的解析紀錄:哪個網域、哪台解析器、回傳什麼。出現成批的 dns resolve failed 時,優先檢查 default-nameserver 是否可達,排查路徑見部落格《Clash 運行日誌怎麼看》

範例裡的 enhanced-mode: fake-ip 是 DNS 與 TUN 交界處最重要的開關,值得單開一章——往下看。

DoH、DoT 與明文 53 的現實取捨

三種傳輸方式的差別不只在「是否加密」。明文 UDP 53 延遲最低,但請求內容對鏈路上的任何裝置都是可見的,也最容易被中間裝置改寫應答;DoT 走 TCP 853 埠,加密完整,但埠特徵明顯,在一些網路裡會被整體阻斷;DoH 把查詢包裹進 HTTPS,和普通網頁流量混在一起,最難被區分對待,代價是每次冷啟動要多一次 TLS 交握。實踐上的組合是:nameserver 用兩條不同服務商的 DoH 互為備份,default-nameserver 只填一兩個可靠的純 IP 明文解析器用於引導。不要在 nameserver 裡堆七八條,核心會並發查詢並取最快應答,條目過多只是徒增流量與不確定性。

解析結果異常的排查順序

DNS 相關的故障表現高度雷同——「能連上但打不開」「部分站點白畫面」——排查時按固定順序走最省時間。第一步確認 dns.enable 為 true 且監聽埠沒被其他程式佔用;第二步在日誌裡搜尋目標網域,看是哪台解析器應答、回傳了什麼位址;第三步判斷該位址是否合理,中國大陸站點卻拿到境外位址、或者反過來,通常意味著 nameserver-policy 分派錯了;第四步才去懷疑規則本身。respect-rules 之類的進階開關會讓解析請求也遵循分流規則,能解決少數場景的精準解析問題,但它引入了「規則依賴解析、解析又依賴規則」的循環,不熟悉時不要輕易打開。

快取、TTL 與內網解析

核心會快取解析結果,快取命中時應答幾乎是零延遲,這也是切換設定後舊位址仍然生效一段時間的原因。遇到需要立刻見效的場景,重新載入設定或重新啟動用戶端網路即可清空快取。若你所在的環境有內網網域(公司 OA、NAS 面板、區域網路印表機),務必在 nameserver-policy 裡把對應後綴指向內網 DNS,並在下一章的 fake-ip-filter 裡放行它們——這兩處配合起來,才能保證內網服務在開啟代理時依然可達。

CH-04

TUN 模式與 Fake-IP

系統代理只能覆蓋「願意讀取代理設定」的應用程式,命令列工具、部分遊戲與背景服務會直接繞過。TUN 模式的做法更徹底:建立一塊虛擬網卡,配合路由表把裝置的全部流量引進核心處理——應用程式無從繞過,因為它們發出的每個封包都要經過這塊網卡。

平台差異先說清楚:iOS 上的 Clash Plus 基於 Network Extension 的通道機制運行,行為天然等同於 TUN,不需要也沒有額外的開關;下面的 tun 設定區塊主要面向桌面端與路由器場景(Windows 需要系統管理員權限載入虛擬網卡驅動程式,macOS 需要在系統設定裡核准網路擴充功能)。路由器上直接運行核心的整體思路,見部落格《路由器直跑 mihomo 核心》

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

stack 決定協定堆疊實作:system 用系統堆疊,效能好但相容性看平台;gvisor 用使用者態堆疊,相容性穩;mixed 取兩者所長,一般直接選它。auto-route 自動寫路由表,auto-detect-interface 自動識別實體出口網卡防止回環,這兩項保持開啟。dns-hijack: any:53 把所有發往 53 埠的明文 DNS 查詢劫持給核心解析——這是 TUN 模式下保證「解析必經核心」的關鍵一環。

Fake-IP:少一次等待的解析模式

回到上一章的 enhanced-mode。傳統 redir-host 模式下,核心收到 DNS 查詢要真實解析一次才能應答;fake-ip 模式則立即從保留網段(預設 198.18.0.1/16)裡分配一個假位址回傳,同時記住「這個假 IP 對應這個網域」。應用程式拿假 IP 發起連線時,核心按對照還原出網域去匹配規則——走代理的流量把網域直接交給遠端解析,本地那次真實解析被完全省掉,建立連線更快,網域匹配也更準。

比較項fake-ipredir-host
應答速度即時回傳假位址等待真實解析完成
規則匹配始終拿得到網域,網域規則全量生效部分場景退化為按 IP 匹配
相容性少數依賴真實 IP 的場景需要過濾無假位址副作用

相容性問題靠 fake-ip-filter 解決:凡是必須拿到真實 IP 的網域——區域網路裝置發現、NTP 校時、部分遊戲對戰平台——列進去讓它們走真實解析:

dns:
  fake-ip-filter:
    - "*.lan"
    - "+.local"
    - time.apple.com
    - "+.stun.*.*"

在 fake-ip 與 redir-host 之間切換後,系統與瀏覽器裡可能殘留舊模式的解析快取,表現為一段時間內部分站點打不開。切換後重新啟動用戶端網路連線,必要時重新啟動裝置,再做驗證。

TUN 與系統代理的共存問題

桌面端最常見的翻車場景是 TUN 與系統代理同時開著。兩者本身可以共存,核心也會處理重複入站,但一旦系統代理指向的埠和 TUN 劫持的流量互相繞圈,就會出現連線莫名逾時、日誌裡同一網域反覆建立連線的現象。穩妥的做法是二選一:需要覆蓋全部應用程式就只開 TUN,只想代理瀏覽器就只開系統代理。若確實要同時開啟,請確認 auto-detect-interface 為 true,讓核心始終把節點流量送往真實實體網卡,而不是又送回虛擬網卡形成回環。

另外兩個平台細節值得提前知道。虛擬網卡的載入需要系統級權限,Windows 上首次啟用會彈出驅動程式安裝提示,macOS 上需要在系統設定裡手動允許網路擴充功能;這兩步沒通過時,用戶端介面會顯示已開啟 TUN,但實際沒有任何流量進來。還有一類問題來自其他網路軟體:部分企業 VPN、安全用戶端也會寫路由表,與 auto-route 爭搶預設路由,表現為開啟 TUN 後整機斷網。遇到這種情況,先退出另一方再測試,確認衝突來源之後再考慮用更細的路由排除規則共存。

Fake-IP 網段與常見誤解

關於 fake-ip 有幾個反覆被問到的點。第一,假位址只在本機有意義,永遠不會出現在網路上,因此不必擔心它和公網位址衝突;但 fake-ip-range 必須避開你實際使用的區域網路網段,預設的 198.18.0.1/16 屬於保留測試網段,通常是安全的。第二,某些應用程式會把解析到的 IP 快取很久甚至寫進設定檔,關閉代理後這些假位址就成了死位址,表現為「關了代理反而更打不開」——退出並重新啟動該應用程式即可。第三,IP 類規則在 fake-ip 下的行為取決於核心能否還原網域:能還原時按網域匹配,還原不了才落到 IP 規則,這也是下一章嗅探要補的那一環。

CH-05

網域嗅探:找回遺失的網域

前兩章解決了「網域如何解析」,但還有一類流量根本不經過核心的 DNS:應用程式自帶加密 DNS(比如瀏覽器內建 DoH)、或乾脆把伺服器 IP 寫死在程式碼裡。這類連線到達核心時只有一個目的 IP,設定裡精心維護的網域規則(DOMAIN-SUFFIXGEOSITE)對它全部失效,只能靠 IP 規則兜底,分流精度大打折扣。

網域嗅探(sniffer)的做法是從流量本身把網域找回來:TLS 交握的 ClientHello 裡帶著 SNI,HTTP 請求標頭裡有 Host,QUIC 初始封包裡同樣能還原出目標網域。核心在建立連線初期讀取這些欄位,把還原出的網域回填給路由引擎,讓網域規則重新生效。

sniffer:
  enable: true
  sniff:
    HTTP:
      ports: [80, 8080-8880]
      override-destination: true
    TLS:
      ports: [443, 8443]
    QUIC:
      ports: [443, 8443]
  force-domain:
    - "+.v2ex.com"
  skip-domain:
    - "Mijia Cloud"

三個協定區塊分別聲明在哪些埠上嘗試嗅探對應協定;override-destination 表示用嗅探到的網域覆蓋連線的目標位址,通常保持開啟。force-domain 列出的網域即便解析結果正常也強制嗅探覆蓋,用於對付部分 CDN 網域與 IP 對不上的情況;skip-domain 則相反,把嗅探後反而出問題的目標排除掉——某些智慧家庭私有協定會被誤識別,加進這裡即可。

代價方面,嗅探只讀取每條連線最初的交握資料,開銷可以忽略。它與 fake-ip 是互補關係而非替代:fake-ip 保證經過核心 DNS 的流量帶著網域,嗅探負責補上繞過核心 DNS 的那部分。兩者同時開啟,網域規則的覆蓋面才算完整。

什麼時候該懷疑嗅探

嗅探帶來的問題通常有很鮮明的特徵:某個應用程式在開啟嗅探後完全連不上,而關掉嗅探立刻恢復。原因多半是它的私有協定在指定埠上跑,而交握資料被誤當成 TLS 解析,拿到一個亂碼「網域」後連線被送去了錯誤的出口。智慧家庭裝置、區域網路內的私有服務、部分遊戲的對戰通道都屬於高發區。處理方式有三檔:先用 skip-domain 排除已知目標,再考慮把該埠從 sniff 的埠清單裡刪掉,最後才是整體關閉嗅探。另外注意 override-destination 的語義——關掉它時嗅探到的網域只用於規則匹配,不覆蓋實際連線目標,這是一個更保守也更安全的折中檔位。

驗證嗅探是否在工作

最直觀的驗證方式是看活動連線清單:嗅探生效時,原本只顯示 IP 的連線會帶上還原出的網域,通常還會標註嗅探來源。若清單裡大量連線依然只有 IP,先確認目標埠是否在 sniff 聲明的範圍內(很多服務跑在非標準埠上),再確認這些連線是不是 QUIC——瀏覽器的 QUIC 流量若沒在 QUIC 區塊裡聲明埠,就不會被嗅探。把 HTTP、TLS、QUIC 三塊都配好,才能覆蓋當下主流的流量形態。

CH-06

本地覆寫與多訂閱合併

一個所有人都會撞上的問題:訂閱檔案是伺服端產生的,你直接在裡面加的規則、改的 DNS,下一次訂閱更新就被整體覆蓋沖掉。正確做法是讓訂閱保持原樣,把自己的修改聲明成覆寫——每次訂閱更新後,用戶端自動把覆寫重新疊加上去。

兩種覆寫形態

主流用戶端提供兩類覆寫。聲明式(merge):寫一份 YAML 片段,聲明哪些頂層鍵要替換、哪些清單要在頭尾追加,直觀且不易出錯;腳本式:寫一個函式,接收完整設定物件、回傳修改後的設定,靈活但需要自行承擔除錯成本。Clash Plus 與 Clash Verge Rev 都內建了覆寫入口,日常需求用聲明式就夠了。以常見的 merge 語義為例:

# 覆寫片段:整鍵替換 dns,規則頭部追加兩條
dns:
  enable: true
  enhanced-mode: fake-ip

prepend-rules:
  - DOMAIN-SUFFIX,internal.example.com,DIRECT
  - PROCESS-NAME,Terminal,DIRECT

理解 merge 只需要記住一條:普通頂層鍵是整體替換,帶 prepend / append 前綴的鍵是清單追加。規則自上而下匹配,自訂規則想優先生效就用頭部追加;想只做兜底就用尾部追加。

多訂閱合併:proxy-providers

手裡有多份訂閱時,不必在用戶端裡來回切換設定。proxy-providers 把每份訂閱聲明成一個節點集合,策略群組用 use 引用集合,所有訂閱的節點就匯入同一份設定:

proxy-providers:
  main-sub:
    type: http
    url: https://example.com/sub?token=xxxx
    path: ./providers/main.yaml
    interval: 43200
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 600

  backup-sub:
    type: http
    url: https://backup.example.com/sub?token=xxxx
    path: ./providers/backup.yaml
    interval: 43200
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 600

欄位與第二章的 rule-providers 同構:interval 控制訂閱自動更新週期,43200(半天)對多數訂閱足夠;health-check 讓集合內節點帶上可用性狀態,供 url-test / fallback 群組直接消費。第一章範例裡 use: [main-sub] 引用的正是這裡——群組的成員隨訂閱更新自動增減,設定本體一行不用改。訂閱更新失敗時先看日誌裡的拉取錯誤,再核對 URL 是否過期。

訂閱 URL 裡的 token 等同於帳號憑證:不要截圖、不要貼進公開的問題回饋裡。範例中的 token=xxxx 是佔位假值。

多訂閱場景下的群組編排

把兩份訂閱都接進來之後,策略群組該怎麼組織?不推薦把所有集合一股腦塞進同一個 url-test 群組——兩家服務商的節點混在一起自動擇優,結果往往是流量全壓在延遲最低的那一家上,另一家的額度白白閒置,而且某家整體故障時切換體感很差。更好的結構是「每份訂閱各自一個自動測速群組,再用一個 fallback 把它們串起來」:主訂閱優先,主訂閱整體不可用時自動落到備用訂閱。這樣既保留了自動擇優,也把「換服務商」這件事降級成群組內切換。

filter 欄位在這裡很有用:同一個集合可以按關鍵詞派生出多個地區群組,例如用正規表示式篩出節點名裡帶特定地區標識的成員組成一個群組,規則裡再把特定業務指向該地區群組。要留意的是篩選依賴節點命名,服務商一旦改名就會出現空群組——群組內沒有可用成員時,核心會在啟動時報錯或讓該群組不可選,遇到這種情況先去看訂閱裡的節點名是否變了。

覆寫的除錯與衝突

覆寫寫錯了同樣有典型症狀:改動完全沒生效,或者訂閱裡原有的某個鍵整塊消失。前者多半是鍵名層級放錯了位置(比如把 fake-ip-filter 寫在頂層而不是 dns 之下),後者則是把「整鍵替換」當成了「局部合併」——只想加一條 fake-ip-filter,結果寫了個只含一條目的 dns 鍵,把訂閱裡其餘 DNS 設定全部覆蓋掉了。判斷方法很簡單:在用戶端裡查看最終產生的執行時設定,那份設定才是核心真正載入的內容,和你腦子裡以為的樣子對照一遍,衝突點立刻現形。養成「改覆寫 → 看執行時設定 → 再看日誌」的習慣,能省下大量猜測時間。

CH-07

外部控制與面板

核心運行時的一切狀態——節點延遲、活動連線、即時日誌、目前模式——都透過一套 RESTful API 對外暴露,這就是外部控制介面。用戶端裡的連線清單、Web 面板、命令列查詢,底層全是同一套 API。

external-controller: 127.0.0.1:9090
secret: "your-secret"
external-ui: ./ui

external-controller 聲明監聽位址與埠;secret 是存取權杖,所有請求需在標頭攜帶;external-ui 指向一個靜態面板目錄,核心會把它託管在同埠的 /ui 路徑下,瀏覽器直接存取即可。主流 Web 面板都是純前端專案,解壓進該目錄就能用。

用 curl 直接對話核心

# 查看全部策略群組與節點狀態
curl -H "Authorization: Bearer your-secret" \
  http://127.0.0.1:9090/proxies

# 切換「節點選擇」群組的目前出口
curl -X PUT -H "Authorization: Bearer your-secret" \
  -d '{"name": "自動測速"}' \
  http://127.0.0.1:9090/proxies/節點選擇

# 即時日誌流 / 活動連線
curl -H "Authorization: Bearer your-secret" \
  http://127.0.0.1:9090/logs
curl -H "Authorization: Bearer your-secret" \
  http://127.0.0.1:9090/connections

常用端點四個就夠記:/proxies(群組與節點)、/connections(活動連線,排查「這條流量走了哪個出口」最直接)、/logs(即時日誌流)、/configs(讀取與熱更新運行設定)。寫腳本做自動化——比如網路切換後自動換群組——也是圍繞這幾個端點。

安全底線:secret 必須設定且足夠複雜;監聽位址預設保持 127.0.0.1,確有區域網路管理需求再改成區域網路位址——把控制介面無驗證地暴露在 0.0.0.0 上,等於把整台裝置的流量調度權交給同網段的任何人。

iOS 場景補一句:Clash Plus 的內建面板在用戶端內部消費同一套介面,一般使用不需要手動設定本節內容;真正需要外部控制的,是桌面端除錯與路由器無頭部署兩類場景。

把 API 當成排查工具

外部控制介面最大的價值不是自動化,而是排查。當你懷疑某條流量走錯出口時,/connections 回傳的每條紀錄都帶著完整鏈路資訊:目標網域或 IP、命中的規則、最終使用的策略群組與節點、上下行位元組數、建立連線時間。把它和日誌對照,「規則為什麼沒命中」這類問題通常一眼就能定位——要麼命中了另一條更靠前的規則,要麼根本沒拿到網域(回到第五章的嗅探)。/proxies 則能一次性看到所有群組的目前選擇與各成員延遲,判斷是節點問題還是分流問題時非常高效。

/configs 支援熱更新部分執行時設定,比如切換 rule / global / direct 模式,或觸發一次設定重新載入。除錯階段用它可以省掉反覆重新啟動用戶端的時間,但要清楚一點:透過 API 做的臨時改動不會寫回設定檔,重新啟動即失效,真正要保留的改動仍然得落到設定或覆寫裡。

面板選擇與存取安全

Web 面板本身是純靜態前端,連接的是你填的控制器位址與權杖,因此「用哪個面板」不影響核心行為,只影響操作體驗。用 external-ui 讓核心自己託管面板的好處是同源存取、不用額外服務;缺點是升級面板要手動替換目錄。若選擇線上面板,請確認它以 HTTPS 提供且你信任其來源——填進去的權杖等同於裝置流量的控制權。

最後重申一次安全邊界,因為這是全篇唯一可能造成實質風險的設定項:控制器監聽位址、權杖複雜度、以及是否經過公網,三者只要有一項失守,任何能存取到該埠的人都可以讀取你的全部連線紀錄、切換出口、乃至替換設定。確有遠端管理需求時,正確做法是透過 SSH 通道或內網穿透把埠對應到可信通道上,而不是直接把 external-controller 改成 0.0.0.0 並在路由器上做埠轉發。到這裡八章內容結束,設定層面的問題基本都能在本頁找到入手點;剩下的就是按主題逐項驗證,把手冊變成你自己那份穩定設定。

手冊之外

設定語義都在上面,落地還差一個用戶端。iOS 首推 Clash Plus,全平台入口在下載中心;從零開始的主線操作,回教學頁按步驟走。