Clash 開發工具分流進階設定:rule-providers 與 YAML 實戰

GitHub 拉取失敗、npm 套件逾時或 Docker Hub 無法登入,往往與規則匹配和 DNS 路由有關。本篇以 rule-providers 搭配 YAML 模組化設定,建立適合日常開發與團隊維護的分流架構。

開發工具分流的目標與設計原則

GitHub 拉取失敗、npm 套件下載逾時、容器映像檔無法取得,表面上看起來像是節點速度不夠,實際上經常是規則沒有命中,或 DNS 解析與連線出口走了不同路徑。瀏覽器可以透過系統代理正常開啟網站,不代表終端機、Git、Node.js、Docker CLI 也會自動使用同一條代理通道。這些工具可能遵循環境變數、各自的代理設定,甚至直接連線,因此需要在 Clash 端建立明確且可維護的分流規則。

本篇使用 mihomo 核心的 rule-providersRULE-SET,把開發工具相關網域從主設定檔拆出去。主檔只保留策略組、DNS、提供者載入方式與規則順序;具體網域則放在獨立的 YAML 或純文字檔案裡。這樣做的好處是更新規則時不必反覆修改整份設定,也能讓個人設定與團隊共用規則分開管理。

  • 開發服務走代理。程式碼託管、套件登錄站、容器映像站與文件服務集中送往開發代理組。
  • 本地服務保持直連。區域網路、公司內部網域、localhost 與私有 IP 不應被送進遠端節點。
  • 一般境內流量不受影響。沒有命中開發規則的請求,仍依既有的境內直連與境外代理邏輯處理。
  • 規則檔可獨立更新。提供者有自己的下載週期、快取路徑與更新代理,不與整份設定檔的生命週期綁死。

先確認核心支援度

rule-providersRULE-SETGEOSITEPROCESS-NAMErespect-rules 等欄位主要針對 Clash Meta / mihomo。若用戶端仍選用已停止維護的原版核心,部分欄位可能被忽略或直接報錯。先在 Clash Verge Rev、Mihomo 類用戶端的核心資訊頁確認目前使用的是 mihomo,再套用以下範例。

rule-providers 的結構與更新機制

一個規則提供者通常包含五個關鍵欄位:typebehaviorurlpathinterval。其中 type: http 表示由網址下載規則檔;behavior 告訴核心下載內容是網域規則、IP 規則,還是完整 Clash 規則;path 是本機快取位置;interval 則是自動檢查更新的秒數。

rule-providers:
  dev-domains:
    type: http
    behavior: domain
    url: "https://rules.example.invalid/clash/dev-domains.yaml"
    path: ./ruleset/dev-domains.yaml
    interval: 86400
    proxy: DEV-PROXY

  dev-network:
    type: http
    behavior: ipcidr
    url: "https://rules.example.invalid/clash/dev-network.yaml"
    path: ./ruleset/dev-network.yaml
    interval: 86400
    proxy: DEV-PROXY

  dev-full:
    type: http
    behavior: classical
    url: "https://rules.example.invalid/clash/dev-full.yaml"
    path: ./ruleset/dev-full.yaml
    interval: 86400
    proxy: DEV-PROXY

behavior: domain 適合只包含網域的檔案,例如 DOMAIN-SUFFIX,packages.example.invalidbehavior: ipcidr 適合網段清單;behavior: classical 則適合每一行已經帶有規則類型與策略名稱的完整格式。提供者的行為類型必須和檔案內容一致,否則即使下載成功,核心也可能無法正確解析。

path 建議使用相對於設定檔的獨立目錄,例如 ./ruleset/。不要把快取放在作業系統暫存目錄,因為用戶端更新、權限變更或清理暫存檔後,規則提供者可能重新下載。若使用多份設定檔,還要確認每份設定檔的工作目錄不同;同名相對路徑可能造成誤以為規則已更新,實際上讀到的是另一份快取。

欄位用途實務建議
type提供者的取得方式遠端規則使用 http,本機內嵌規則可使用 inline
behavior宣告規則檔格式網域用 domain,網段用 ipcidr,完整規則用 classical
url遠端規則下載位址使用穩定的 HTTPS 位址,避免帶有短期失效的查詢參數
path本地快取檔案集中放在 ruleset 目錄,便於備份與檢查
interval自動更新週期,單位為秒每日更新可填 86400,頻繁變動的清單再縮短週期
proxy下載規則時使用的策略組遠端站點本身需要代理時,指定 DEV-PROXY

規則檔格式與 RULE-SET 引用方式

規則提供者只是把規則集中管理,真正把它套用到流量上的,是 rules 區段中的 RULE-SET。引用格式為 RULE-SET,提供者名稱,策略組,提供者名稱必須與 rule-providers 下的鍵完全一致,大小寫與連字號都不能寫錯。

網域型提供者的檔案可以只保留網域後綴。這種檔案內容簡單,適合團隊共同維護,也不會把策略名稱寫死在規則檔裡:

payload:
  - "+.code.example.invalid"
  - "+.packages.example.invalid"
  - "+.container.example.invalid"
  - "registry.example.invalid"

