本文適合已在 iPhone 或 iPad 上使用 Shadowrocket,並有自己的伺服器資訊或訂閱,卻不清楚規則為何命中或失效的使用者。請先確認 Global Routing 與目前使用的設定檔,再區分網域匹配、IP 匹配和 FINAL 兜底規則。閱讀本文後,你可以寫出最精簡的規則片段,並透過請求記錄確認實際流向。文中的網域與保留位址僅供說明,不提供連線服務。
一、規則生效的前提:Global Routing 與目前使用的設定檔
Shadowrocket(小火箭)的規則不是伺服器清單。Home 中選取的伺服器會決定代理連線使用的出口;Config 中的設定檔則包含規則等設定。匯入或更新自己的訂閱,不代表已切換到預期的規則設定檔。排查前,請分別確認這兩項。
在 Home 查看 Global Routing。本文討論的是選擇 Config 後,由目前設定檔逐條判斷請求的情況。Proxy 與 Direct 是全域路由模式,不能僅憑它們的連線結果,就認定某條設定檔規則已命中。Scene 會依所選場景設定運作,也不能視為 Config 的同義項。
| 設定項目 | 核對說明 | 本文測試方式 |
|---|---|---|
Config | 依目前設定檔執行規則分流。 | 選取此項,再確認目前設定檔是否正確。 |
Proxy | 採用全域代理路由模式。 | 可用於排除出口問題,但不能作為逐條規則的驗證結果。 |
Direct | 採用全域直連路由模式。 | 可與直連狀態比較;測試結束後請切回 Config。 |
Scene | 依場景設定決定相應行為。 | 先確認場景設定;初次測試規則時,請改用 Config。 |
二、規則語法與順序:先命中,先執行
常見規則由英文關鍵字、匹配內容和策略組成,欄位之間以半形逗號分隔。FINAL 不需要匹配內容,因此主要只有關鍵字和策略兩個欄位。DIRECT 表示直接連線;下文的 PROXY 表示透過代理連線,使用前仍須確認目前選取的代理可正常使用。若填寫自訂策略組名稱,該名稱必須存在於設定檔中。
[Rule]
DOMAIN,login.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-KEYWORD,example,PROXY
IP-CIDR,192.0.2.0/24,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY
這只是用來說明語法的片段,不是可直接連線的完整設定。Shadowrocket 會由上而下檢查規則,遇到第一條符合條件的規則,就採用相應策略,不會再繼續尋找「更精確」的規則。因此,精確規則不會自動取得較高的優先順序。
以上述範例來說,當請求的網域是 login.example.com,第一行便已命中,結果為 DIRECT。如果將 DOMAIN-SUFFIX 移到 DOMAIN 前面,login.example.com 會先命中後綴規則並交由 PROXY 處理,後面的精確規則就不會再處理這次請求。
- 少數需要優先處理的例外應放在前面,例如特定登入網域。
- 涵蓋整個網域及其子網域的一般規則,放在例外之後。
- 範圍較廣的關鍵字與地區 IP 判斷,應確認是否會遮蔽後續規則。
- FINAL 應放在所有需要比對的規則之後,後面不要再加入有效例外。
三、DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD 的適用範圍
這三種關鍵字都用來匹配網域,但涵蓋範圍不同。規則中填寫的是主機名稱或關鍵字,不是完整網址:不要加上 https://、網頁路徑、查詢參數或連接埠。連線至 login.example.com 的 443 連接埠,不代表 DOMAIN 的匹配內容要寫成 login.example.com:443。
| 規則範例 | 會命中 | 不會命中 |
|---|---|---|
DOMAIN,example.com,DIRECT | example.com | www.example.com、example.com.test |
DOMAIN-SUFFIX,example.com,PROXY | example.com、www.example.com、a.b.example.com | notexample.com、example.com.test |
DOMAIN-KEYWORD,example,PROXY | example.com、myexample.test、example.net | 不含 example 的網域 |
DOMAIN:只匹配一個完整主機名稱
若要分別處理 api.example.com 和 www.example.com,使用 DOMAIN 最容易檢視。它不會自動涵蓋子網域,因此 DOMAIN,example.com,DIRECT 不會一併處理 api.example.com。替某個 App 設定規則時,也要留意它可能同時連線至登入、API、圖片等多個主機名稱,不能只根據首頁網域推斷所有請求的流向。
DOMAIN-SUFFIX:依網域層級涵蓋
DOMAIN-SUFFIX,example.com,PROXY 會同時涵蓋根網域及其下各層子網域,不必加上萬用字元。它不是搜尋任意字串結尾:notexample.com 雖然結尾含有相同字母,但缺少網域層級邊界,因此不屬於 example.com 的子網域。
DOMAIN-KEYWORD:依字串包含關係擴大範圍
DOMAIN-KEYWORD 不要求關鍵字位於特定網域層級邊界,適合用來涵蓋多個含有特定字串的網域,但也更容易意外命中。例如 example 會匹配 myexample.test。如果只想處理 example.com 這組網域,應優先使用 DOMAIN-SUFFIX,而不是用範圍更廣的關鍵字取代。
四、GEOIP 與 IP-CIDR:匹配目標位址
GEOIP 會依目標 IP 在位址資料庫中的地區歸屬進行判斷。GEOIP,CN,DIRECT 的意思是:目標 IP 若被資料庫歸類為 CN,就使用 DIRECT。它不會檢查網域註冊地或使用者所在區域,也無法保證同一品牌的所有服務一直使用同一地區的 IP 位址。
IP-CIDR 則用於匹配指定的 IPv4 網段。IP-CIDR,192.0.2.0/24,DIRECT 涵蓋 192.0.2.0 至 192.0.2.255;其中 /24 表示前 24 位是網路前綴,不是連接埠號碼。192.0.2.0/24 是文件專用保留位址範圍,此處僅用來說明匹配方式,不是可用的伺服器位址。
IP-CIDR,192.0.2.0/24,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY
IP 規則是否需要先解析網域,會影響排查方式。選用參數 no-resolve 表示不要只為這條 IP 規則主動進行網域解析;若已知道目標 IP,仍可依位址判斷。因此,這不是「關閉 DNS」,也不代表網頁之後不再需要解析。如果還不知道目標 IP,這條規則可能會略過,讓後續規則繼續判斷。
- 網域例外優先:明確要依網域處理的服務,通常應將對應的 DOMAIN 或 DOMAIN-SUFFIX 放在涵蓋範圍較廣的 GEOIP 之前。
- 資料庫分類不等於服務分類:CDN 位址、解析結果及 IP 位址資料庫的歸屬,都可能影響 GEOIP 的判斷結果;請確認實際目標 IP。
- 分開確認 IP 位址類型:IP-CIDR 的 IPv4 網段不會涵蓋 IPv6;若涉及 IPv6 位址,需另外使用相應的 IP-CIDR6 規則。
- 連接埠不是 CIDR:目標連接埠 443 與網段 /24 是不同資訊,不能把連接埠加在 IP-CIDR 的位址欄位後面。
五、FINAL 為何必須放在最後
FINAL 是兜底規則:前面的規則都未命中時,便採用它指定的策略。它沒有網域或網段限制,因此若放在中間,所有一路比對到這一行的請求都會被攔截,後面的規則也無法再參與判斷。「最後」指的是整份有效規則序列的末尾,不只是目前編輯視窗中看起來的最後一段。
[Rule]
DOMAIN,login.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
GEOIP,CN,DIRECT
FINAL,PROXY
FINAL,PROXY 和 FINAL,DIRECT 都是明確的兜底選擇,沒有一種答案適合所有人。前者會將尚未分類的請求交由代理處理;後者則讓這些請求直接連線。選用前者需有可用的代理出口;選用後者則須接受未知目標直接連線的結果。修改前應先確認自己的使用需求,不要只看能否開啟某個網頁。
「規則寫得更精確,為什麼還是沒有命中?」
先查看它上方是否已有 DOMAIN-SUFFIX、DOMAIN-KEYWORD 或 FINAL。將需要優先處理的 DOMAIN 例外移到範圍較廣的規則之前,再重新建立連線確認。
「FINAL 後面可以再加一條規則嗎?」
文字上可以繼續新增,但這條規則不會處理已被 FINAL 接手的請求。請把新增規則移到 FINAL 之前,並保留一條明確的最終兜底規則。
「把 FINAL 改成 DIRECT 就算修好了嗎?」
不一定。這可能只是避開了無法使用的代理出口。請回到 Home 確認目前選取的伺服器,再檢查預期網域是否應由更精確的規則處理。
「更新訂閱後,規則也會一起更新嗎?」
伺服器訂閱與規則設定檔是分開更新的。請先在 Config 確認目前使用的設定檔,再確認更新的是伺服器清單還是設定檔;清單成功重新整理,不代表規則已更新。
六、最精簡的驗證步驟:一次只修改一條規則
驗證時,請同時記錄「預期策略」和「實際請求」。網頁能開啟只代表某次請求成功,不能單憑這點判斷使用的是 DIRECT 還是 PROXY。以下步驟不需要更換自己的訂閱,也不需要調整協定參數;Shadowsocks、VMess、VLESS 等出口協定和規則關鍵字屬於不同層面。
-
保留原始設定
在 Config 確認目前使用的設定檔,修改前先保留可還原的副本或原始文字。記下原本的 FINAL 策略,不要直接覆蓋唯一可用的設定檔。
-
確認路由模式
在 Home → Global Routing 選擇 Config,再回到 Config 確認目前啟用的是準備測試的設定檔,而不是另一份同名或遠端設定檔。
-
新增精確例外
在目前設定檔的規則區段中,為自己能確認的實際目標新增一條 DOMAIN 規則,並放在範圍較廣的規則及 FINAL 之前。本文使用的 example.com 僅用於說明語法,不是代理連線測試目標。
-
重新發出請求
儲存並確認設定檔生效後,先結束目標 App 中已建立的連線,再發出新請求。請勿更改 Home 中選取的伺服器,以免連線重用或出口變更影響判斷。
-
檢查請求記錄
在請求記錄或日誌中確認主機名稱、目標 IP、命中的規則及實際策略,並以介面提供的欄位為準。如果記錄資訊不足,先啟用相應的記錄功能,再重複相同請求;不要根據延遲數值推斷出口。
七、規則命中後仍無法連線:依錯誤層級排查
規則負責選擇連線去向,無法保證目標、DNS 與代理伺服器一直可用。請求記錄顯示預期規則已命中時,接著應檢查後續連線環節。以下是網路診斷時可能看到的原始錯誤訊息,不是規則語法錯誤提示。錯誤的具體顯示方式取決於發生的層級,不能只憑一行文字就認定是規則問題。
錯誤:Connection refused
原因:某個連線端點拒絕了連線,可能是目標連接埠或代理伺服器連接埠沒有相應服務。
處理方式:先從記錄確認連線的位址與連接埠,再核對 Home 中該伺服器的連接埠是否與自己已有的服務資訊一致;若失敗發生在目標端,請檢查目標服務,而非擴大網域規則的範圍。
錯誤:Operation timed out
原因:相關操作未能在等待時間內完成,可能與網路連線、代理連線或目標回應有關,單憑逾時無法判斷問題出在哪個環節。
處理方式:搭配錯誤前後的連線記錄判斷發生階段,並在 Home → Global Routing 暫時切換至 Proxy 或 Direct 進行比對;測試完成後切回 Config,並維持相同的測試目標。
錯誤:No route to host
原因:連線使用的網路路徑無法到達目標位址,這不代表 DOMAIN 或 FINAL 的欄位寫錯。
處理方式:確認目前網路是否正常、實際目標 IP 與位址類型是否符合預期,再檢查請求最後是透過 DIRECT 還是代理出口連線,並依實際路徑處理。
如果問題發生在網域解析階段,請先確認 DNS 請求是否成功;如果是伺服器驗證失敗,則應核對自己的伺服器參數。不要把所有請求都改成 DIRECT 來掩蓋問題,也不要為了排除單一錯誤就同時重寫整份規則。保留對照條件,才能確認修正是否真的生效。
- 設定檔核對:Home → Global Routing 設為 Config,且 Config 中啟用的檔案正確。
- 語法核對:使用半形逗號,網域欄位不含網址路徑,策略名稱有效。
- 順序核對:精確例外排在範圍較廣的規則之前,FINAL 位於有效規則序列末尾。
- 結果核對:新請求的主機名稱、目標 IP 與實際策略都符合預期,而不只是網頁能開啟。