V2Ray 自訂路由規則設定:domain、ip、geosite 比對語法與優先順序

了解 domain 的 full、domain、keyword、regexp 寫法及 geosite、geoip 資料集用法,掌握規則比對順序與避免規則互相覆蓋的方法。

本文重點速覽

本文適合已匯入節點,並想調整直連與代理分流的使用者。先分清網域比對和 IP 比對,再透過設定片段說明規則順序、解析策略與預設出站。請特別留意:關鍵字比對通常直接填入字串,不能把說明中的 keyword 當成通用 JSON 前綴。文中使用的都是範例網域,不含可連線的代理節點。

一、路由負責選擇出站,不會建立節點

V2Ray 路由會讀取連線的目標位址、連接埠、網路類型等資訊,再將連線交給指定的出站。它不會把訂閱轉換成節點,也不會因為設定了 outboundTag: "proxy" 就自動建立代理伺服器。標籤只是參照,必須能在目前設定的 outbounds 中找到對應的 tag。

入站接收連線讀取目標資訊依序比對規則選擇出站標籤建立目標連線

網域規則能否生效,也取決於核心是否取得網域資訊。應用程式透過 SOCKS 傳送網域時,核心可以直接比對;若應用程式先自行解析,再傳送 IP,網域資訊可能已經遺失。流量嗅探可從部分協定辨識主機名稱,但無法還原所有加密流量中的網域,也不能取代 DNS。

二、domain 的四種寫法:精確網域、根網域及子網域、關鍵字與正規表示式

domain 是字串陣列。同一陣列中的多個項目採「或」關係,符合任一項即可。以下以 example.com 說明比對範圍;網域項目中不要填入完整網址、路徑或查詢參數,因為路由比對的不是瀏覽器網址列中的完整 URL。

寫法比對範圍範圍說明
full:example.com僅比對 example.com不包含 www.example.com
domain:example.com根網域及其子網域不比對 notexample.com
example網域中含有 example 的字串也可能比對到 notexample.net
regexp:^api[0-9]+\.example\.com$指定以 api 開頭、後接數字的子網域在 JSON 中需跳脫反斜線
{
  "type": "field",
  "domain": [
    "full:login.example.com",
    "domain:static.example.com",
    "regexp:^api[0-9]+\\.example\\.com$"
  ],
  "outboundTag": "proxy"
}

上方的正規表示式是 JSON 字串,因此其中一個反斜線必須寫成兩個。^ 和 $ 用來限定字串的開頭與結尾,避免只比對到網域的一部分。若只需要整個網域及其子網域分流,優先使用 domain:,比範圍較廣的關鍵字和複雜正規表示式更容易檢查。

三、geosite 與 geoip:分類資料不會自動推測

geosite 用於參照網域分類,放在 domain 陣列中;geoip 用於參照 IP 分類,放在 ip 陣列中。兩者都需要核心能讀取資料檔,且檔案中確實包含所需分類。填入分類名稱不會觸發線上搜尋,也不會自動下載缺少的資料。

網域分類規則

規則欄位
domain
項目範例
geosite:cn
常見資料檔
geosite.dat
比對依據
資料集中列出的網域規則

分類內容取決於資料檔,不代表伺服器所在地。

IP 分類規則

規則欄位
ip
項目範例
geoip:private
常見資料檔
geoip.dat
比對依據
資料集收錄的 IP 網段

使用的分類必須存在於目前的資料檔中;若載入失敗,請先檢查檔案與分類名稱。

網域屬於某個分類,不代表它使用的所有 CDN 位址都屬於同一個 IP 地區。反過來說,某個 IP 被列入地區分類,也不表示使用該位址的所有網域都應直連。若要明確控制特定服務網域,請另設獨立規則,並排在範圍較廣的分類規則之前。

四、ip、CIDR 與連接埠:同欄位為「或」,不同欄位為「且」

ip 可填入單一位址、CIDR 網段或受支援的資料集參照。CIDR 斜線後的數字代表前綴長度,不是連接埠。以下三個數字用來說明語法邊界,方便檢查輸入內容,並非網路測速結果。

/32
IPv4 單一位址的前綴長度
/128
IPv6 單一位址的前綴長度
443
以下範例限制的目標連接埠
{
  "type": "field",
  "ip": [
    "192.168.0.0/16",
    "10.0.0.0/8",
    "fc00::/7"
  ],
  "port": "443",
  "network": "tcp",
  "outboundTag": "direct"
}

這條規則只會讓「目標 IP 屬於三個網段之一,且目標連接埠為 443,且網路類型為 TCP」的連線直連。它不會讓所有內網流量都直連;連線至內網裝置的 80 埠或 UDP 服務時,仍會繼續比對後續規則。

在同一條規則中加入 domain,不會變成「網域或 IP 任一符合即可」,而是增加一個必須同時符合的條件。尤其當目標一開始只有網域、尚未觸發解析時,這種組合很容易與預期不符。若要設定「指定網域直連,或指定 IP 直連」,請拆成兩條規則。

結論:先拆開規則,再組合條件

將網域例外與網段例外分別設為單獨規則,確認各自能命中後,再評估是否真的需要限制連接埠或網路類型。

