先釐清路由規則處理的對象
V2Ray 與 Xray 的路由模組位於入站與出站之間。應用程式流量進入核心後,路由模組會讀取目標網域、目標 IP、連接埠、網路類型、入站標籤等資訊,再將這條連線交給某個出站。常見出站標籤包括代理連線使用的 proxy、本機直連使用的 direct,以及拒絕連線使用的 block。這些名稱不是固定關鍵字,而是設定中 outbounds 項目的 tag;規則裡的 outboundTag 必須與實際標籤完全一致。
VMess、VLESS 等協定負責用什麼方式在用戶端與遠端之間傳輸資料,路由規則則負責選擇哪一條出站。兩者處於不同層面。將 VMess 更換為 VLESS,不會自動改變分流結果;匯入新的訂閱,也不代表原有自訂規則一定仍然適用。使用 v2rayN、v2rayNG 或 v2flyNG 時,應分別檢查目前的設定、路由模式與核心類型,確認規則最後確實寫入正在執行的設定。
一條典型的欄位規則由 type、比對條件與目標出站組成。目前常用的類型是 field。同一條規則可以包含多種條件,例如同時限定網域與連接埠;不同類別通常必須同時符合。同一類別中的多個值則代表候選集合,只要符合其中一個即可套用該規則。
{
"type": "field",
"domain": [
"domain:example.com",
"full:api.example.net"
],
"port": "443",
"network": "tcp",
"outboundTag": "proxy"
}
這個範例只處理 TCP 443 連接埠,而且目標網域必須符合兩個網域項目之一。若存取的是同一網域的 80 連接埠,就不會符合。實際設定時,不要為了「更精確」而任意疊加條件;每增加一種條件,都可能將原本需要處理的連線排除在外。
domain 的四種常見比對寫法
domain 陣列不只接受完整網域。前綴會決定核心如何解讀每個項目。最常見的寫法是 full:、domain:、regexp:,以及不含前綴的純字串。選錯前綴,常會造成比對範圍過大,或只符合主網域卻漏掉子網域。
| 寫法 | 比對範圍 | 適用情境 |
|---|---|---|
full:www.example.com |
僅比對完整目標網域 | 單獨處理一個明確的主機名稱 |
domain:example.com |
比對根網域及其子網域 | 處理一個網站及其常見子網域 |
regexp:^api\d+\.example\.com$ |
依正規表示式比對 | 網域具有固定編號或格式 |
example |
依網域關鍵字比對 | 需要涵蓋含有特定片段的網域 |
full::只符合一個精確網域
full:api.example.com 適合 API 主機、更新伺服器等界線明確的目標。它不會一併涵蓋 www.example.com 或 cdn.api.example.com。若只想調整某個子網域,不希望影響同一主網域下的其他服務,應優先使用 full:。
domain::涵蓋根網域與下層子網域
domain:example.com 會處理 example.com,也會處理 www.example.com、static.example.com 等下層網域,但不會將名稱相似、邊界不同的網域視為同一網站。按整個網站進行分流時,這通常比關鍵字寫法更穩妥。
純字串與正規表示式:範圍較寬,使用要審慎
不含前綴的值會以關鍵字方式比對。項目 example 可能涵蓋多個名稱含有該片段的網域,適合目標網域變化較多且命名規律明確的情況,但也更容易誤傷無關網站。正規表示式的控制力更強,同時也會增加維護與排錯成本。能用 full: 或 domain: 表達時,沒有必要先寫複雜的正規表示式。
{
"type": "field",
"domain": [
"full:status.example.com",
"domain:media.example.net",
"regexp:^edge-[0-9]+\\.example\\.org$"
],
"outboundTag": "proxy"
}
JSON 字串中的反斜線需要跳脫,因此正規表示式裡的 \. 在 JSON 檔案中要寫成 \\.。這是許多「正規表示式單獨測試正常,放進設定卻無法啟動」問題的來源。儲存後若核心立即退出,應先查看執行記錄中的 JSON 解析錯誤與規則解析錯誤。
ip、CIDR 與 geoip 的寫法
ip 陣列用於比對目標 IP,可以放入單一位址、CIDR 網段,也可以引用 geoip 資料集。單一位址適合固定伺服器,CIDR 適合連續網段。IPv4 的 192.0.2.0/24 代表該網路前綴涵蓋的一組位址;IPv6 也採用前綴長度寫法,例如 2001:db8::/32。
{
"type": "field",
"ip": [
"192.0.2.25",
"198.51.100.0/24",
"2001:db8::/32"
],
"outboundTag": "direct"
}
CIDR 的重點是網路前綴,而不是起訖位址的文字縮寫。前綴長度越大,範圍越小。IPv4 中 /32 只指向一個位址,/24 通常涵蓋同一前綴下的 256 個位址。不要把服務供應商目前解析出的某個位址直接擴成過大的網段,否則同一網路中的無關服務也會被改道。
geoip:private 常用來比對私有網路與本機用途位址,適合作為直連規則的一部分。如此一來,存取區域網路閘道、內部面板或本機裝置時,就不會被送往遠端代理。若啟用 TUN 等更廣泛的流量接管方式,私有位址直連規則尤其需要放在通用代理規則之前。
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
}
geoip:cn 這類項目依賴目前核心載入的 IP 資料檔。資料集代表一批網路位址,不等同於網域集合,也不保證某個網站的所有伺服器始終位於同一地區。大型網站經常使用內容傳遞網路,同一網域在不同網路、不同時間可能解析到不同位址,因此只靠 IP 地理集合進行網站層級分流並不總是穩定。
geosite 是網域集合,不是協定名稱
geosite: 寫在 domain 陣列中,用於引用預先整理的網域集合。例如 geosite:cn 常用來表示一組對應分類的網域,geosite:category-ads-all 常用來表示廣告相關網域集合。實際可用的名稱取決於目前的資料檔;名稱不存在、檔案未載入或資料版本不相容時,規則可能無法正常生效。
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
}
geosite 的優點是不必手動維護大量網域。它適合建立基礎分流層,但不應理解為即時線上查詢。資料檔更新後,集合內容才會改變。遇到尚未收錄的新網域時,可以在 geosite 規則之前增加一條明確的 full: 或 domain: 規則,先修正目前的連線路徑,再考慮更新資料。
若要使用廣告分類進行阻擋,必須先在出站中設定對應的拒絕出站,並讓規則引用正確的標籤。僅寫 outboundTag: "block",而完整設定中沒有 block 標籤,並不能建立有效的連線鏈路。
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
}
依分類進行分流時,也要留意例外需求。假設某個網域被集合規則判定為直連,但目前網路環境中必須走代理,就應將該網域的明確代理規則放在集合規則前面。反過來,若某個網域被寬泛的代理集合涵蓋,卻需要固定直連,也要先寫更具體的直連規則。
比對優先順序:規則由上而下,符合後即停止
路由規則會依照 rules 陣列中的順序逐一檢查。第一條符合條件的規則會決定出站,後續規則不再參與。這表示「更具體的規則」不會自動取得更高優先順序,真正的優先順序就是排列位置。即使第二條使用 full: 精確比對,只要第一條寬泛規則已經符合,第二條也沒有執行機會。
以下順序會讓 full:special.example.com 的直連規則失效,因為前面的 domain:example.com 已經涵蓋它:
[
{
"type": "field",
"domain": [
"domain:example.com"
],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"full:special.example.com"
],
"outboundTag": "direct"
}
]
正確做法是將例外放在前面,把涵蓋範圍更廣的規則放在後面:
[
{
"type": "field",
"domain": [
"full:special.example.com"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"domain:example.com"
],
"outboundTag": "proxy"
}
]
整理順序時,可以採用「本機保護、明確例外、分類集合、區域規則、最後兜底」的思路:
- 先處理私有網路、區域網路與必須保留的本機連線。
- 接著放入單一網域、單一 IP 等明確例外。
- 之後放入 geosite、geoip 與較大的 CIDR 集合。
- 最後使用涵蓋 TCP、UDP 的通用規則決定剩餘流量。
通用兜底規則一定要放在最後。若將 network: "tcp,udp" 的代理規則放在最前面,絕大多數連線會立即符合,後面的直連與阻擋規則就形同虛設。
domainStrategy 如何影響網域與 IP 規則
routing.domainStrategy 決定路由階段如何處理網域解析。常見值包括 AsIs、IPIfNonMatch 與 IPOnDemand。不同核心版本與用戶端產生設定的方式可能存在差異,修改前應確認最終執行設定,而不是只看介面選項名稱。
| 策略 | 處理重點 | 使用時需檢查 |
|---|---|---|
AsIs |
依原始目標資訊執行網域規則,不主動為路由比對解析 IP | 依賴 IP 分流的網域連線可能無法符合預期規則 |
IPIfNonMatch |
網域規則未符合時,再解析 IP 並嘗試套用 IP 規則 | DNS 伺服器、解析結果與最終兜底順序 |
IPOnDemand |
路由判斷需要 IP 條件時可能觸發解析 | 規則數量、DNS 路徑與額外查詢行為 |
若分流主要依賴 domain: 與 geosite:,讓網域資訊持續參與判斷通常更直觀。若還要讓網域連線依據 geoip: 或 CIDR 分類,就必須同時檢查 domainStrategy 與 DNS。解析取得哪個 IP,會直接影響後續 IP 規則的結果。
路由 DNS 與應用程式本身的解析行為也需要區分。部分連線會直接提交 IP,核心看不到原始網域,此時網域規則無法符合,只能依靠 IP、連接埠等條件。部分應用程式提交網域,則可以先參與 domain 或 geosite 判斷。排錯時應查看記錄中的目標形式,不要只憑瀏覽器網址列推斷核心收到的一定是網域。
三組常見規則組合
組合一:區域網路直連,其餘流量走代理
這組結構適合需要保留本機裝置存取,同時讓其餘 TCP、UDP 流量進入代理出站的設定。第一條先接住私有位址,第二條作為最後兜底。
{
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
啟用前請確認代理出站能處理所需的網路類型,並檢查本機 DNS、區域網路網域與私有 IP 的對應關係。如果內部服務透過自訂網域存取,可以額外加入一條內部網域直連規則,放在最後兜底之前。
組合二:常用集合直連,其餘流量走代理
這組結構先保護私有網路,再讓 geosite 與 geoip 集合直連,最後將未符合的連線交給代理。它適合以區域集合為基礎的分流,但實際效果取決於資料檔與 DNS 解析結果。
{
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
若某個網域被 geosite 集合涵蓋但需要走代理,可在 geosite:cn 前加入精確的代理項目。若將例外放在集合之後,就會被前面的直連規則攔截。
組合三:阻擋分類、保留例外,其餘依集合分流
更完整的結構可以先放入必須存取的例外,再處理阻擋分類,接著執行直連集合與代理兜底。將例外放在阻擋規則之前,表示它具有更高的優先順序。
{
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"full:required.example.com"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
範例中的網域僅用於說明結構,使用時應替換為實際目標。整段路由設定也必須嵌入完整設定的 routing 物件中,不能將片段單獨視為可執行設定。若用戶端提供圖形化規則編輯器,應依相同順序逐條建立,並在儲存後查看產生的結果。
在 v2rayN、v2rayNG 與 v2flyNG 中套用
v2rayN 桌面版通常透過路由設定、規則集或自訂設定管理分流。不同版本的介面名稱可能有所調整,但檢查方法一致:先確認目前選用的路由模式,再確認規則已套用至正在使用的設定,最後重新啟動相關核心並查看記錄。只在編輯視窗儲存,卻沒有切換至對應的規則方案,執行結果不會改變。
v2rayNG 使用 Xray 核心時,可透過用戶端提供的路由選項套用常見規則。v2flyNG 使用 v2fly 核心時,規則語意仍圍繞網域、IP、連接埠與出站標籤展開,但可用欄位應以目前核心實際支援的內容為準。匯入訂閱通常只會更新伺服器節點資訊,不應預設它會替使用者合併所有本機自訂分流。
調整規則前,建議先複製目前可用的設定,之後每次只修改一個變數。例如先加入一條 full: 網域規則並驗證,再加入 geosite 集合,最後調整 domainStrategy。一次加入數十條規則後若連線異常,很難判斷是 JSON 結構、標籤名稱、資料檔還是比對順序造成的。
規則未生效時,依這個順序檢查
- 檢查設定是否真正啟用。確認用戶端目前執行的是剛才修改的路由方案,而不是另一個節點設定或預設規則。
- 檢查 JSON 與欄位位置。
rules應位於routing物件中,字串跳脫、逗號與方括號都必須完整。 - 檢查出站標籤。
outboundTag必須與完整設定中的標籤逐字一致,大小寫也不能混用。 - 檢查前置規則。確認目標是否已被更早的 domain、IP、連接埠或通用網路規則符合。
- 檢查目標是網域還是 IP。若應用程式直接連線至 IP,任何 domain 與 geosite 規則都無法從該連線還原原始網域。
- 檢查 DNS 與 domainStrategy。需要進行 IP 二次判斷時,確認路由階段能夠取得解析結果。
- 檢查資料檔。geosite 與 geoip 項目依賴目前載入的資料內容與分類名稱。
- 查看執行記錄。重點尋找設定解析錯誤、找不到出站標籤、資料載入失敗,以及實際選用的出站。
測試時應選擇可重複的目標,並排除應用程式本身的連線重用影響。已建立的長連線通常不會因規則剛修改就立即重新選擇路徑。儲存設定後重新啟動核心,再重新發起連線,結果會更容易判斷。網域解析快取也可能保留舊位址,涉及 geoip 或 CIDR 時尤其要考慮這一點。
撰寫規則時保留清楚的決策鏈
穩定的路由設定不取決於規則數量,而取決於每一層是否有清楚的界線。精確網域負責例外,domain: 負責整個網站,geosite 負責批次網域,CIDR 與 geoip 負責網路位址,最後兜底負責剩餘連線。將窄範圍規則放在前面、寬範圍規則放在後面,就能減少大多數優先順序錯誤。
設定完成後,用「目標是什麼、先符合哪一條、交給哪個出站」三個問題逐條檢查。只要這條決策鏈能在記錄與設定中相互對應,之後新增 VMess、VLESS 節點或更新訂閱時,也能快速判斷問題是在節點連線還是本機分流。