進階原理 預計閱讀 14 分鐘

Clash 設定檔結構逐段解析:從 port 到 rules 讀懂 YAML

完整拆解 Clash 設定檔:通用欄位、DNS、proxies 節點、proxy-groups 策略組與 rules 規則清單,搭配範例說明欄位用途及常見寫法錯誤。

先看懂設定檔的處理流程

一份 Clash 或 mihomo 設定並不只是單純的「節點清單」。核心啟動時會先解析 YAML,接著建立本機監聽連接埠、DNS 模組、代理節點與策略組,最後依照 rules 由上而下比對連線。某個區段通過語法檢查,不代表它與其他區段的引用一定正確:規則可能指向不存在的策略組,策略組也可能引用已改名的節點。

理解設定時,可以將檔案分成五層:基礎執行參數負責連接埠與工作模式;DNS 區段負責網域解析;proxies 定義可用的單一出站;proxy-groups 將出站整理成可手動選擇或自動測試的策略;rules 決定各類連線最後交由哪項策略處理。訂閱設定還可能加入 proxy-providersrule-providers,用來從外部檔案載入節點或規則集合。

YAML 最容易出錯的三個基礎重點

  • 階層使用空格縮排,不能使用 Tab。常見做法是每層縮排 2 個空格。
  • 冒號後通常要留一個空格,例如 mode: rule;列表項目以連字號加空格開頭。
  • truefalse、數字與字串的含義不同。連接埠寫成 7890,而包含特殊字元的名稱或密碼則適合加上引號。

常見桌面客戶端可從「設定」→選取目前設定→「編輯」開啟 YAML;儲存後再進入「設定」→「重新載入」或「套用」。不同客戶端的按鈕名稱略有差異,但檢查順序相同:先儲存,確認核心沒有回報解析錯誤,再測試代理連線。排除問題時可進入「日誌」→「日誌層級」→「debug」,完成定位後改回 info,避免長時間記錄大量除錯資訊。

通用欄位:連接埠、模式與控制介面

設定檔開頭通常是本機監聽與核心執行參數。以下是一組適合本機桌面環境閱讀的範例,其中 HTTP 代理監聽 7890,SOCKS5 代理監聽 7891,外部控制介面只繫結本機迴路位址:

port: 7890
socks-port: 7891
allow-lan: false
bind-address: "*"
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
secret: "change-this-token"
欄位 具體作用 常見判斷
port 提供 HTTP 代理監聽連接埠 系統代理通常設定為 127.0.0.1:7890
socks-port 提供 SOCKS4、SOCKS5 代理入口 支援 SOCKS5 的應用程式可連線至 127.0.0.1:7891
mixed-port 在同一連接埠同時接受 HTTP 與 SOCKS 連線 使用它時通常不必再另外設定相同用途的連接埠
allow-lan 決定區域網路裝置能否連線至本機代理連接埠 啟用後還要檢查繫結位址、系統防火牆與存取控制
mode 選擇 ruleglobaldirect 日常使用通常採用 rule
external-controller 向圖形介面或面板提供控制 API 僅供本機使用時,繫結 127.0.0.1 更合適

mode: rule 表示讓每條連線進入規則比對;global 會將連線統一交給全域策略;direct 則直接連線。這裡的模式不是某種代理協定,也不會改變節點本身的參數。遇到「節點可以測速,但指定網站沒有走代理」時,應先檢查目前是否誤切換到直連模式,再確認規則命中了哪項策略。

區域網路分享不能只切換一個開關

allow-lan 改為 true 後,手機或其他電腦還要使用執行 Clash 裝置的區域網路位址,例如 192.168.1.20:7890,而不是對方裝置自己的 127.0.0.1。同時需要放行 TCP 7890 連接埠。若電腦位址由 DHCP 自動分配,重新連線路由器後可能改變,適合在路由器中為該裝置設定固定租約。

DNS 區段:解析路徑與 fake-ip 模式

