一、YAML 總覽:從檔案結構到生效設定
Clash 設定不是一張節點位址表,而是一組彼此引用的物件。通用欄位宣告入口與工作模式,DNS 欄位決定核心如何解析網域名稱,代理節點定義可用出口,策略組組織出口,規則則將連線交給指定目標。閱讀陌生設定時,先查看頂層有哪些鍵,再追蹤名稱引用;直接從數百條規則往下讀,容易忽略真正控制連線路徑的入口設定與最終策略。
縮排、映射與清單
YAML 使用縮排表達層級。冒號後接一個空格表示鍵和值,短橫線開頭通常表示清單元素。建議統一使用兩個空格縮排,不要混用定位字元;同一層級必須對齊。頂層的 dns 與 rules 需對齊,而 enable 放在 DNS 下方。可以使用中文名稱,但名稱中的空格、標點與大小寫都屬於引用內容,不能在其他位置任意變更。
連接埠使用整數,開關使用不加引號的 true 或 false。網域模式、密碼、含冒號或井字號的字串建議加上引號,避免被解讀為映射、註解或其他型別。井字號只有在字串外才具有註解作用。也應避免重複頂層鍵:不同解析器可能報錯,也可能只保留其中一份,不能靠重複撰寫兩段規則清單來實現追加。
# 完整的直連教學設定,不包含遠端代理節點
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
dns:
enable: false
proxies: []
proxy-groups: []
rules:
- MATCH,DIRECT
這份設定可用於支援這些欄位的核心進行基本啟動測試;在連接埠未被占用時,會建立本機混合代理入口,但所有符合條件的連線仍會直連。應用程式還必須明確使用該入口,設定才會參與請求處理。它不提供遠端出口,也未啟用核心 DNS。請將它另存為獨立測試檔案,不要直接覆蓋正在使用的訂閱,否則原有節點與規則會被移除。
先辨識輸入檔案所屬層級
訂閱 URL 是取得內容的位址,不代表回傳內容必然是完整 YAML。有些回傳整份設定,有些只有節點清單,有些則回傳編碼文字或單一節點分享連結。完整設定應放入設定匯入入口,節點集合則可能需要由用戶端轉換,或由 proxy-providers 引用。入口選錯時,即使位址可以下載,也可能出現欄位缺失、解析失敗或規則目標不存在。
設定檔也可能經過用戶端二次加工。訂閱原文保存服務方提供的內容,本機設定保存連接埠、接管方式等偏好,覆寫檔案用於插入或替換部分欄位,最終產生的檔案才會交給核心。編輯某一層後,應找到用戶端的執行設定預覽或匯出入口,確認變更是否進入最終檔案。介面顯示某個數值,並不代表訂閱檔案中的同名欄位具有最終優先級。
沿著引用關係檢查,而不只是查看語法
規則中的策略名稱必須對應節點、策略組或內建目標;策略組中的節點名稱也必須存在。名稱正確還不夠,組與組之間不能形成循環引用。建議依節點、策略組、規則的順序閱讀:先了解有哪些出口,再了解如何選擇出口,最後查看哪些連線會被送往那裡。遇到規則提供器或代理提供器時,還要檢查其路徑、格式與載入結果,不要把頂層宣告當成已成功載入。
開始修改前,記錄目前的用戶端名稱、核心類型與設定來源,並匯出一份可還原的副本。優先保留可正常運作的設定,一次只變更一個主題,再驗證差異。若尚未安裝用戶端,可先前往用戶端下載頁考慮 Clash Plus,再依平台與所需功能比較其他入口。匯入格式的進一步區分請參閱訂閱連結與 YAML 匯入說明。
二、通用欄位:連接埠、模式與存取界線
通用設定欄位決定本機程式如何進入代理,以及核心收到連線後採用哪種處理模式。最容易混淆的是本機監聽連接埠與遠端節點連接埠:前者由裝置上的核心提供,後者屬於伺服器端連線參數。將節點伺服器連接埠填入系統代理設定,不會自動建立連線;系統代理通常需要填寫本機監聽位址與對應的 HTTP 代理連接埠,而節點連接埠則保留在節點定義內。
選擇監聽入口,核對實際占用情況
| 欄位 | 用途 | 修改前檢查 |
|---|---|---|
port | HTTP 代理入口 | 應用程式是否支援 HTTP 代理設定。 |
socks-port | SOCKS 代理入口 | 應用程式使用的 SOCKS 協定及解析方式。 |
mixed-port | 在同一連接埠接收 HTTP 與 SOCKS 請求 | 該連接埠是否已被其他程序占用。 |
allow-lan | 是否允許區域網路存取代理入口 | 監聽位址、防火牆及存取驗證。 |
mode | 規則、全域或直連模式 | 用戶端是否會覆蓋檔案中的模式。 |
對一般桌面教學設定而言,先使用一個混合連接埠更容易定位問題。只有應用程式確實需要獨立入口時,才設定 HTTP 或 SOCKS 連接埠。不要讓不同監聽欄位重複占用同一連接埠,也不要在圖形用戶端已經執行時,再啟動另一份使用相同連接埠的核心。發生監聽失敗時,應先辨識占用者;任意更換連接埠後若忘記更新系統代理,只會把錯誤從啟動階段轉移到連線階段。
# 通用欄位片段,監聽連接埠僅供教學
mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false
這裡將監聽限制為本機用途。bind-address 對各入口的具體影響需結合核心與用戶端產生的結果確認,不能僅憑檔案判斷外部可存取性。應用程式應連線至 127.0.0.1:7890,而不是把它當成遠端節點。桌面系統的代理設定、瀏覽器獨立代理設定與終端機環境變數可能彼此不同,因此同一台裝置上的不同程式可能採用不同路徑。
模式選擇與流量接管是兩回事
rule 會依規則順序為已進入核心的連線選擇目標;global 使用全域策略處理這些連線;direct 使用直連。全域模式不是作業系統層級的完整接管,無法保證所有程式都進入代理。反過來,啟用 TUN 也不代表所有請求都會經過遠端節點:流量進入核心後,仍可由規則決定直連、拒絕或代理。
系統代理主要影響遵循系統代理設定的應用程式;TUN 透過虛擬網路介面及配套路由接管流量,可能需要管理員權限、服務元件或行動平台 VPN 授權。不要為了驗證一個網頁而同時修改系統代理、TUN、DNS 與模式。先確認單一應用程式能透過明確的本機連接埠存取,再決定是否需要擴大接管範圍;具體安裝與授權步驟可回到模式與接管教學。
區域網路開放、日誌與 IPv6
只有其他可信任裝置需要使用本機代理時,才考慮開啟區域網路存取。此時還要檢查監聽網卡、防火牆入站規則與代理驗證,並避免路由器將該入口轉發至公網。代理入口與控制介面不是同一項服務;後者可能具備切換策略、讀取連線及修改設定的能力。若沒有遠端管理需求,應讓控制介面僅限本機使用,不要為了解決連線問題而擴大管理權限。
log-level: info 適合日常觀察。排錯時可暫時提高日誌詳細程度,以查看更多錯誤上下文,但日誌可能包含網域、節點位址與連線中繼資料,分享前需要去除敏感資訊。排錯結束後再恢復日誌級別,避免持續寫入大量紀錄。日誌是否寫入磁碟、保留多久及儲存位置,通常還受用戶端管理,不能只查看核心的級別欄位。
頂層 ipv6 與 DNS 區域中的同名欄位作用層面不同,作業系統本身也可能繼續使用 IPv6。範例關閉它只是為了簡化測試路徑,不是通用的網路最佳化建議。需要雙堆疊存取時,應同時核對解析結果、路由、接管範圍以及節點是否能到達目標;只修改一個開關,無法證明不存在繞過代理的連線。任何通用欄位修改,都應以最終監聽狀態與實際請求路徑作為驗收依據。
三、DNS 處理:解析入口、上游與 Fake-IP
DNS 設定首先要回答誰發起查詢、誰接收查詢,以及如何抵達上游。核心啟用 DNS 服務,不代表系統與所有應用程式會自動使用它;瀏覽器內建的加密 DNS、應用程式自己的解析器及其他 VPN 都可能形成獨立路徑。排查時應畫出應用程式、系統解析器、核心 DNS 與上游伺服器之間的順序,先確認請求確實進入目標入口,再討論回傳位址是否正確。
基礎欄位與解析依賴
# DNS 片段;不會自動改寫作業系統的 DNS 設定
dns:
enable: true
listen: "127.0.0.1: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"
listen 宣告核心 DNS 的監聽位址。範例使用本機非標準連接埠,適合進行明確查詢測試,但多數系統網路設定無法直接填寫這類連接埠。要讓一般應用程式使用它,還需要用戶端提供的 DNS 接管、轉送或 TUN 劫持機制;不要只把系統 DNS 設定為一個未在標準連接埠監聽的位址。範例中的上游只是可替換物件,其可達性取決於目前網路。
nameserver 設定一般解析上游,default-nameserver 通常用於解析上游 DNS 位址本身的網域名稱。若加密 DNS 伺服器以網域名稱作為位址,核心必須先知道該網域名稱對應的 IP,才能建立加密連線。這個引導過程不能反過來完全依賴尚未建立的同一解析通道,否則可能形成依賴迴圈。修改上游前,先確認它在目前網路中確實可達。
Fake-IP 保存網域名稱映射關係
Fake-IP 模式可為網域名稱回傳一個虛擬位址,核心會保留該位址與網域名稱的映射。之後應用程式連線至虛擬位址時,核心會依此還原網域名稱資訊並執行後續處理。虛擬位址不是目標網站的真實伺服器位址,因此在系統查詢結果中看到它,不應立即認定解析遭到污染。能否完成連線,還取決於相應連線是否由同一核心接管,以及映射是否仍然有效。
傳統的真實位址回傳方式通常更容易相容於要求真實 IP 的程式,但在連線階段可能需要其他機制才能保留或還原網域名稱資訊。選擇模式時,應以應用程式相容性與接管方案為依據,而不是將某種模式視為必然更快的選項。切換增強模式後,系統或應用程式仍可能快取舊結果;先清除相關快取、重建連線,再比較現象,避免把快取差異誤認為模式差異。
fake-ip-filter 用於排除不適合回傳虛擬位址的網域名稱,常見起點是區域網路服務與依賴真實位址的應用程式。範例只說明清單結構,並不保證涵蓋所有內網名稱。特別是 .local 服務可能還依賴組播 DNS,不能靠加入排除項目解決所有探索問題。排除虛擬位址也不等於指定直連:解析方式與連線策略需要分別檢查。
依網域名稱選擇上游與判斷 DNS 洩漏
# 合併至現有 dns 映射中,不要再增加第二個 dns 頂層鍵
# 內網 DNS 位址僅為教學值,需要替換為實際可達的位址
nameserver-policy:
"+.corp.example":
- 192.168.1.1
這段策略用於說明某些網域名稱可以交給特定解析器,適合存在內部名稱的網路。內網解析器必須知道該網域名稱,且能從裝置目前的網路抵達。切換到外部網路後,原先可用的內網位址可能不再存在,不能把逾時直接歸因於遠端代理節點。策略鍵的比對語法也不是規則清單語法,不要將 DOMAIN-SUFFIX 規則原封不動放在這裡。
在支援相關欄位的 mihomo 中,proxy-server-nameserver 可用於解析代理節點伺服器的網域名稱;respect-rules 會讓 DNS 上游連線遵循路由規則,需要特別注意節點解析與代理連線之間的依賴。fallback 也不應簡單理解為第一台伺服器逾時後的依序備援,它可能結合過濾條件選擇結果。尚未確認實作前,先採用較少的解析路徑。
驗證時分別測試一般網域名稱、內網網域名稱與需要代理的網域名稱,記錄解析結果及後續連線命中的規則。若只有區域網路應用程式異常,先縮小排除範圍;若所有請求都在等待解析,再檢查上游可達性與依賴迴圈。虛擬位址的查詢與連線流程可繼續閱讀Fake-IP 映射與排除項目說明。
四、代理節點:協定欄位與連線前提
proxies 是靜態節點清單,每個節點描述一種連往遠端服務的方式。節點不是策略組,也不決定哪些網站使用它;只有被規則直接引用,或被策略組選取後,才會參與相應連線。排查節點定義時,應分別核對服務位址、驗證資訊、傳輸方式與 TLS 參數,不要因為名稱能顯示在用戶端中,就認為協定參數已通過連線驗證。
通用欄位與協定專屬欄位
# 節點教學片段;範例網域與密碼不能用於實際連線
proxies:
- name: "教學節點"
type: ss
server: edge.example.com
port: 8388
cipher: aes-128-gcm
password: "your-password"
udp: true
name 是本機引用識別,建議保持穩定且唯一;不必等同於伺服器網域名稱。type 決定核心使用哪種協定,以及後續欄位如何解讀。server 和 port 必須與伺服器實際監聽位置一致,不能從網頁位址或訂閱介面路徑推測。範例中的保留網域名稱與教學密碼需要替換為合法取得的真實參數,修改名稱不會改善伺服器連通性。
協定專屬欄位必須成套對應。Shadowsocks 的加密方式與密碼要與伺服器端匹配;其他協定可能需要 UUID、驗證口令、額外握手參數或不同的傳輸層設定。不能將某個節點的 type 改成另一種協定,卻繼續沿用其餘欄位。用戶端能辨識分享連結,只代表它具備相應的匯入邏輯,最終仍要確認產生的欄位受目前核心支援。
| 檢查層級 | 典型欄位 | 主要現象 |
|---|---|---|
| 服務位置 | server、port | 解析失敗、拒絕連線或連線逾時。 |
| 協定驗證 | type、cipher、password | 握手失敗、驗證不匹配。 |
| 安全傳輸 | sni、憑證驗證選項 | 憑證名稱、時間或信任鏈異常。 |
| 傳輸能力 | udp 及協定選項 | 網頁可用,但部分應用程式通訊失敗。 |
TLS 名稱與傳輸參數不能混用
# 獨立的代理清單片段,不要與前面的頂層 proxies 重複貼上
proxies:
- name: "TLS 教學節點"
type: trojan
server: edge.example.com
port: 443
password: "your-password"
sni: edge.example.com
skip-cert-verify: false
udp: true
對採用 TLS 的協定而言,連線位址與憑證驗證名稱可能相關,但不一定相同。SNI 用於 TLS 握手中的服務名稱選擇,HTTP Host 與 WebSocket 路徑則處於不同層級。服務提供者明確要求不同取值時,應依其參數填寫,而不是為了消除錯誤任意替換網域名稱。出現憑證錯誤時還應檢查系統時間、伺服器憑證與中間設備,不應長期關閉憑證驗證。
udp: true 表示允許使用節點支援的 UDP 能力,並不會替不支援 UDP 的伺服器端增加這項能力。遊戲、語音或其他應用程式異常時,需要同時檢查應用程式是否進入代理、協定是否支援、伺服器端是否放行,以及所用接管入口能否處理該流量。網頁測試通常只涵蓋部分傳輸路徑,不能用一次網頁成功來證明節點適合所有應用程式。
靜態節點與代理提供器的取捨
少量固定節點可以直接寫入 proxies,方便閱讀與比對;定期更新的節點集合可以由 proxy-providers 管理,再由策略組透過 use 引用。提供器下載位址回傳的內容必須符合其要求,通常節點集合與完整設定不是同一種輸入。將完整訂閱填入只接受節點集合的入口,可能導致欄位結構不匹配,而不是網路下載故障。
提供器還涉及更新週期、快取路徑與健康檢查。遠端內容更新失敗時,核心可能繼續使用既有快取,因此介面仍顯示節點,不代表剛剛重新整理成功。應檢查最後一次載入結果與快取內容,而不只是清點清單項目。若需要透過代理下載提供器,又依賴該提供器才能取得代理,就會出現首次載入的依賴問題,需要保留可用的引導路徑。
節點名稱重新命名後,要同步檢查策略組成員、規則直接引用及用戶端保存的選取紀錄。排錯時先保留一個可信且參數完整的節點,確認服務狀態與驗證有效後,再逐步恢復集合。分享設定時,請刪除訂閱位址中的存取憑據、節點密碼及可識別個人身分的資訊;用於公開討論的範例應改成教學值,而不只是遮住截圖中的一小段字元。
五、策略組:組織節點並保留規則入口
策略組是規則與節點之間的穩定介面。規則可以持續指向名為「出口選擇」的組,而組內節點會隨訂閱更新或使用者選擇而改變。這樣既能減少規則對具體節點名稱的依賴,也讓不同業務使用不同出口。策略組本身不會憑空建立遠端連線;最終必須落到實際節點或內建目標。閱讀策略組時,應同時查看類型、成員來源與最終落點,而不只看介面中的名稱。
手動選擇組與內建目標
# 此片段不依賴外部節點,方便驗證組與規則的引用
proxy-groups:
- name: "出口選擇"
type: select
proxies:
- DIRECT
- REJECT
rules:
- DOMAIN-SUFFIX,example.com,出口選擇
- MATCH,DIRECT
select 組讓使用者手動選擇成員。這裡刻意只放直連與拒絕兩個內建目標,使結構測試不依賴遠端服務;選擇拒絕後,命中該組的連線會被阻止,而不會自動轉向其他成員。實際使用時,可將已定義的節點名稱加入清單。設定中的成員順序與用戶端保存的選取狀態可能共同影響首次顯示,不應假定每次重新載入都固定選中第一項。
DIRECT 表示由目前裝置直接連線至目標,REJECT 表示拒絕符合條件的連線。為組命名時不要重複使用內建目標名稱,也不要將名稱與協定類型混為一談。規則目標寫成「自動選擇」時,設定中必須存在完全同名的物件;一個字、空格或標點的差異,都可能使引用失效。中文名稱便於閱讀,但更新鏈路越複雜,越需要維持穩定命名。
自動選擇、故障轉移與負載分配
# 前提:proxies 中已定義並驗證過「教學節點」
proxy-groups:
- name: "自動選擇"
type: url-test
proxies:
- "教學節點"
url: "https://www.gstatic.com/generate_204"
interval: 300
tolerance: 50
- name: "出口選擇"
type: select
proxies:
- "自動選擇"
- "教學節點"
- DIRECT
url-test 會透過指定位址進行連通性測試,並依測試結果選擇成員。範例中的間隔與容差只是教學數值;容差用於減少細微差異造成的頻繁切換,不是對實際業務延遲的承諾。測試位址需要由節點出口存取,因此測試失敗可能是該位址受到限制,不一定代表節點完全不可用。只有一個成員時,自動選擇也沒有可比較的替代出口。
fallback 更接近依成員順序進行可用性故障轉移,適合主備關係;load-balance 面向連線分配,具體策略與設定選項應依目前核心文件確認。負載分配通常不會將單一下載連線拆分至多個節點,也不等於頻寬相加。涉及登入工作階段或出口位址敏感的應用程式時,頻繁變動的出口可能帶來額外驗證,應優先考慮穩定性。
健康檢查只能反映特定時間、特定目標與特定測試方式的結果,無法涵蓋所有地區限制、UDP 能力、驗證續期及長連線表現。不要透過極短測試間隔追求看似即時的狀態:測試會消耗裝置與節點資源,也可能在網路波動時造成更多切換。可以先用手動組建立穩定基線,確認業務正常後再引入自動組,並比較其實際效益。
提供器引用、巢狀與選擇還原
當節點來自代理提供器時,策略組通常透過 use 引用提供器名稱,靜態節點則透過 proxies 引用。兩者引用的物件不同,不能將下載 URL 填入成員名稱位置。節點篩選還可能排除所有成員,導致空組;因此更新後應同時檢查提供器是否載入成功、篩選條件是否命中及組內實際成員,而不只是查看訂閱重新整理提示。
策略組可以引用其他組,但依賴關係必須有終點。例如手動組引用自動組、自動組引用節點,就是清楚的層次;兩個組互相引用則會形成循環。為了讓排錯路徑可追蹤,巢狀層級應盡量少。若介面顯示「出口選擇」已選中自動組,還應繼續確認自動組最終選中了哪個節點,否則日誌中的實際出口可能與使用者直覺不同。
部分用戶端或核心會保存策略選擇,設定更新後嘗試還原原有成員;成員改名或被刪除時,還原行為可能不同。更新規則與訂閱前,記錄重要組的選擇;更新後檢查實際落點。若出現「規則命中正確但存取結果不對」,先檢查該組是否選中了直連或已失效節點,再排查更深層的 DNS 與路由。規則與策略組的協作流程也可對照連線驗證步驟。
六、規則語法:比對條件、順序與最終目標
rules 通常依從上到下的順序進行比對,命中後交給指定目標處理。排序就是邏輯的一部分:精確例外應放在廣泛規則之前,最終兜底則放在末尾。不要把規則清單當成可以任意排序的分類表;一條位置過早的寬泛規則,可能讓後面的精細規則永遠沒有執行機會。修改前先明確要改變哪類連線,以及它原本命中的位置。
網域名稱、位址段與兜底規則
# 局部規則片段:使用內建目標示範比對順序
rules:
- DOMAIN,blocked.example.com,REJECT
- DOMAIN-SUFFIX,example.com,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
- MATCH,DIRECT
DOMAIN 用於精確網域名稱,DOMAIN-SUFFIX 用於網域後綴及其子網域,DOMAIN-KEYWORD 用於網域名稱中的關鍵字。關鍵字範圍通常比預期更廣,可能誤傷含有相同字串的其他網域名稱;明確知道後綴時,優先使用後綴規則。網域規則無法辨識完整網頁 URL 的路徑、查詢參數或頁面內容,不能直接依某個網址目錄進行分流。
IP-CIDR 用於 IPv4 位址段,IPv6 位址段則使用相應的 IPv6 規則類型。範例中的私有位址範圍不代表已涵蓋所有本機通訊,還需要依實際網路考慮其他特殊範圍與路由安排。MATCH 不帶比對值,直接指定最終目標,應放在末尾。若將它放在第一條,後續一般規則就會失去作用。
| 規則類型 | 比對對象 | 常見誤用 |
|---|---|---|
DOMAIN | 完整網域名稱 | 把協定前綴與網頁路徑一起填入。 |
DOMAIN-SUFFIX | 網域後綴及子網域 | 誤以為只會比對一個特定主機。 |
IP-CIDR | 目標位址段 | 忽略解析觸發與規則順序。 |
RULE-SET | 已定義的規則提供器 | 引用不存在或載入失敗的名稱。 |
MATCH | 剩餘連線 | 提前放置,遮蔽後續規則。 |
網域資訊與 no-resolve 的界線
網域規則能夠比對的前提,是核心在進行規則判斷時擁有相應的網域名稱資訊。若應用程式先自行解析,再只傳送目標 IP,核心可能無法直接使用網域規則。Fake-IP 映射、代理協定攜帶的主機名稱或適用的嗅探機制可以提供線索,但不能保證還原所有連線的原始網域名稱。遇到網域規則失效時,應先查看日誌中的目標呈現為網域名稱還是位址。
位址規則可能為了判斷目標所屬位址段而觸發解析。加入 no-resolve 表示不為該條位址規則主動發起網域名稱解析,並不代表關閉全域 DNS,也不會阻止後續建立連線時所需的解析。如果連線已經具有目標 IP,規則仍可使用它進行比對。先放網域規則,再放必要的位址規則,可以減少不必要的解析依賴,但具體順序仍應服從業務目標。
規則提供器與本機規則維護
# 前提:已在對應位置建立規則檔案
rule-providers:
local-policy:
type: file
behavior: classical
path: ./rules/local-policy.yaml
rules:
- RULE-SET,local-policy,DIRECT
- MATCH,DIRECT
# rules/local-policy.yaml 的內容,不是主設定
payload:
- DOMAIN-SUFFIX,example.com
- IP-CIDR,192.168.0.0/16,no-resolve
規則提供器將比對集合拆分至獨立檔案,主設定負責為這個集合指定策略。上例使用 classical 行為,集合中的規則不再撰寫最終目標;網域集合與位址集合則需要相應的行為與內容格式。遠端規則還要核對下載格式、快取路徑與更新結果。副檔名相同不代表內容結構相同,將一般文字清單當成帶有 payload 的 YAML 會造成載入錯誤。
地理資料、程序名稱與程序路徑規則都依賴額外條件。地理分類受資料庫涵蓋範圍與更新時間影響;程序規則受系統權限、平台及接管方式限制,不能把某個平台的寫法視為通用方案。維護規則時應記錄新增原因,並採用最小比對範圍。驗證新規則時要建立新連線,因為已建立的長連線通常不會僅因規則重新載入而重新選擇出口。
七、覆寫與合併:保留訂閱更新與本機修改
直接編輯訂閱下載檔案,往往會在下次更新時遺失。覆寫的目的,是將訂閱負責的節點與基礎規則,和裝置本身的連接埠、DNS 或規則偏好分開管理。這裡沒有一套適用於所有用戶端的相同合併演算法:有些提供欄位替換,有些支援規則前置或後置,有些允許腳本處理完整物件。使用前應先確認入口處理的是 YAML 片段、完整設定,還是可執行腳本。
標量、映射與清單必須分開理解
# 原始設定中的相關欄位
mixed-port: 7890
mode: global
allow-lan: true
# 僅用於支援此類欄位替換的用戶端覆寫入口
mode: rule
allow-lan: false
# 假設規則:同名標量由本機覆寫替換
mixed-port: 7890
mode: rule
allow-lan: false
這個範例只展示標量替換:原設定的連接埠保留,模式與區域網路存取則被本機值替換。它不能證明巢狀 DNS 欄位也會逐項合併,更不能證明規則清單會自動追加。若用戶端介面的通用設定在覆寫之後再次寫入,最終結果還可能改變。實際使用時,應對照用戶端產生的最終設定,而不是從覆寫入口的名稱推測執行順序。
映射合併存在淺層替換與遞迴合併的差異。例如原 DNS 映射包含上游、過濾清單與監聽位址,本機只填寫 enable: true;如果整個映射被替換,其他內容可能就會消失。如果使用遞迴合併,未提及的鍵可能保留。欄位刪除也不是簡單寫入 null 就一定有效:有些機制會保留空值,有些拒絕輸入,有些則提供專用刪除操作。
清單的追加方向決定邏輯
規則、節點與策略組都是清單,但不能共用一套不加區分的追加邏輯。規則具有順序語意,把本機例外放在既有 MATCH 後面通常不會生效;節點清單需要注意名稱重複;策略組清單不只涉及組名,也涉及組內成員引用。不要將「支援合併」理解為能自動處理同名節點、循環引用與規則優先級。
# 這是最終設定中的順序示意,不是通用覆寫指令
rules:
- DOMAIN,printer.lan,DIRECT
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,出口選擇
上例假設原設定已定義「出口選擇」組,且確實需要讓印表機網域名稱直連。將這條規則放在前面,只處理規則層面的出口選擇;如果印表機網域名稱解析錯誤、組播探索失敗或區域網路路由不通,仍然需要分別處理。對存在更具體拒絕規則的設定,還要確認前置規則不會意外放行原本希望阻止的目標。
建立可重複、可撤銷的處理流程
建議分別保存訂閱原文、本機覆寫與最終執行設定。原文用於判斷服務方是否變更結構,覆寫用於追蹤本機意圖,最終檔案則用於核心測試。每次只新增一個處理步驟,並註明它依賴的組名或欄位。若原文中的組名被服務方調整,即使本機規則語法正確,也可能失去目標,應在訂閱更新後重新檢查引用關係。
腳本覆寫需要具備冪等性:同一份輸入處理一次與重複處理,結果都應保持一致。常見錯誤是每次執行都向規則清單插入同一條內容,最終不斷累積;或直接修改共用物件,使後續步驟讀到意外狀態。還應防禦欄位缺失與型別變化,不能假設每份訂閱都存在 DNS 映射或同名策略組。無法解釋腳本行為時,優先使用更簡單的欄位操作。
用戶端升級、核心切換與訂閱更新都可能改變合併鏈路。正式套用前,先在副本中產生結果,比對連接埠、模式、DNS、組名與末尾規則,並確認沒有清空既有提供器路徑或安全設定。出現異常時,先停用最近加入的覆寫,還原原始設定與已知可用的選擇,再逐項重新啟用處理步驟。保留最小差異,比反覆複製整份設定更容易定位問題。
八、驗證與排錯:從語法檢查到實際連線
驗證應分層進行:檔案能解析、引用能載入、監聽能啟動、應用程式能進入入口、規則能命中、出口能抵達目標。前一層通過不代表下一層成功。特別是設定測試指令主要檢查格式與可載入性,不會替使用者完成所有節點的線上驗證與業務測試。先記錄故障發生在哪一層,再選擇最短的驗證路徑,可以減少重複重裝與無關參數修改。
使用相同核心檢查最終設定
# macOS / Linux:目前目錄已有可執行的 mihomo
# check.yaml 是匯出的最終設定副本
./mihomo -t -f ./check.yaml
# Windows PowerShell:目前目錄已有 mihomo.exe
.\mihomo.exe -t -f .\check.yaml
執行前確認指令所指向的核心與用戶端執行環境一致,並透過該可執行檔的說明資訊核對參數。圖形用戶端名稱不等於可執行檔名稱;系統中的另一份同名程式可能支援不同欄位。測試應在受控目錄中進行,提供器、規則檔案與資料庫等依賴也必須能夠存取。相對路徑通常取決於核心工作目錄或設定處理方式,不能只搬走一個主檔案就認為測試環境相同。
遇到解析錯誤行號時,同時檢查報錯行及其前幾行。未閉合引號、錯誤縮排與清單層級偏移,可能直到下一個欄位才被偵測出來。引用錯誤則沿著名稱向上追蹤,檢查組名、節點名與提供器名;缺少資源時檢查路徑、權限與內容格式。不要把所有錯誤都歸咎於 YAML 縮排,也不要為了讓測試通過而刪除不理解的安全或路由欄位。
依入口、規則、出口逐段驗證
# 前提:mixed-port 為 7890,核心已成功啟動
curl --proxy http://127.0.0.1:7890 --head https://example.com/
# Windows 使用 curl.exe,避免指令別名差異
curl.exe --proxy http://127.0.0.1:7890 --head https://example.com/
明確指定代理入口,可以暫時排除系統代理設定是否生效這項變數。成功取得 HTTP 回應,表示這次請求完成了相應鏈路,但回應狀態不一定是成功狀態,也不能據此證明所有應用程式都被接管。測試網域只是一般連通性目標;需要驗證特定業務時,應再使用該業務允許的實際位址,並在用戶端連線紀錄中確認命中的規則與最終策略。
如果明確代理成功而瀏覽器失敗,重點檢查瀏覽器獨立代理、加密 DNS、擴充功能與系統設定。如果兩者都失敗,先看核心是否監聽、連接埠是否一致,再檢查 DNS 與遠端連線錯誤。如果直連正常而代理節點逾時,檢查訂閱有效性、節點位址、驗證參數與上游網路,而不是立即修改整套規則體系。相關分層順序請參閱代理節點逾時排查。
| 現象 | 優先定位 | 下一步 |
|---|---|---|
| 儲存後核心無法啟動 | 語法、欄位支援與引用關係 | 測試最終檔案,閱讀第一個有效錯誤。 |
| 提示連接埠已被占用 | 重複程序或監聽衝突 | 確認占用者,避免同時執行兩個入口。 |
| 網頁正常,特定應用程式失敗 | 接管範圍、DNS 與 UDP | 對照該應用程式的連線紀錄與協定需求。 |
| 更新訂閱後本機規則消失 | 編輯層級與合併順序 | 比較原文、覆寫與最終檔案。 |
| 規則正確但出口異常 | 策略組實際選擇 | 追蹤巢狀組最終落到的節點。 |
快取、日誌與安全回滾
更換 DNS、Fake-IP 模式或規則後,應重新發起連線。瀏覽器連線池、應用程式長連線、系統 DNS 快取與核心快取,可能讓舊狀態暫時持續存在。先關閉目標應用程式的相關連線,再使用系統或用戶端提供的適當快取清理方式;不要透過刪除整個使用者目錄來處理一次快取問題。分別記錄測試前後請求的時間,才能與日誌中的事件準確對應。
日誌應保留錯誤類型、發生時間、命中規則與必要的連線階段,同時移除訂閱憑據、驗證資訊及不需要公開的網域名稱。介面閃退與核心失敗是不同分支:前者需要檢查執行環境與介面元件,後者更應檢查設定、權限與監聽錯誤。用戶端無法開啟時,可先依照啟動失敗與設定還原步驟保留現場,不要直接清除資料。
回滾時先關閉最近啟用的接管方式,還原已知可用的設定與策略選擇,再檢查系統代理與 DNS 是否留下手動設定。退出用戶端不一定會撤銷使用者自行寫入的網路參數,因此應保留修改前紀錄。最終驗收至少涵蓋一次一般存取、一次目標業務存取與一次區域網路存取;確認日誌與路徑符合預期後,再恢復常用日誌級別並備份這份設定。
若只是希望完成首次連線,請回到快速上手主線;若需要重新選擇圖形用戶端,可在選型指南比較設定管理方式,再從下載頁進入對應平台。本手冊的目標,是讓每次修改都有明確前提、可觀察結果與還原方法,而不是要求同時啟用所有可選欄位。