如果採用完整的 classical 格式,則每一行都要描述規則類型與參數。例如同一份檔案可能同時放網域、網段與程序規則:

payload:
  - DOMAIN-SUFFIX,code.example.invalid
  - DOMAIN-SUFFIX,packages.example.invalid
  - DOMAIN-KEYWORD,container
  - IP-CIDR,203.0.113.0/24,no-resolve
  - PROCESS-NAME,dev-cli.exe

對開發工具而言,優先使用 DOMAIN-SUFFIX,其次才是 DOMAINDOMAIN-SUFFIX,packages.example.invalid 可以同時涵蓋主網域與其子網域,例如下載端點、API 端點與鏡像端點;DOMAIN 只適合精確固定的主機名稱。DOMAIN-KEYWORD 很容易把不相關的服務誤送進代理,例如關鍵字出現在公司內部網域中,因此不應作為主要分流依據。

主設定檔可以這樣引用:

rules:
  - RULE-SET,dev-domains,DEV-PROXY
  - RULE-SET,dev-network,DIRECT
  - RULE-SET,dev-full,DEV-PROXY
  - GEOSITE,cn,DIRECT
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

RULE-SET 不是自動優先

提供者被放進 rule-providers 後,不會自動影響任何連線;只有在 rules 裡透過 RULE-SET 引用才會生效。另一方面,規則仍遵循由上到下、第一個命中即停止的原則。若把 MATCH,PROXY 放在開發提供者之前,後面的 RULE-SET 全部都不會被執行。

小型團隊的 inline 提供者

規則數量很少且不需要遠端更新時,可以直接使用 inline,避免額外的下載失敗:

rule-providers:
  team-internal:
    type: inline
    behavior: domain
    payload:
      - "+.corp.example.invalid"
      - "+.git.corp.example.invalid"
      - "+.artifacts.corp.example.invalid"

這種寫法適合公司內部網域、測試環境與固定的私有服務,不適合頻繁變動的公共規則。團隊成員更新設定檔後即可同步內容,但每次調整都要重新分發主設定檔,維護彈性不如遠端 HTTP 提供者。

開發工具策略組與 DNS 路由

開發流量最好使用獨立策略組,不要直接把所有規則指向通用的 PROXY。這樣可以在 Git 拉取速度下降、套件下載失敗或容器登入異常時,單獨切換開發節點,而不影響瀏覽器的其他連線。

proxy-groups:
  - name: DEV-PROXY
    type: select
    proxies:
      - DEV-AUTO
      - PROXY
      - DIRECT

  - name: DEV-AUTO
    type: url-test
    url: "https://connectivity-check.example.invalid/ping.txt"
    interval: 300
    tolerance: 80
    proxies:
      - node-a
      - node-b
      - node-c

select 適合需要手動指定地區或節點的情況;url-test 會定期測試延遲並選擇較快的節點。測試網址只代表可達性與回應速度,不代表該節點一定能使用所有開發服務。若套件站點需要特定地區出口,應優先使用手動選擇的節點,再用命令列測試實際下載。

開發工具的 DNS 解析也要和分流策略一致。mihomo 可透過 respect-rules 讓 DNS 查詢參考分流規則;對需要代理的網域,則使用代理側的解析器,避免本地 DNS 先回傳錯誤或被污染的結果:

dns:
  enable: true
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  respect-rules: true
  default-nameserver:
    - 192.0.2.53
  nameserver:
    - https://dns.example.invalid/dns-query
  proxy-server-nameserver:
    - https://dns-proxy.example.invalid/dns-query

proxy-server-nameserver 的用途是解析節點伺服器本身的網域,不能把它誤認為所有應用程式請求的唯一 DNS。若代理節點使用 IP 位址,這個欄位對節點啟動的影響較小;若節點位址是網域名稱,則應提供一條能在目前網路環境下穩定連線的解析路徑。

  • Git 拉取逾時:先檢查程式碼託管網域是否命中 dev-domains,再確認 Git 使用的是 HTTP 代理還是 TUN 接管。
  • npm 安裝卡住:查看套件登錄站與其依賴下載網域是否分散在不同後綴,不能只加入一個主站網域。
  • 容器登入失敗:登入服務、令牌服務與映像層下載服務可能使用不同網域,必須在規則檔中逐一確認。
  • 內部套件被送出外部:把公司內部網域與私有網段放在開發代理規則之前,並指定 DIRECT

YAML 模組化實戰:從主檔到規則檔

較適合日常維護的做法,是把設定拆成四個責任清楚的部分:主檔負責埠與模式,策略組負責出口選擇,規則提供者負責網域集合,rules 則負責最終優先順序。不要把數百條開發網域直接塞進主檔,也不要把 DNS、策略組與規則全部混成一個難以審查的長檔案。

mixed-port: 7890
mode: rule
allow-lan: false
log-level: info
unified-delay: true

proxy-groups:
  - name: DEV-PROXY
    type: select
    proxies:
      - DEV-AUTO
      - PROXY
      - DIRECT

