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

整理 domain、full、regexp、ip、geosite、geoip 等規則寫法,說明規則由上而下的比對順序與常見衝突,並附上可直接套用的範例。

本文摘要

自訂分流先確認規則順序,再檢查比對條件,最後確認 DNS 策略。本文適合已能正常連線至節點、需要新增網站例外規則的使用者,說明 V2Ray 與 Xray 常見的 field 路由寫法,以及如何在 v2rayN 中設定與驗證。範例使用保留的示範網域與文件位址,不代表實際網站分類。

一、路由規則先比對條件,再選擇出站

路由不是節點連線參數。VMess、VLESS 等協定負責連線至伺服器;路由則決定進入核心的請求要交由哪個出站處理。v2rayN 是設定介面,實際執行規則的是目前執行中的核心。下文使用 V2Ray/Xray 的 JSON 語法,不能直接貼到其他設定格式的編輯器。

常見規則包含 type: "field"、比對欄位與 outboundTag。標籤必須對應現有出站的 tag。將標籤設為 proxy 不會自動建立代理節點,設為 direct 也不會自動建立直連出站。用戶端產生的標籤可能不同,修改前請先確認實際設定。

53
傳統 DNS 常用的目標連接埠
443
HTTPS 常用的目標連接埠
/32
IPv4 單一位址的 CIDR 前綴

這些連接埠是請求的目標連接埠,不是用戶端的本機監聽連接埠。例如,下方規則只會將目標連接埠為 443、且網域屬於 example.com 的請求交由代理出站處理,不會涵蓋該網域的所有連線。

{
  "type": "field",
  "domain": ["domain:example.com"],
  "port": "443",
  "outboundTag": "proxy"
}

二、domain、full、regexp:網域比對範圍

需要涵蓋主網域及所有子網域時,使用 domain:;只允許特定完整主機名稱時,使用 full:。不要只因規則名稱都含有「網域」,就認為兩者相同。網域欄位填寫的是主機名稱,不是網頁網址,不應包含通訊協定、路徑或查詢參數。

規則寫法比對範圍容易混淆的邊界
domain:example.comexample.com 及其子網域,例如 api.example.com不符合 notexample.com,也不符合 example.com.test
full:example.com僅限 example.com不符合 www.example.com
example網域中包含這段字串可能符合 unrelated-example.test,不適合用於精確的網站例外規則
regexp:^api[0-9]+\.example\.com$例如 api1.example.com、api25.example.com需要加上開頭與結尾錨點;寫入 JSON 時,反斜線也必須跳脫

只有確實需要比對模式時才使用正規表示式。下例在 JSON 字串中將反斜線寫了兩次,因此核心收到的正規表示式才會包含用於比對字面句點的 \.。如果介面欄位接收的是原始規則文字,而非 JSON 字串,就不需要這層 JSON 跳脫。

{
  "type": "field",
  "domain": [
    "full:login.example.com",
    "regexp:^api[0-9]+\\.example\\.com$"
  ],
  "outboundTag": "proxy"
}

結論:單一網站例外先用 full

只想調整某個登入主機時,先新增完整主機名稱規則並進行驗證;確認所有子網域都需要使用相同出口後,再擴大為 domain 規則,避免連帶改變靜態資源及其他服務的出口。

三、ip、geoip、geosite:分開設定位址與網域集合

ip 是 JSON 欄位,geoip: 是可放入該欄位陣列的集合參照;geosite: 則放在 domain 陣列中。這兩類集合都依賴核心可讀取的對應資料檔。集合名稱及內容由資料檔決定,不是核心依名稱即時產生。

{
  "type": "field",
  "domain": ["geosite:cn"],
  "outboundTag": "direct"
}
{
  "type": "field",
  "ip": [
    "192.0.2.15/32",
    "2001:db8::15/128",
    "geoip:private",
    "geoip:cn"
  ],
  "outboundTag": "direct"
}

上方的 192.0.2.15 與 2001:db8::15 是文件示範位址,實際使用時請替換成目標服務的位址。IPv4 的 /32 和 IPv6 的 /128 都代表單一位址;網段前綴越短,涵蓋範圍通常越大。不要只為了解決單一位址的連線問題,就直接加入涵蓋整個大型網段的規則。

四、比對優先順序:例外規則必須排在寬泛規則之前

核心不會自動判斷「完整網域比網域集合更精確」。規則會依照 rules 陣列由上往下執行。如果第一條已使用 domain:example.com 設為直連,後面的 full:api.example.com 代理規則就沒有機會覆蓋它。正確順序是先放例外,再放涵蓋範圍較大的集合,最後放兜底規則。

以下是可合併至現有設定的 routing 片段,不是完整的用戶端設定。前提是現有 outbounds 中已有 proxy 和 direct 這兩個標籤,且具備所參照的資料集合。若實際使用的標籤不同,請先統一標籤,不能只複製規則而忽略出站設定。

