本文適合已能連線至節點,並準備調整分流規則的使用者。先確認核心取得的是網域名稱還是 IP,再選擇比對語法、排列規則,並透過記錄檔確認流量出口。文中的 JSON 是核心設定片段,不是訂閱內容;釐清兩者差異後,便能排查「已新增規則卻未生效」、「私有網路流量誤走代理」及「分類規則載入失敗」等問題。
一、路由規則如何決定流量出口
v2rayN 是用戶端介面,實際進行比對與轉送的是 V2Ray 或 Xray 核心。VMess、VLESS 是連線至節點時使用的協定,不會決定特定網站必須走哪個出口。路由會在連線處理過程中,根據目標網域、目標 IP、連接埠及入站標籤等資訊,選擇一個已設定的出站。
routing.rules 會由上而下逐條檢查,第一條符合條件的規則便會決定出口,不會繼續尋找「更精確」的規則。若沒有規則符合,通常會使用 outbounds 陣列中的第一個項目;因此也要確認預設出口,不能只檢查規則末尾。
- 同一欄位中的多個值通常採「或」的關係:
domain陣列中任一項符合,網域條件就成立。 - 同一條規則中的不同條件通常採「且」的關係:同時設定
domain和port時,網域與連接埠都必須符合。 - 不同規則依序判斷:精確的例外規則應放在範圍較廣的分類之前,預設規則則放在最後。
- 出站名稱必須確實存在:
outboundTag必須對應某個出站的tag,不能任意填寫說明文字。
二、domain、full 與 regexp 的比對範圍
domain 既是規則中的欄位名稱,也可以是欄位值的前綴,兩者並不相同。欄位用來放置網域條件,前綴則用來指定比對方式。若要涵蓋主網域及所有子網域,優先使用 domain:;若只接受完整的主機名稱,則使用 full:。
| 寫法 | 比對方式 | 範圍示例 |
|---|---|---|
example.com | 未加前綴時會採子字串比對 | 也可能比對到 notexample.com |
domain:example.com | 比對主網域及其子網域 | 會比對 img.example.com,不會比對 notexample.com |
full:api.example.com | 比對完整網域名稱 | 不會比對 img.api.example.com |
regexp:^api[0-9]+\\.example\\.com$ | 正規表示式;此處示範 JSON 字串中的寫法 | 會比對 api12.example.com,不會比對 api.example.com |
網域規則不會比對網頁 URL 的路徑。若要處理 https://api.example.com/v1/status,目標網域是 api.example.com,不能把通訊協定、路徑或查詢參數一併填入網域欄位。一般路由規則也無法直接辨識 HTTPS 路徑。
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:static.example.net",
"regexp:^edge[0-9]+\\.example\\.org$"
],
"port": "443",
"outboundTag": "proxy"
}
這條規則表示:三個網域條件任一項符合,且目標連接埠為 443 時,才會走 proxy。正規表示式中的句點必須跳脫;在 JSON 字串中,反斜線也必須再跳脫一次,因此要寫成 \\.。若填入用戶端的純文字網域欄位,通常只需寫 \.,請勿混用這兩種輸入格式。
三、ip、CIDR 與 geoip 的適用情境
ip 欄位用來處理目標 IP,可填入單一位址、CIDR 網段或 geoip: 分類。它判斷的是目前連線的目標位址,不是電腦網卡的位址,也不是節點伺服器的位址。應用程式直接連線至 IP 時,即使沒有進行網域解析,仍可符合 IP 規則。
明確指定網段
- 單一位址
192.168.1.10- IPv4 網段
192.168.0.0/16- IPv6 網段
fc00::/7- 資料依賴
- 不依賴地理分類檔案
適合用於範圍明確的區域網路或固定服務網段。
geoip 分類規則
- 私有位址類別
geoip:private- 地區位址類別
geoip:cn- 常見資料檔案
geoip.dat- 維護重點
- 分類存在且資料可讀取
分類範圍取決於使用的資料集,不代表即時網路位置。
{
"type": "field",
"ip": [
"127.0.0.0/8",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"::1/128",
"fc00::/7"
],
"outboundTag": "direct"
}
上述片段示範明確指定的直連網段,並非完整的特殊用途位址清單。若使用 geoip:private,請以目前資料集所收錄的範圍為準。公司內部網路最好明確列出實際使用的網段,避免只憑「私有網路分類應該有包含」來判斷。
四、引用 geosite 分類與資料檔案
geosite: 寫在 domain 陣列中,用來引用網域集合;geoip: 則寫在 ip 陣列中。這兩種前綴不能互換。geosite:cn 代表引用資料集中名為 cn 的集合,不能直接理解為所有以 .cn 結尾的網域。
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
}
- 先確認集合確實存在:同名資料檔可能來自不同維護來源,分類名稱、內容及屬性不一定相同。
- 分辨兩種載入失敗情況:找不到
geosite.dat是檔案或資源路徑問題;找不到指定分類則是集合名稱或資料版本問題。 - 更新後重新驗證:集合內容變更可能影響比對結果,更新成功不代表原有分流行為完全不變。
- 按需求使用屬性篩選:例如
geosite:google@cn只有在所用資料集為對應項目提供該屬性時才有預期效果,不能只憑名稱推斷。
若核心載入設定時立即結束,請先檢查記錄檔中的資源載入錯誤,而不是反覆切換節點。分類規則尚未成功載入時,連線速度測試無法證明路由設定正確。暫時移除有問題的分類引用,保留一條明確的網域規則,有助於判斷是設定錯誤還是網路故障。
五、domainStrategy 如何影響 IP 規則
routing.domainStrategy 控制路由判斷時是否解析網域目標的 IP,並不等同於最終出站所使用的 DNS 策略。它也無法憑空還原應用程式已經遺失的網域名稱:若應用程式只提供 IP,想使用網域規則還得考慮入站流量嗅探等條件,而且嗅探並非對所有流量都有效。
| 策略 | 網域目標的處理方式 | 常見影響 |
|---|---|---|
AsIs | 路由比對時不會主動將網域解析為 IP | 網域目標通常不能只靠 IP 規則分流;原本就是 IP 的目標仍可比對 |
IPIfNonMatch | 先根據現有目標資訊比對;未符合時再解析網域並重新比對 | 若第一輪已符合預設規則,就不會觸發這次的後續解析 |
IPOnDemand | 比對過程中遇到需要目標 IP 的條件時,才解析網域 | 較前面的 IP 規則可能先符合,進而影響後續的網域例外規則 |
常見的誤區是:設定了 IPIfNonMatch,又在規則末尾加入涵蓋所有 TCP、UDP 流量的代理規則。由於這條預設規則在第一輪就會符合,網域目標不會進入「未符合後解析 IP」的步驟;前面的 geoip:cn 因此可能沒有機會判斷解析結果。
結論:先決定預設處理方式,再選擇解析策略
若要用 IP 分類處理未符合規則的網域,使用 IPIfNonMatch 時可依靠第一個出站作為預設出口,不要再加上第一輪必定符合的末尾規則;若選擇 IPOnDemand,則應把必須保留的網域例外放在範圍較廣的 IP 分類之前。
這裡的 DNS 解析結果會直接影響 IP 分類判斷。若遇到「同一個網域今天直連、明天走代理」,應一併檢查解析結果與分類資料,而不是立刻認定規則順序失效。DNS 與路由欄位的完整說明,請參閱設定參考。
六、依優先順序排列的路由範例
以下範例使用 IPOnDemand,明確示範「指定網域例外、私有網路直連、網域分類、IP 分類、最後走代理」的順序。這只是一個可合併至現有設定的 routing 物件:前提是設定中已有 proxy 和 direct 這兩個出站標籤,且相關分類資料可供使用。
{
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{
"type": "field",
"domain": [
"full:api.example.com"
],
"outboundTag": "proxy"
},
{
"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"
}
]
}
}
範例中的 api.example.com 是用來說明規則的保留網域,不是可供測試的服務。它放在第一條,因此即使後續的 IP 分類也可能符合,仍會優先選擇代理。實際使用時,請改成需要固定出口的業務網域,或直接刪除這條規則。
- 保留原有設定:先在用戶端匯出目前設定,並記下正在使用的路由方案,避免修改失敗後無法還原。
- 確認實際標籤:檢查產生的設定中
outbounds的tag,確認與範例相符;用戶端可能使用不同的標籤名稱。 - 只合併路由物件:不要用這段內容覆蓋完整設定,否則會遺失入站、節點出站、DNS 等必要設定。
- 在介面中儲存並啟用:v2rayN 的選單名稱可能因版本而異,常見位置為「設定」→「路由設定」;新增規則後,還要確認已啟用目標路由方案。
- 重新建立測試連線:儲存後依用戶端提示重新載入或重新啟動核心,並關閉舊的網頁連線後再測試。已建立的連線不一定會重新執行路由比對。
七、如何確認規則確實符合
網頁能開啟,只能證明連線成功,無法證明出口正確。驗證分流時,應同時記錄目標、協定、符合的出站及測試時間。先用單一完整網域建立最小測試,再逐步加回分類規則,比一次修改十幾條規則更容易找出問題。
- 確認流量有進入核心:檢查瀏覽器是否遵循系統代理。命令列測試可使用
curl --proxy socks5h://127.0.0.1:10808 https://example.com/ -I;其中的10808必須替換為用戶端實際使用的 SOCKS 入站連接埠。 - 保留網域目標:上述命令使用
socks5h,會將網域名稱交由代理端處理;若應用程式先在本機解析,再提交 IP,測試網域規則的前提就會改變。 - 查看核心記錄檔:留意目標位址與出站標籤;記錄格式會因核心版本而異。若未啟用存取記錄,請依目前版本設定暫時開啟,不要把「沒有記錄」當成沒有流量。
- 建立三組對照測試:分別測試一個明確的網域例外、一個可連線的內部網路位址,以及一個一般公網網域,並記錄預期出口與實際出口。內部網路服務的連接埠可依實際情況使用
80或443。 - 清除測試條件:關閉舊連線後重試;必要時重新啟動測試應用程式。完成後請還原日常記錄層級,避免長期累積詳細的存取記錄。
為什麼新增了 full 規則,子網域還是沒有走代理?
full:example.com 只涵蓋這個完整主機名稱。若要一併涵蓋 www.example.com,請改用 domain:example.com,並將規則移至範圍較廣的直連規則之前,再重新建立連線。
domain 和 ip 都有填,為什麼反而更難符合?
同一條規則中的兩個欄位不是二選一。若目標是「這些網域或這些 IP 都直連」,應拆成兩條規則,並在兩條規則中設定相同的 outboundTag。
複製 geosite 分類後,核心無法啟動怎麼辦?
查看第一筆載入錯誤,確認 geosite.dat 的資源路徑與分類名稱。先移除該分類,使用 full: 規則確認核心能否正常運作,再還原有效的資料檔案與分類。
Android 用戶端可以直接照搬桌面版的完整設定嗎?
v2rayNG 使用 Xray 核心,v2flyNG 使用 v2fly 核心;基本比對語法相近,但出站標籤、資源檔案位置與匯入方式取決於用戶端。請先確認所選核心支援的欄位,再移植路由片段,不要直接覆蓋整份執行設定。
排查時建議依序檢查「目標資訊、規則順序、解析策略、資料檔案、實際出口」。先確認一條精確規則能夠生效,再逐步加入網域集合與 IP 分類,通常比反覆更換整套路由規則更可靠。