rule-providers:
  dev-domains:
    type: http
    behavior: domain
    url: "https://rules.example.invalid/dev-domains.yaml"
    path: ./ruleset/dev-domains.yaml
    interval: 86400
    proxy: DEV-PROXY

  dev-direct:
    type: http
    behavior: domain
    url: "https://rules.example.invalid/dev-direct.yaml"
    path: ./ruleset/dev-direct.yaml
    interval: 86400

rules:
  - RULE-SET,dev-direct,DIRECT
  - RULE-SET,dev-domains,DEV-PROXY
  - DOMAIN-SUFFIX,localhost,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - GEOSITE,cn,DIRECT
  - GEOIP,CN,DIRECT
  - MATCH,PROXY

這份範例把內部網域放在 dev-direct,並且置於外部開發網域之前。若同一個請求同時符合兩個提供者,前面的規則優先。私有 IP 規則使用 no-resolve,避免 Clash 為了判斷內網網段而額外解析尚未解析的網域。

規則檔的命名應表達用途,而不是只用日期。例如 dev-domains.yaml 代表開發服務網域集合,dev-direct.yaml 代表必須直連的內部服務。若規則由多人維護,可以在檔案外部文件中記錄來源、負責人、更新頻率與測試方式;規則檔內則維持單純格式,減少不同核心對註解或額外欄位的相容性差異。

YAML 與提供者的常見錯誤

  • 縮排錯誤:YAML 只接受正確的層級關係,建議固定使用兩個空白,不要混用 Tab。
  • 鍵名不一致:dev-domainsdev_domain 是兩個不同名稱,引用時必須逐字相同。
  • 格式宣告錯誤:檔案內容是 DOMAIN-SUFFIX,...,卻宣告成 behavior: domain,核心可能無法載入。
  • 網址可開但檔案無效:遠端網址回傳登入頁、JSON 錯誤訊息或 HTML 時,下載動作看似成功,規則仍然不會生效。
  • 代理組名稱不存在:proxy: DEV-PROXY 指向的策略組必須已在設定檔中定義,不能只在規則裡臨時命名。

驗證、除錯與團隊維護流程

設定完成後,不要只用瀏覽器開啟首頁判定成功。開發工具分流必須分別驗證「規則有載入」、「請求有命中」與「應用程式真的使用代理」三個層次。Clash Verge Rev 或其他 mihomo 面板通常可以在設定檔頁面查看提供者狀態、在連線頁面查看實際命中的規則,並在日誌中觀察 DNS 與連線錯誤。

  1. 重新載入設定檔,確認 rule-providers 頁面出現每個提供者,狀態不是載入失敗或檔案格式錯誤。
  2. 打開提供者詳情,檢查規則數量與最近更新時間。規則數量顯示為零時,先檢查遠端內容是否真的包含 payload
  3. 在規則模式下執行一個明確的測試,例如以假的網域 packages.example.invalid 進行解析與連線觀察,確認命中 dev-domains
  4. 再測試公司內部假的網域 git.corp.example.invalid,確認它先命中 dev-direct,沒有被後面的代理規則攔截。
  5. 若命令列仍逾時,檢查該工具的代理環境變數、TUN 狀態、DNS 查詢結果與實際出口,不能只看 Clash 是否顯示有連線。

Git、npm 與 Docker 類工具的代理設定位置不完全相同。Git 常見做法是設定 HTTP 與 HTTPS 代理;npm 可以在其設定中指定代理;容器工具則可能由環境變數、守護程序設定或桌面端的代理頁面決定。Clash 端規則命中,只能證明流量進入核心;如果工具本身沒有把請求交給系統代理,也沒有啟用 TUN,核心就不可能看見這筆連線。

git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890

npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890

以上命令只適合需要明確指定代理的測試環境,實際使用前要確認埠號與用戶端設定一致。若日後切換用戶端或改用 TUN,舊的全域代理設定可能造成重複代理、憑證錯誤或請求繞路;排查完成後,可用 git config --global --unset http.proxy 等命令清理不再需要的設定。

建議的團隊變更流程

每次新增網域先記錄服務名稱與用途,再加入最小範圍的 DOMAINDOMAIN-SUFFIX;不要為了「先能用」直接加入 DOMAIN-KEYWORD。提交前以直連、開發代理與全域代理三種模式各測一次,確認內部服務不外送、外部服務不誤走直連,最後才提高 interval 或發布新的規則檔。

當 GitHub 拉取失敗、npm 逾時或容器登入異常時,建議依照「提供者狀態 → 規則命中 → DNS 解析 → 工具代理 → 節點出口」的順序檢查。這個順序可以把設定錯誤、核心錯誤與服務端限制分開,不必一開始就反覆更換節點。完成模組化後,主設定檔會更短,規則更新更容易追蹤,開發環境也能在不影響一般上網的前提下保持穩定。

下載 Clash 用戶端

規則分流的前提是用戶端先接管流量。前往下載中心依平台選擇用戶端,再回到教學文章完成系統代理或 TUN 接管設定。

下載Clash