DNS 設定決定網域如何取得 IP 位址,也會影響網域規則能否穩定命中。mihomo 常見的增強模式包括 fake-ipredir-host。前者會向應用程式回傳保留位址池中的映射位址,核心收到連線後再還原網域;後者則更接近傳統的實際位址解析流程。TUN 模式下使用 fake-ip 往往能保留更多網域資訊,但部分區域網路服務、連線檢測或依賴實際位址的應用程式需要加入過濾清單。

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver:
    - 223.5.5.5
    - 1.1.1.1
  nameserver:
    - https://dns.alidns.com/dns-query
    - https://1.1.1.1/dns-query
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query
  fake-ip-filter:
    - "*.lan"
    - "*.local"
    - "time.*.com"
    - "+.msftconnecttest.com"

default-nameserver 主要負責引導解析,因此一般填寫純 IP 的 DNS 位址;如果加密 DNS 伺服器本身以網域名稱表示,核心需要先知道要在哪裡解析該網域。nameserver 是一般查詢使用的上游伺服器。mihomo 中的 proxy-server-nameserver 可專門解析代理伺服器網域,減少「節點位址尚未解析,DNS 查詢卻又等待代理節點」的依賴問題。

DNS 設定有效但仍然無法開啟網站時

  1. 查看日誌中是否出現 dns resolve failed、逾時或憑證連線錯誤。
  2. 確認系統或 TUN 的 DNS 請求確實進入核心監聽,而不是繼續傳送至舊的區域網路 DNS。
  3. 暫時將 enhanced-mode 改為 redir-host 後重新測試,用來判斷問題是否與 fake-ip 相容性有關。
  4. 檢查 fake-ip-filter,只將確實有相容性問題的網域加入清單,避免使用涵蓋範圍過大的萬用字元規則。
  5. 分別測試網域與 IP。能存取 IP、卻無法存取網域時,通常應優先排查 DNS;兩者都失敗則繼續檢查策略組與節點連線。

範例中的 198.18.0.1/16 是常見的 fake-ip 位址池。應用程式看到這個位址,不代表網站實際部署於此,而是核心維護的暫時映射。封包擷取時若反覆看到 198.18.x.x,應搭配 Clash 日誌中的原始網域判斷,不能直接將它當成遠端伺服器位址。

proxies:如何將單一節點寫成 YAML

proxies 是節點物件清單。每個物件至少要有唯一的 name、協定 type、伺服器位址 server 與連接埠 port,其餘欄位取決於具體協定。以下以 Shadowsocks 與 SOCKS5 示範結構,範例網域與憑證僅用於說明格式:

proxies:
  - name: "東京-SS"
    type: ss
    server: ss-node.example.com
    port: 443
    cipher: aes-128-gcm
    password: "demo-password"
    udp: true

  - name: "本機-SOCKS"
    type: socks5
    server: 192.168.1.30
    port: 1080
    username: "proxy-user"
    password: "demo-password"
    udp: false

欄位名稱必須符合協定定義。Shadowsocks 使用 cipherpassword,SOCKS5 可帶有 usernamepassword;其他協定還會涉及 TLS、傳輸層、伺服器名稱等參數。不能因為兩個節點都在圖形介面中顯示為一行,就將一種協定的欄位直接複製到另一種協定。

節點名稱其實是引用鍵

name 不只用於顯示,也會被策略組逐字引用。若節點定義為「東京-SS」,策略組中寫成「東京 SS」,中間字元不同就會成為無效引用。節點名稱也不宜與策略組同名,否則閱讀日誌和規則目標時,很難快速判斷指向哪一層。

  • 同一清單內保持名稱唯一,可採用「地區-協定-編號」的固定格式。
  • 包含冒號、井號、星號或前後空格的名稱應加上引號,避免 YAML 將字元解讀為語法。
  • udp: true 只表示該節點設定允許 UDP,實際可用性還取決於協定、伺服器端與接管方式。
  • 伺服器位址填寫網域名稱時,也要同步檢查用於解析節點網域的 DNS 路徑。

proxy-groups:從節點到可操作的策略

規則通常不會直接指向某個固定節點,而是指向策略組。如此便能在「工作服務」、「串流影音」、「預設代理」等不同用途之間獨立選擇出站。策略組也是客戶端代理頁面的主要操作對象,使用者切換的通常不是規則,而是某個 select 組目前選取的成員。