五、規則由上往下比對,不會依「越具體越優先」排序

每次掃描規則時,第一條命中的規則就會決定出站,後續規則不會重新判定。核心不會自動把 full: 排到 geosite: 前面,也不會提高較長網域的優先權。明確例外、服務規則、廣泛分類與最後的兜底規則,都必須由設定者自行安排順序。

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "domain": ["full:login.example.com"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": ["domain:example.com"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

這是一段用於合併的 routing 設定片段,不是完整的用戶端設定。它需要現有的 proxy 與 direct 出站,其中 direct 通常使用 freedom 協定。第一條規則讓登入網域走代理,第二條則讓其他根網域及子網域直連。若將兩條規則對調,登入網域會先被第二條規則攔截。

  1. 若要先比對網域,未命中後再嘗試 IP 規則:使用 IPIfNonMatch,並避免過早加入會比對所有流量的兜底規則。
  2. 若要在掃描到 IP 規則時主動嘗試解析:可研究 IPOnDemand,並一併評估額外 DNS 請求與等待時間。
  3. 若未設定全流量兜底規則:請確認 outbounds 的第一個項目。未命中任何規則的流量會使用第一個出站;標籤名稱本身沒有任何預設效果。

六、domainStrategy 與 DNS:先確認目標資訊

同一組規則可能在瀏覽器中正常運作,在另一個程式裡卻有不同結果。問題不一定是規則遭到忽略,而可能是兩個程式送出的目標不同:一個送出網域,另一個送出已解析的 IP。路由解析策略只控制路由判斷所需的解析行為,並不保證應用程式、作業系統與核心使用相同的 DNS。

策略觸發方式檢查重點
AsIs路由不會主動為網域補上 IP原始目標是網域時,不能依賴 IP 分類進行分流
IPIfNonMatch網域第一輪未命中規則後,嘗試解析再進行比對過早命中的全流量規則會跳過第二輪比對
IPOnDemand網域請求命中需要 IP 判斷的規則時,嘗試解析IP 規則的位置與 DNS 是否可連線都會影響結果

變更路由後,既有長連線通常不會重新選擇出站。請關閉測試程式的舊連線,再送出新請求;必要時重新啟動核心。如果同時修改 DNS、嗅探和路由順序,就很難判斷是哪項設定改變了結果。每次只調整一個變數,並保留可還原的設定副本。

七、套用至用戶端,排查規則未生效

v2rayN 是桌面用戶端,v2rayNG 使用 Xray 核心,v2flyNG 使用 v2fly 核心。本文設定片段採用兩種核心常見的原生路由欄位,但不代表所有擴充語法、資料檔與介面匯入格式都完全相同。用戶端儲存的規則項目,也可能與最後產生的核心 JSON 格式不同。

  1. 備份目前方案。在 v2rayN 的「設定」→「路由設定」中確認目前啟用的路由方案;不同介面版本的選項名稱可能略有差異。先複製方案,再新增一條明確的 full: 例外規則。
  2. 確認產生的設定。檢查實際執行設定中的 routing.rules 順序、outbounds 標籤,以及設定是否遭全域代理或全域直連模式取代。
  3. 分清規則表單與完整設定。在 v2rayNG 的「設定」→「路由設定」中可檢查常用的網域和 IP 分流項目;這些表單並非原生 JSON 編輯器。複雜且有順序要求的規則,應使用目前版本明確支援的自訂設定方式。
  4. 重新建立連線。套用設定並重新啟動服務,再查看執行記錄;只重新整理頁面,可能仍會沿用舊連線。若記錄層級不足以顯示路由細節,可暫時調高,測試完成後再恢復。

已填入網域,為什麼還是走代理?

先確認這條規則排在代理兜底規則之前,再暫時改用單一 full: 進行測試。確認核心收到的是網域還是 IP;若只收到 IP,單純增加網域項目無法補回遺失的資訊。

加入 geosite 後服務無法啟動,該怎麼辦?

先還原上一份設定,並從記錄中找出具體的分類名稱與檔案路徑。確認資料檔可讀取且分類確實存在後,再新增規則;不要接連更換多個分類名稱碰運氣。

規則顯示已儲存,怎麼完全沒有變化?

確認目前啟用的路由方案就是剛才編輯的那一份,並檢查是否遭全域模式覆蓋。重新啟動核心並建立新連線後,核對實際設定中的出站標籤,不要只看表單提示。

能把所有條件都放進同一條規則嗎?

只有在所有條件都必須同時成立時才這麼做。網域、IP、連接埠和網路類型一起填入代表交集;若要表達多個彼此獨立的例外,請拆成多條規則,並依照明確例外優先的原則排列。

最後用三條新連線驗證設定:一個精確例外網域、一個一般子網域,以及一個已知的內網 IP。分別記錄目標形式、命中的規則與出站標籤。如此可分開檢查「語法能載入」、「規則確實命中」和「出站本身可連線」,避免將節點故障誤判為路由失效。更多概念請參閱術語表,設定範圍可參考進階設定。

下載用戶端v2rayN / v2rayNG