Shadowrocket 規則寫法:DOMAIN、GEOIP、IP-CIDR 與 FINAL 各比對什麼

Shadowrocket(小火箭)的規則列表裡,每一行都由「類型、值、策略」三段組成,比對順序由上而下、首條命中即停。本文逐條拆解 DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD、GEOIP、IP-CIDR 與 FINAL 的比對對象,並提供可直接照抄的寫法與排查順序。

本文速覽

規則列表是一份純文字,一行一條,格式為「類型,值,策略」。本文把網域類(DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD)、IP 類(GEOIP、IP-CIDR)與兜底(FINAL)逐一講清比對對象與命中順序,並提供可在 Config → Rules 直接照抄的範例。適合已經匯入訂閱、想讓流量依自己的意圖分流的使用者;讀完能獨立寫出一份不互相衝突的規則列表。

一條規則的三段結構

Shadowrocket 的規則列表是一份純文字,儲存在設定檔裡,一行一條。每行用英文半角逗號切成三段:類型(TYPE)、值(VALUE)、策略(POLICY)。類型決定「拿什麼去比」,值決定「比什麼」,策略決定「命中之後怎麼辦」。

策略只有三種:PROXY 表示走目前選取的伺服器,DIRECT 表示直連,REJECT 表示捨棄這條連線。以 # 開頭的整行是註解,解析時會跳過;空行同樣忽略。寫規則時用到的逗號必須是英文半角,全形逗號會讓整行失效。

# 每行格式:類型 / 值 / 策略
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-KEYWORD,analytics,DIRECT
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
FINAL,DIRECT

三段裡最容易出錯的是值:網域類規則的值是主機名稱,IP 類規則的值是 CIDR 網段或兩位國家/地區代碼,連接埠類規則的值是數字。格式不對的行不會報錯,只會被靜默跳過——所以遇到「規則寫了沒反應」,先回頭檢查這一行的逗號與值格式,再去懷疑其他環節。

網域類:DOMAIN、DOMAIN-SUFFIX、DOMAIN-KEYWORD

網域類規則比對的是請求裡的主機名稱。HTTPS 請求的主機名稱通常來自 TLS 交握中的 SNI,HTTP 請求來自 Host 標頭,這兩種資訊在連線剛建立時就已經具備,不需要等待 DNS 解析,因此網域規則判斷最快,也最不受解析結果波動影響。三種常用寫法的範圍依次放寬:

類型比對對象寫法範例命中範圍
DOMAIN完整主機名稱,一字不差DOMAIN,api.example.com,PROXY只命中 api.example.com;www.api.example.com 不命中
DOMAIN-SUFFIX網域後綴,含自身與全部子網域DOMAIN-SUFFIX,example.com,PROXYexample.com、a.example.com、a.b.example.com 都命中
DOMAIN-KEYWORD主機名稱中任意位置出現的關鍵字DOMAIN-KEYWORD,analytics,DIRECTanalytics.example.com、cdn-analytics.example.net 都命中
DOMAIN-SET外部網域清單檔案,每行一條網域DOMAIN-SET,example-domains.txt,DIRECT清單中寫過的網域依該行策略執行

範圍越寬,誤傷的機率越高。DOMAIN-KEYWORD,analytics,DIRECT 會命中主機名稱中任何位置出現 analytics 的請求,包括你並不想直連的網站;DOMAIN-SUFFIX,example.com,PROXY 則會連帶把 mail.example.com、static.example.com 一起送進代理。寫寬泛規則之前,先確認這個後綴下確實沒有需要區別對待的子網域。

選擇寫法時,依下面的順序判斷:

DOMAIN,www.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
DOMAIN-KEYWORD,adservice,REJECT
DOMAIN-SET,example-domains.txt,DIRECT

IP 類:GEOIP 與 IP-CIDR 比的是解析後的位址

IP 類規則不看網域,只看連線目標的 IP 位址。要拿到 IP,系統必須先做一次 DNS 解析,所以 IP 規則比網域規則晚一步生效,而且會丟掉「網域」這個維度:同一個網域解析到不同位址時,命中結果可能跟著變化。

GEOIP 用兩位國家/地區代碼概括整段位址歸屬,GEOIP,CN,DIRECT 的含義是「目標是中國的 IP 就直連」。IP-CIDR 寫精確網段,內網直連的常見寫法是 IP-CIDR,192.168.0.0/16,DIRECTIP-CIDR,10.0.0.0/8,DIRECT;IPv6 目標用 IP-CIDR6。依連接埠判斷由 DST-PORTSRC-PORT 負責,例如 DST-PORT,443,PROXY 表示目標連接埠是 443 的連線走代理。

GEOIP,CN,DIRECT
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
IP-CIDR6,fc00::/7,DIRECT,no-resolve
DST-PORT,443,PROXY