proxy-groups:
  - name: "手動選擇"
    type: select
    proxies:
      - "自動測速"
      - "東京-SS"
      - "本機-SOCKS"
      - DIRECT

  - name: "自動測速"
    type: url-test
    proxies:
      - "東京-SS"
      - "本機-SOCKS"
    url: "https://www.gstatic.com/generate_204"
    interval: 300
    tolerance: 50
    lazy: true

  - name: "預設代理"
    type: select
    proxies:
      - "手動選擇"
      - "自動測速"
      - DIRECT
組類型 選擇邏輯 適用情境
select 由使用者手動選擇成員 需要明確指定地區、線路或直連時
url-test 定期請求測試網址,選擇延遲較低的成員 節點較多,希望自動選擇較佳節點時
fallback 依序使用可用成員,目前成員失效後切換 重視固定優先順序與故障轉移時
load-balance 依指定策略將不同連線分配給多個成員 需要分散連線且上游條件允許時

範例中的 interval: 300 表示每 300 秒進行一次週期測試,tolerance: 50 表示延遲差異較小時避免頻繁切換。測速值只反映向測試 URL 發出請求所需的時間,不等同於下載頻寬。一次實測中,節點 A 延遲 86 毫秒、節點 B 延遲 112 毫秒,只能表示 A 對該測試位址回應較快;存取其他地區的服務時,結果可能相反。

檢查策略組的循環引用

策略組可以引用其他策略組,但不能形成循環。例如「預設代理」包含「手動選擇」,而「手動選擇」又包含「預設代理」,核心就無法取得最終出站。閱讀複雜設定時,從規則目標開始往下追蹤:規則指向哪個組、該組包含哪些成員、成員最後能否落到節點或 DIRECTREJECT

rules:依序決定每條連線的去向

rules 是一份有順序的比對清單。連線會從第一條開始檢查,命中後立即採用該條指定的策略,不再繼續往下比對。精確規則應放在寬泛規則之前,最後通常使用 MATCH 接住前面未命中的流量。

rules:
  - DOMAIN,api.example.com,預設代理
  - DOMAIN-SUFFIX,example.net,預設代理
  - DOMAIN-KEYWORD,video,手動選擇
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,預設代理

DOMAIN 比對完整網域;DOMAIN-SUFFIX 比對指定網域及其子網域;DOMAIN-KEYWORD 只要網域包含關鍵字就可能命中,範圍更廣,誤匹配機率也更高。IP-CIDR 依位址區段判斷,GEOIP 依賴核心載入的地理資料庫,MATCH 則是兜底規則。

no-resolve 常用於 IP 類規則,表示比對時不要為了取得 IP 而額外解析網域。它不是所有規則都必須加上的固定後綴。網域規則本來就依據網域判斷,而某些需要位址結果的情境仍須正常解析。

為什麼規則看似正確卻沒有命中

  1. 前面已有更寬泛的規則:例如先寫 DOMAIN-SUFFIX,example.com,DIRECT,後面的 DOMAIN,api.example.com,預設代理 就永遠沒有機會執行。
  2. 應用程式直接存取 IP:日誌只看得到目標位址,沒有網域資訊,此時網域規則無法參與比對,可搭配 IP 規則或調整 DNS 接管方式。
  3. 策略名稱拼寫不同:規則目標必須與 proxy-groups 中的名稱完全一致。
  4. 設定沒有重新載入:編輯的是本機檔案,但客戶端仍在執行舊設定。應儲存後執行「設定」→「重新載入」,再觀察日誌。
  5. 連線沒有重新建立:既有 TCP 或 QUIC 工作階段可能繼續沿用舊路徑。關閉應用程式連線,等待數秒後再測試,較容易取得明確結果。

provider 區段:將節點與規則拆分至外部檔案

當節點來自訂閱、規則集合數量較大時,可以使用 provider。proxy-providers 管理外部節點集合,rule-providers 管理規則集合。provider 不會自動決定流量去向:節點 provider 仍須被策略組引用,規則 provider 仍須透過 RULE-SET 寫入 rules

proxy-providers:
  airport:
    type: http
    url: "https://subscription.example.com/clash.yaml"
    path: ./providers/airport.yaml
    interval: 3600
    health-check:
      enable: true
      url: "https://www.gstatic.com/generate_204"
      interval: 600

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

節點 provider 可透過策略組中的 use 引入,規則 provider 則需要寫成 RULE-SET,private-sites,DIRECTbehavior 必須與規則檔案內容相符:domain 面向網域規則,ipcidr 面向位址區段,classical 可容納經典規則表示式。格式宣告與檔案內容不一致時,常見結果是 provider 下載成功但解析失敗。

