閱讀設定檔時,先找入口、出口及連接兩者的標籤,再檢查路由與 DNS。本文以一份不含遠端伺服器憑證的傳統 V2Ray JSON 設定檔為例,逐段說明欄位、比對順序與檢查方式。適合已匯入訂閱、想了解 v2rayN 匯出檔的使用者;範例僅示範本機 SOCKS 連線、直連與阻擋,不提供遠端代理功能。
一、先區分用戶端設定與核心執行設定
v2rayN 是管理介面,V2Ray 與 Xray 則是實際處理連線的核心。訂閱會儲存伺服器資訊或設定來源,介面也會保存群組、目前選取項目及路由預設等狀態;核心啟動時讀取的 JSON,則用來描述監聽連接埠、出站協定與路由規則。這幾類檔案不能只因副檔名相同就互相替換。
本文採用 V2Ray 傳統 JSON 設定結構,不涵蓋所有核心的專屬欄位。v2rayNG 使用 Xray 核心,v2flyNG 使用 v2fly 核心;即使兩者都有 inbounds 和 outbounds,也不代表所有協定選項都相容。尤其 REALITY、流量控制與傳輸相關欄位,應以實際執行核心的文件為準。
閱讀檔案時,沿著這條鏈追查引用關係即可。log 用來觀察處理過程,dns 提供名稱解析功能;兩者並非必須依照檔案中的排列位置依序執行的網路節點。JSON 物件中五個模組的排列順序不會決定處理流程,但路由規則陣列的順序會影響結果。
- 物件:
{}用來儲存鍵值,例如某個入站的監聽位址與協定。 - 陣列:
[]用來儲存多個項目,例如多個出站或多條路由規則。 - 型別:
10808是數字,"10808"是字串,false是布林值,不能任意互換。 - 語法:本文採用標準 JSON,不使用註解或尾端逗號;鍵名與字串都以英文雙引號括住。
二、完整範例:本機 SOCKS 入站與兩種出站
以下提供一份用來理解結構的完整設定檔。它只監聽本機回環位址並接收 SOCKS 請求;目的連接埠為 25 的 TCP 連線會遭到阻擋,其餘未符合規則的連線則預設直連。這份設定不會讓應用程式自動使用代理,也不會連線至遠端代理伺服器。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": false
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"inboundTag": ["local-socks"],
"network": "tcp",
"port": "25",
"outboundTag": "block"
},
{
"type": "field",
"ip": [
"127.0.0.0/8",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["full:localhost"],
"outboundTag": "direct"
}
]
},
"dns": {
"servers": ["localhost"],
"queryStrategy": "UseIP"
}
}
這些數值是範例設定中的固定值,並非所有版本用戶端的預設值。如果本機已有程式使用 10808,請改用其他未占用的連接埠,並同步更新應用程式中的 SOCKS 位址。範例中的私有網路直連規則僅用來展示寫法,並非完整的本機網路位址清單。
三、log 與 inbounds:先確認請求能否進入核心
log.loglevel 用來設定記錄的詳細程度。範例使用 warning,適合查看警告與錯誤;排除問題時可暫時改為 info,必要時再使用 debug。未設定 access 或 error 檔案路徑,不代表日誌一定不會輸出;啟動核心的用戶端仍可能接收並顯示日誌。
inbounds 是入口陣列。範例只接收傳送至 127.0.0.1:10808 的 SOCKS 連線,因此應用程式必須明確使用這個位址。若將瀏覽器設為 HTTP 代理,卻指向只提供 SOCKS 的連接埠,就會發生協定不符;單純啟動核心也不會變更系統代理設定。
日誌觀察項目
- loglevel
- warning
- 暫時排除問題
- info 或 debug
- 輸出位置
- 取決於路徑設定與啟動方式
找出問題後,請降低記錄詳細程度,避免長期記下過多連線資訊。
本機入口項目
- listen
- 127.0.0.1
- port
- 10808
- protocol
- socks
- tag
- local-socks
tag 是供路由引用的名稱,不是監聽位址,也不是遠端節點名稱。
auth: "noauth" 表示此 SOCKS 入站不需要驗證,因此範例將監聽範圍限制在本機。請勿為了讓其他裝置連線,就直接將監聽位址改為所有介面,卻忽略存取控制。udp: false 表示此入站未啟用 SOCKS UDP 轉送,無法用來確認 UDP 應用程式是否正常。
連接埠遭占用屬於入口啟動問題,連線逾時則是後續鏈路的問題。先確認日誌中沒有監聽失敗,再檢查路由、DNS 或遠端伺服器,可減少無效修改。
四、outbounds:協定負責連線,tag 負責供規則引用
outbounds 陣列定義連線如何離開核心。範例中的 freedom 會直接連線至目標,blackhole 則會丟棄符合條件的流量。direct 與 block 只是自訂標籤;更改標籤名稱不會改變協定行為,但所有引用該標籤的規則都必須一併修改。
| 欄位 | 範例值 | 閱讀重點 |
|---|---|---|
| outbounds[0].tag | direct | 路由引用名稱;此處也是預設出站 |
| outbounds[0].protocol | freedom | 直接連線至目標,不經過遠端代理 |
| outbounds[1].protocol | blackhole | 阻擋路由選取的連線 |
| settings | 空物件 | 本例採用預設行為;代理協定通常需要更多參數 |
在此使用的傳統設定模型中,未符合任何規則的連線會交由第一個出站處理。因此,調整陣列順序可能改變預設行為。若將 block 移至第一項,原本預設直連的請求就可能遭到阻擋;請勿把排序當成單純的介面整理。
實際的 VMess 或 VLESS 出站還會包含伺服器位址、連接埠、驗證資訊,以及可能存在的 streamSettings。其中 protocol 用來指定代理協定,傳輸與安全層參數則設在其他位置。不能只把 freedom 改成 vless 就期待成功連線,也不能直接互換不同協定的 settings。
判斷預設行為:先看第一項,再檢查標籤引用
修改設定前,先記下第一個出站的 tag,並搜尋所有 outboundTag。只有同時確認預設路徑與明確指定的路徑,才能判斷連線最後會直連、走代理或遭到阻擋。
五、routing:依序比對,不要用規則長短猜優先順序
routing.rules 會由上而下檢查,符合條件後便使用對應的出站。它不會自動將較長的網域名稱或較小的 IP 網段排在優先位置。同一條規則中的不同條件通常必須同時符合;同一條件陣列中的多個值則通常符合任一個即可。設定前,請先分清楚「必須同時符合」與「符合任一項」的差別。
- 第一條規則:入站標籤必須是
local-socks、網路必須是 TCP,且目的連接埠必須為25。三個條件都符合時,才會交由block處理。 - 第二條規則:目標 IP 落在列出的任一網段時,會交由
direct處理。即使目標是私有網路位址,只要先符合上一條 TCP 25 規則,仍會遭到阻擋。 - 第三條規則:
full:localhost表示精確比對此網域,不會比對所有包含 localhost 字樣的名稱。 - 全部未符合:使用第一個出站,也就是本例的
direct。本例的第二、三條規則與預設出站的結果相同,保留它們是為了示範規則寫法。
inboundTag 必須引用入站的 tag;outboundTag 必須引用出站的 tag。大小寫與拼字都必須一致。這些不是核心會自動辨識的中文群組名稱,也不會隨用戶端中顯示的節點名稱自動更新。
domainStrategy: "AsIs" 表示路由階段不會為了比對 IP 規則而主動將網域解析為位址。如果應用程式送來的是網域名稱,第二條 IP 規則未必能據此比對;若送來的原本就是 IP,則可直接檢查網段。改為 IPIfNonMatch 時,若網域階段未比對成功,會嘗試解析後再比對;這不代表所有 DNS 請求都會改走遠端。
full:example.com:只比對完整網域名稱,適合精確測試。domain:example.com:比對此網域及其子網域,適合依網域範圍分流。port: "25":此處指目標連接埠,不是本機監聽的10808。ip:用於比對目標位址,不能表示「來自某台區域網路裝置」的來源條件。
六、dns:區分解析策略與流量出口
範例的 dns.servers 只有 "localhost",表示使用本機系統的解析功能,而不是在本機監聽 DNS 連接埠。queryStrategy: "UseIP" 允許查詢 IPv4 與 IPv6 位址;實際回傳結果仍會受到網域紀錄、解析器與網路狀況影響。
設定 dns 模組,不代表所有應用程式的 DNS 請求都會進入核心。應用程式可能已自行解析,再將 IP 傳給 SOCKS;也可能把網域名稱交由核心處理。前者可能缺少依網域分流所需的資訊,後者則會保留目標網域名稱。入口如何接收請求,與 DNS 模組如何解析,是兩個不同的問題。
| 設定位置 | 控制內容 | 不應混淆為 |
|---|---|---|
| dns.servers | 內建 DNS 模組可用的解析來源 | 作業系統中所有程式的 DNS 設定 |
| dns.queryStrategy | 查詢位址族的策略 | 選擇直連或代理的路由規則 |
| routing.domainStrategy | 路由比對時是否使用解析結果 | 強制所有解析請求走相同出口 |
| 出站中的解析策略 | 該出站如何處理目標網域名稱 | 所有核心共用的統一欄位 |
若要依網域選擇解析器,可以進一步了解 DNS 伺服器物件中的 domains 等欄位,也要確認查詢流量如何抵達解析器。只更換 DNS 位址,無法證明解析請求經過預期的代理路徑。排除問題時,應同時確認請求帶入的是網域名稱還是 IP,以及最後選用的出站。
七、如何檢查匯出檔:從語法到實際連線
編輯前先複製一份設定檔,避免直接覆寫用戶端自動產生的執行檔。v2rayN 可能在切換節點、更新訂閱或重新啟動核心時重新產生設定檔;如果修改只留在暫存的執行檔中,下次啟動時可能就會消失。若要長期保留變更,請儲存至用戶端對應的路由、DNS 設定或自訂設定入口;實際位置請以目前版本的介面為準。
- 檢查 JSON 語法:確認雙引號、括號與逗號都成對。若本機已安裝 Python,可使用以下命令檢查基本語法;檢查通過不代表核心支援所有欄位。
- 確認實際使用的核心:在用戶端的核心選擇設定與啟動日誌中,核對名稱、版本及讀取的設定檔路徑,不要只看用戶端名稱。
- 檢查引用關係:逐一搜尋
inboundTag與outboundTag,確認都能找到對應定義,並核對第一個出站。 - 檢查監聽與請求:確認
127.0.0.1:10808能正常啟動,且應用程式使用 SOCKS 協定與相同連接埠。 - 逐項測試:每次只修改一個模組;先測試一般 TCP 請求,再測試網域規則與阻擋規則,避免同時變動多個因素。
python -m json.tool config.json
若語法檢查通過,但核心仍拒絕啟動,請繼續查看日誌中的欄位路徑與錯誤類型。未知欄位、協定選項不相容及連接埠遭占用是不同問題,無法一律靠更換 DNS 解決。分享日誌或設定檔前,請刪除伺服器驗證資訊、訂閱連結與不必要的個人路徑。
JSON 檢查通過,為什麼還是無法啟動?
語法檢查只能確認檔案可供解析。請開啟用戶端啟動日誌,找出第一個錯誤,並核對協定名稱、欄位型別與實際使用的核心;若訊息指出位址遭占用,請先停止占用 10808 的程式,或同步更換監聽連接埠。
修改 outboundTag 後,為什麼原本的節點不再運作?
先確認新標籤與某個出站的 tag 完全一致,再檢查規則順序。請勿只修改路由引用,卻漏改出站定義;也要確認請求是否已先符合前面的規則。
複製這份設定後,為什麼沒有連上訂閱中的伺服器?
本文只有 freedom 和 blackhole 兩種出站。若要使用遠端代理,應由用戶端根據有效訂閱產生對應出站,再檢查路由如何引用該出站;請勿在這份範例中自行猜填驗證參數。
重新啟動 v2rayN 後,手動修改的內容為什麼不見了?
通常是用戶端重新產生了執行設定。請保留修改前後的副本,將需要長期保存的路由或 DNS 調整寫入用戶端的持久化設定,再重新啟動並核對新產生的檔案,不要一再修改暫存檔。