內網網段這類規則通常要在末尾補一個 no-resolve:它的作用是比對這條規則時,不要為了拿 IP 而觸發 DNS 解析。少了這個參數,一個本來可以直接命中的請求會先被迫解析一次,既拖慢判斷,也可能因為解析失敗而落空。

結論:網域規則要寫在 IP 規則前面

GEOIP 與 IP-CIDR 需要先拿到目標 IP。如果它們排在網域規則之前,一個本可被 DOMAIN-SUFFIX 精確命中的請求會先被迫解析,命中結果取決於當下解析到哪個位址。把網域類放前、IP 類放後,順序才穩定。

命中順序:由上而下,首條命中即停

Shadowrocket 從規則列表的第一行開始逐條比對,某一行命中後立即執行該行的策略,後面的規則不再參與判斷。這套機制決定了排序原則:越具體、越需要優先處理的規則寫在越上面,越寬泛的規則寫在越下面。

FINAL 是一條只有策略、不需要比對值的兜底規則,用來承接前面全部沒有命中的請求:FINAL,DIRECT 讓未命中的流量直連,FINAL,PROXY 讓未命中的流量走代理。它必須放在列表最後一行——寫在 FINAL 之後的規則不會被執行。

# 1. 內網與保留位址先直連
IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
# 2. 明確要攔截的網域
DOMAIN-SUFFIX,ads.example.com,REJECT
# 3. 明確要走代理的網域
DOMAIN-SUFFIX,example.com,PROXY
# 4. 中國大陸位址直連
GEOIP,CN,DIRECT
# 5. 兜底
FINAL,PROXY

排序時可以依下面五層由上往下擺:

讓規則生效:Global Routing 與設定檔

規則列表只在 Global Routing 處於 Config 姿態時才參與判斷。姿態在 Settings → Global Routing 裡切換,三個常用選項的差別是:

設定(Config)

推薦

依設定檔裡的規則列表逐條比對:命中 PROXY 走代理,命中 DIRECT 直連,命中 REJECT 丟棄。

適合:日常主力,想讓規則真正發揮作用

代理(Proxy)

忽略規則列表,所有連線一律走目前選取的伺服器。

適合:臨時全量代理、排查規則問題

直連(Direct)

忽略規則列表與伺服器,所有連線直接送出。

適合:確認某個現象是否由代理造成

另一個前提是「改對了檔案」。Config 分頁裡可能同時存在多份設定,只有目前選取(帶勾)的那一份會被使用。編輯入口是 Config → 選取正在使用的設定檔 → Rules,列表依行顯示,右上角「+」新增一行,點任意一行可以修改類型、值與策略。完整流程如下:

  1. 確認姿態

    Settings → Global Routing 選 Config,否則規則列表不參與判斷。

  2. 開啟 Config

    底部分頁切到 Config,確認帶勾的正是你在用的那份設定檔。

  3. 進入 Rules

    點進設定檔,找到 Rules 一行,裡面就是完整的規則列表。

  4. 插入新行

    右上角「+」新增規則,依「類型,值,策略」三段填寫,逗號用英文半角。

  5. 調整順序

    把具體規則移到寬泛規則之前,FINAL 保持在最後一行。

  6. 儲存並重新連線

    儲存後回到 Home 中斷再連線一次,讓新的規則列表生效。

結論:先定姿態,再談規則

規則寫了卻不生效時,先確認 Global Routing 是否停在 Config、目前選取的是不是你改的那份設定檔,再去檢查規則順序與寫法。順序反過來查,通常會在寫法上白折騰很久。

四個常見問題

下面四個問題涵蓋了規則類回饋裡最常見的情境,排查路徑都是從「姿態 → 設定檔 → 規則順序 → 規則寫法」逐層往下。

加了 DOMAIN-SUFFIX,example.com,PROXY,這個網域還是直連?

先看列表裡有沒有更靠前的規則先命中——例如寫在網域規則之前的 GEOIP,CN,DIRECT,或者一條寬泛的 DOMAIN-KEYWORD。再確認 Global Routing 停在 Config、目前選取的正是你編輯的那份設定,最後中斷重新連線一次。

GEOIP,CN,DIRECT 為什麼沒讓中國大陸網站直連?

GEOIP 比對的是解析後的 IP,不是網域。如果它寫在網域規則之前、或者目標解析到的位址不在 CN 段內,這條規則就不會命中。把它放到網域規則之後、FINAL 之前,再重新連線一次觀察。

IP-CIDR 規則為什麼不比對我寫的網域?

IP-CIDR 只比對 IP 位址,不認網域。要依網域分流就用 DOMAIN-SUFFIX;要依網段分流,就確認目標解析到的位址確實落在你寫的 CIDR 裡。寫內網網段時記得帶上 no-resolve。

REJECT 寫了,某些請求還是送出去了?

規則由上而下比對、首條命中即停。如果 REJECT 上面已經有一條 PROXY 或 DIRECT 命中了同一個目標,請求就走不到這一行。把 REJECT 提到對應網域規則之前再試。

App Store 正版核驗