proxy-groups:
  - name: "訂閱自動選擇"
    type: url-test
    use:
      - airport
    url: "https://www.gstatic.com/generate_204"
    interval: 300

rules:
  - RULE-SET,private-sites,DIRECT
  - MATCH,訂閱自動選擇

interval: 3600 表示節點 provider 每 3600 秒嘗試更新,規則範例中的 86400 則是 24 小時。更新頻率應配合來源變化速度設定;過短會產生不必要的網路請求,過長則可能讓已調整的節點或規則遲遲無法生效。

如何串起一份易讀的最小設定

整合前面的結構後,可以得到一份便於學習的最小設定。它不是通用成品,因為節點協定、DNS 上游與分流目標仍需依實際環境填寫,但能清楚展示欄位之間的引用關係:

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver:
    - 223.5.5.5
  nameserver:
    - https://dns.alidns.com/dns-query
  fake-ip-filter:
    - "*.lan"
    - "*.local"

proxies:
  - name: "東京-SS"
    type: ss
    server: ss-node.example.com
    port: 443
    cipher: aes-128-gcm
    password: "demo-password"
    udp: true

proxy-groups:
  - name: "代理"
    type: select
    proxies:
      - "東京-SS"
      - DIRECT

rules:
  - DOMAIN-SUFFIX,example.net,代理
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,代理

連線至 api.example.net 時,核心先透過 DNS 區段處理網域解析,再由 DOMAIN-SUFFIX,example.net,代理 命中「代理」組。如果組內目前選取「東京-SS」,連線就會交給該節點;若使用者在代理頁將組切換為 DIRECT,同一條規則仍會命中,但最終改為直接連線。這也是「規則」與「策略選擇」需要分開理解的原因。

儲存後的驗證順序

  1. 先檢查 YAML 縮排、列表符號與冒號後的空格。
  2. 確認每個規則目標都能在策略組中找到,每個策略組成員都能落到節點或內建策略。
  3. 重新載入設定,查看啟動日誌是否出現欄位錯誤、引用失敗或連接埠遭占用。
  4. 確認 789090901053 等連接埠沒有被其他程式占用。
  5. 分別使用一個直連目標與一個代理目標進行測試,並在日誌中核對實際命中的規則。
  6. 最後再啟用系統代理或 TUN,避免同時變更多個變數而難以定位問題。

如果核心啟動後立即退出,最有效的排查方式不是大幅刪除設定,而是逐段縮小範圍:先保留通用欄位與一個可用節點,再加入策略組,接著加入 DNS,最後恢復規則與 provider。每加入一段就重新載入一次,便能將錯誤定位到特定欄位。以 200 行設定為例,分五段逐步恢復通常只需載入 5 至 8 次,比逐行猜測更快。

常見誤區與維護建議

把訂閱連結直接當成節點位址

訂閱 URL 回傳的是節點集合或完整設定,不是某個節點的 server。完整訂閱應交由客戶端的訂閱管理或 proxy-providers 處理,單一節點資訊則依協定欄位寫入 proxies。兩者的資料層級不同,不能互換。

只看測速數字,不看策略命中結果

節點測速成功,表示核心能透過該節點存取測試位址,但業務連線可能被規則送往 DIRECT、另一個策略組或另一個節點。排除問題時應先在日誌中確認規則目標,再查看策略組目前的選擇,最後檢查節點連線結果。

把所有問題都歸咎於 DNS

DNS 只負責解析流程的一部分。連接埠遭占用、系統代理未啟用、TUN 路由未接管、規則順序錯誤、策略組為空、節點協定參數不相容,都可能表現為「網頁無法開啟」。採用分層檢查法,比反覆更換 DNS 位址可靠。

長期直接編輯自動更新的設定

訂閱重新整理後,手動加入的規則、策略組或 DNS 欄位可能被重新產生的內容取代。長期維護應明確分層:訂閱負責更新節點,本機覆寫負責固定參數,規則 provider 負責大規模規則集合,少量個人規則放在順序可控的前置規則區。如此更新節點時,不需要重新合併整份 YAML。

尋找對應客戶端 依平台前往下載頁