{
  "routing": {
    "domainStrategy": "IPOnDemand",
    "rules": [
      {
        "type": "field",
        "domain": ["full:api.example.com"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": ["domain:example.com", "geosite:cn"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private", "geoip:cn"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}
測試目標首次符合規則預期出站
api.example.com:443第 1 條:完整網域例外proxy
www.example.com:443第 2 條:主網域及子網域規則direct
192.168.1.20:80第 3 條:私人位址集合direct
未符合上述集合的公開網路目標第 4 條:TCP/UDP 兜底proxy

表格是設定推演,不是網路速度測試結果。示範網域不保證提供實際服務,驗證網頁時請改用已知可正常連線的目標。如果移除最後一條兜底規則,未符合任何規則的請求通常會使用設定中的第一個出站;因此不能脫離完整設定,籠統地說「未符合規則就一定走代理」或「一定直連」。

五、domainStrategy:為什麼 IP 規則沒有生效

請求進入核心時,目標可能是網域,也可能已經是 IP。只有位址的請求,不會因為新增網域規則就自動還原成原始網域。反過來說,只有網域的請求若要符合 ip 條件,通常需要路由解析策略提供位址資訊。這就是為什麼需要另外檢查 domainStrategy。

策略路由階段的行為設定注意事項
AsIs不會為路由比對主動將目標網域解析為 IP目標原本是 IP 時仍可符合 IP 規則;這不代表出站永遠不會解析網域
IPIfNonMatch網域在第一輪沒有符合任何規則時,嘗試解析後再次比對若第一輪已符合無條件兜底規則,就不會觸發這次補充解析
IPOnDemand比對過程遇到需要 IP 的規則時,嘗試解析目標網域可能增加 DNS 查詢;也應考量解析延遲及 DNS 出口

上一節使用 IPOnDemand,是為了讓第三條位址集合規則能在最後的兜底規則之前參與判斷。如果直接改成 IPIfNonMatch,網域請求可能先符合第四條寬泛規則,導致預期的位址分流沒有生效。這不是 geoip 寫法錯誤,而是觸發解析的時機不同。

結論:先確認需要哪一種資訊

依網站分流時,先確保請求中保留網域資訊;依解析位址分流時,再選擇解析策略。DNS 伺服器、DNS 查詢的出站方式,以及嗅探是否涵蓋目標,都應分別確認,不能只切換一個 domainStrategy 就期待同時解決所有問題。

六、在 v2rayN 中套用與驗證

一般使用者建議透過路由設定介面管理規則。v2rayN 會產生執行設定,直接修改暫時產生的 JSON,可能在重新啟動服務或切換節點後被覆蓋。以下以含有「設定」→「路由設定」入口的桌面介面為例;不同版本的介面按鈕位置可能不同,但仍須逐項確認規則順序與出站對應。

  1. 保留原有設定

    開啟「設定」→「路由設定」,記下目前使用的規則集與網域解析策略。修改前請先備份現有設定,不要直接清空預設規則集。

  2. 新增單一規則

    在目標規則集中新增完整網域條件,例如 full:api.example.com,並選擇代理出站。介面中的網域輸入欄位只需填寫規則項目,不要貼上整個 routing 物件。

  3. 調整規則順序

    將這條例外規則移至對應的 domain:、geosite: 或其他寬泛規則之前。儲存後,確認主介面目前選取的就是剛修改的規則集。

  4. 重新建立連線

    重新啟動服務或重新載入設定,再關閉目標網頁的舊連線並重新瀏覽。規則變更後,既有連線通常不會自動切換至另一個出站。

  5. 確認執行記錄

    查看核心記錄中的目標主機、目標連接埠及出站標籤。先用已知可正常連線的網站驗證,再擴大規則範圍;若記錄層級不足,可暫時調高至 info 或 debug,完成後再恢復原設定。

驗證時至少測試三類請求:例外主機、同一主網域下的一般主機,以及區域網路資源。前兩類用來確認網域規則的邊界,第三類則確認私人位址直連是否被前面的寬泛代理規則攔截。若記錄中沒有出現請求,請先確認應用程式是否經過目前的代理入口,而不是繼續修改路由運算式。

七、常見規則衝突快速解答

已設定 full,為什麼還是直連?

先檢查前面是否有涵蓋該網域的 domain:、geosite: 或全流量規則。將完整網域例外移到寬泛規則之前,儲存後使用新連線測試;同時確認這條規則選擇的出站標籤。

把 domain 和 ip 放在一起,為什麼反而不符合?

在同一條 field 規則中,這兩者是必須同時符合的條件。若要「網域或位址任一項符合」就生效,請拆成兩條使用相同出站的規則;只有確實需要同時限制兩項條件時,才將兩者寫在同一條規則中。

有 geosite:cn,為什麼有些網站仍走代理?

先確認實際請求的目標主機名稱,例如頁面引用的資源可能使用不同網域。再檢查前置規則、資料檔是否已載入,以及集合是否包含該網域。可以先新增一條明確的 full: 規則進行驗證,並透過存取日誌確認實際出站。

設定 port 443 就能比對所有網頁嗎?

不能。它只會限制目標連接埠;傳統 HTTP 可能使用 80,其他服務也可能使用自訂連接埠。HTTPS 也可能透過 TCP 或 UDP 傳輸,若另外設定 network: "tcp",就不會符合 UDP 請求。

更新訂閱後,自訂規則還會生效嗎?

節點訂閱與路由規則屬於不同的設定內容。更新後請確認目前選取的仍是正確規則集,且代理出站仍指向有效節點。不要把訂閱網址當成路由設定,也不要將路由 JSON 貼到訂閱網址欄位。

請維持固定的排查順序:確認請求已進入核心、確認網域或位址資訊可用、檢查第一條符合的規則,再確認出站本身能否連線。每次只修改一類條件,才能分辨結果變化是由規則範圍、DNS 策略,還是節點網路造成。

下載v2rayN依平台選擇安裝套件