JSON 結構總覽與讀取順序
先區分核心設定與用戶端設定
V2Ray 設定檔是一個 JSON 物件。核心啟動後會讀取頂層欄位,再將入站監聽、出站連線、路由選擇、網域解析與連線策略組合成處理鏈。它不是依照檔案中欄位的出現順序逐行執行,因此把 routing 寫在 inbounds 前面,不會改變執行結果。真正決定流量方向的是欄位之間的引用關係,尤其是 tag、inboundTag、outboundTag 與 balancerTag。
v2rayN、v2rayNG 與 v2flyNG 都有各自的介面設定與資料儲存方式。用戶端顯示的訂閱分組、系統代理開關與分應用程式設定,不一定會原樣存在於核心 JSON 中。桌面端排錯時,請先確認目前查看的是本次啟動實際載入的設定,而不是舊備份或訂閱原文。用戶端重新產生設定後,直接寫入執行檔的手動內容可能會被取代。需要長期保留的規則,建議優先填入用戶端提供的自訂路由、DNS 或進階設定入口。
常見頂層欄位
| 欄位 | 類型 | 用途 | 主要關聯 |
|---|---|---|---|
log |
物件 | 定義存取日誌、錯誤日誌與日誌層級 | 故障定位 |
inbounds |
陣列 | 接收來自本機應用程式或網路介面的連線 | routing.inboundTag |
outbounds |
陣列 | 定義流量最終使用的連線方式 | routing.outboundTag |
routing |
物件 | 依網域、位址、連接埠、協定與來源選擇出站 | 入站與出站標籤 |
dns |
物件 | 定義核心內部的網域解析行為 | routing.domainStrategy |
policy |
物件 | 定義連線逾時、統計開關與系統層級策略 | 使用者 level、stats |
stats |
物件 | 啟用核心統計模組 | policy 中的統計開關 |
最小設定不等於只有一個伺服器物件。完整處理至少需要一個入站與一個出站。入站決定應用程式如何將請求交給核心,出站決定核心如何處理請求。路由、DNS 與策略都可以暫時省略,此時核心會使用預設行為;但一旦加入路由規則,所有被規則引用的標籤都必須實際存在。標籤區分大小寫,proxy 與 Proxy 會被視為不同值。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
}
]
}
此範例只在本機迴路位址監聽 SOCKS,收到的流量全部交給 freedom 出站。它適合檢查核心能否讀取 JSON、連接埠能否監聽,以及應用程式是否正確指向代理連接埠,但不包含遠端代理伺服器。listen 使用 127.0.0.1 時,區域網路上的其他裝置無法連線至該連接埠;改為監聽所有網路介面前,應先確認存取範圍與系統防火牆規則。
JSON 語法邊界
JSON 的物件鍵與字串必須使用雙引號,陣列或物件最後一項後不能保留逗號,布林值只能寫 true 或 false,連接埠數字不能加引號。標準 JSON 不接受註解,因此說明文字應放在站外文件或用戶端備註欄位中,不要插入執行設定。複製範例時也要留意全形標點、彎引號與不可見空格,這些字元常由富文字編輯器帶入。
設定的可讀性主要依靠縮排、標籤與分段。建議統一使用兩個空格縮排,標籤採用簡短且能說明用途的英文詞,例如 local-socks、proxy、direct、block。不要依賴陣列位置表達用途。日後新增出站或調整路由時,穩定的標籤能減少錯誤指向。如果目標只是匯入訂閱並開始連線,不需要手寫整份檔案,可直接依照V2Ray 使用教學操作;需要選擇用戶端時,請前往下載中心。
inbounds 入站:監聽、協定與流量入口
入站物件負責什麼
inbounds 是陣列,每個元素代表一個獨立入口。桌面用戶端常見入口是本機 SOCKS 與 HTTP 代理連接埠;透明接管情境也可能使用 dokodemo-door。請求進入核心後會帶有入站標籤、目標位址、目標連接埠、網路類型等屬性,這些屬性接著交由路由模組匹配。入站不決定最終走代理、直連或攔截,它只負責接收、解析並將請求送入處理鏈。
常用公共欄位包括 tag、listen、port、protocol、settings、sniffing 與 streamSettings。其中 settings 的結構由協定決定:SOCKS 可設定驗證方式與 UDP,HTTP 可設定帳號,dokodemo-door 可設定轉送目標。不同協定的欄位不能混用,把 SOCKS 的 udp 放到 HTTP 入站中,不會得到預期效果。
本機 SOCKS 與 HTTP 雙入口
{
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
],
"routeOnly": true
}
},
{
"tag": "local-http",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
兩個入站使用不同連接埠。支援 SOCKS 的應用程式連線至 127.0.0.1:10808,只支援 HTTP 代理的應用程式連線至 127.0.0.1:10809。同一個位址與連接埠不能同時由兩個程序監聽;如果用戶端啟動後提示連接埠被占用,應先檢查系統中是否已有另一份用戶端、舊核心程序或其他代理工具正在執行,再決定關閉程序或修改連接埠。
auth: "noauth" 適用於僅繫結迴路位址的本機入口。若監聽範圍擴大到區域網路,存取控制不應只依賴應用層驗證,還要配合系統防火牆限制來源。設定中的 udp: true 表示 SOCKS 入站接受 UDP 轉送請求,但不代表所有出站協定、傳輸方式與上游網路都一定能完成 UDP 通訊。出現網頁正常、語音、遊戲或網域解析異常時,需要分別從入站、路由、出站與上游支援四個層面檢查。
sniffing 與目標還原
部分應用程式會先將網域解析成位址,再向代理連接埠提交位址。此時路由模組看到的目標可能只有位址,網域規則無法直接匹配。sniffing 會從符合條件的連線中識別 HTTP 主機名稱或 TLS 交握中的伺服器名稱,讓路由模組取得網域線索。它不會將所有流量都轉換成可識別的網域,也不應被理解為通用封包擷取功能。
destOverride 指定允許識別的類型。範例啟用了 http 與 tls。routeOnly: true 表示識別結果主要用於路由判斷,而不直接替換原始連線目標,這樣可以降低目標改寫造成的相容性差異。若某個應用程式在啟用目標識別後連線異常,可先只對 SOCKS 入站啟用,再按應用程式測試;原因尚未定位前,不要同時修改路由、DNS 與出站傳輸。
| 欄位 | 建議檢查點 | 常見現象 |
|---|---|---|
listen |
本機使用時優先繫結迴路位址 | 繫結錯誤導致應用程式無法連線或擴大暴露範圍 |
port |
確認未被其他程序占用 | 核心啟動失敗,用戶端顯示連線未建立 |
protocol |
與應用程式實際支援的代理類型一致 | 將 HTTP 請求傳送到 SOCKS 連接埠後立即失敗 |
udp |
同時檢查出站與上游能力 | TCP 正常但 UDP 業務異常 |
tag |
與路由中的 inboundTag 完全一致 | 限定入站的規則始終未命中 |
多入口的界線
多入口適合區分應用程式來源。例如為瀏覽器使用一個入站,為開發工具使用另一個入站,再在路由規則中依 inboundTag 指向不同出站。這樣比頻繁修改全域規則更清楚。若兩個入站實際需要相同策略,就沒有必要為了形式完整而繼續拆分。入口越多,連接埠衝突、系統代理指向錯誤與規則遺漏的機率越高。
Android 用戶端通常透過系統提供的網路介面接收應用程式流量,介面中的分應用程式代理與繞過選項會參與產生執行設定。桌面 JSON 的本機監聽方式不能直接套用到行動裝置。v2rayNG 使用 Xray 核心,v2flyNG 使用 v2fly 核心,兩者的介面欄位與核心可用能力可能不同。需要手動調整時,應先確認目前的用戶端、核心與實際產生設定的位置,再對照欄位處理。
outbounds 出站:伺服器、協定與傳輸層
出站物件的三層結構
outbounds 同樣是陣列。每個出站通常由三層資訊組成:公共層使用 tag 與 protocol 標示用途;協定層在 settings 中填寫伺服器位址、連接埠與使用者參數;傳輸層在 streamSettings 中填寫 TCP、WebSocket、gRPC、TLS 等設定。排錯時應分三層核對,不要把「協定正確」直接等同於「整條連線正確」。
伺服器提供的協定、位址、連接埠、使用者識別碼、傳輸方式、安全層與伺服器名稱必須視為一組資訊讀取。只修改協定名稱,或只將 VMess 使用者參數替換成 VLESS 使用者參數,都不能完成設定轉換。訂閱匯入的主要價值,正是將這些關聯欄位作為完整節點交給用戶端。手動輸入時,建議逐項對照伺服器端資料,不要依賴舊節點的預設值。
VLESS over TCP with TLS 範例
{
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "server.example.com",
"port": 443,
"users": [
{
"id": "11111111-1111-4111-8111-111111111111",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "server.example.com",
"allowInsecure": false
}
}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
]
}
範例中的網域與使用者識別碼僅用於展示結構,實際連線必須使用伺服器端提供的資訊。address 是連線目標,可以是網域或位址;port 是數字。VLESS 使用者項目中的 id 用於身分識別,encryption 通常依伺服器端要求填寫。它與外層 TLS 是不同概念:前者屬於協定使用者參數,後者屬於傳輸安全層,不能互相取代。
network: "tcp" 表示底層傳輸為 TCP。security: "tls" 啟用 TLS,tlsSettings.serverName 用於指定交握時使用的伺服器名稱,通常應與伺服器憑證及部署資訊一致。allowInsecure: false 維持正常的憑證驗證行為。連線失敗時,不應先將它改成 true 來掩蓋問題,而應核對系統時間、伺服器名稱、位址解析、憑證涵蓋範圍與中間網路。
VMess 物件的欄位位置
{
"tag": "proxy-vmess",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "vmess.example.com",
"port": 443,
"users": [
{
"id": "22222222-2222-4222-8222-222222222222",
"security": "auto"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "vmess.example.com"
},
"wsSettings": {
"path": "/connection"
}
}
}
VMess 與 VLESS 都可能使用 vnext,但 users 內部欄位不同。VMess 範例使用 security,而 VLESS 範例使用 encryption。WebSocket 傳輸還需要 wsSettings,其中路徑必須與伺服器端一致。若伺服器端要求特定請求標頭,也應放在對應的 WebSocket 設定中。TCP、WebSocket 與 gRPC 各自有專用的設定物件,不要保留上一種傳輸留下的無關欄位。
direct 與 block 是處理出口
freedom 出站讓核心直接連線至目標,通常標記為 direct;blackhole 用於終止符合規則的流量,通常標記為 block。這兩類出站不是遠端節點,卻是路由設定的重要組成部分。路由規則只負責選擇標籤,沒有同名出站就無法完成處理。建議明確寫出代理、直連與攔截三個標籤,讓規則意圖直接呈現在檔案中。
陣列中的第一個出站具有特殊意義:沒有路由規則命中時,核心通常會使用第一個出站作為預設出口。因此出站順序不能只按名稱排序。若希望未命中流量預設走代理,就將代理出站放在前面;若希望預設直連,就將 direct 放在前面。更穩妥的做法是同時寫清楚關鍵的兜底規則,並在修改順序後重新檢查實際路徑。
| 層級 | 代表欄位 | 核對來源 |
|---|---|---|
| 公共層 | tag、protocol |
本機命名與協定類型 |
| 協定層 | address、port、users |
伺服器端或訂閱資訊 |
| 傳輸層 | network、security |
伺服器端傳輸設定 |
| 傳輸細節 | tlsSettings、wsSettings |
伺服器名稱、路徑等部署資訊 |
routing 路由:匹配條件、規則順序與出口選擇
路由規則依序處理
routing 會依連線屬性選擇出站。rules 是有序陣列,核心從前往後檢查,遇到第一條符合條件的規則後,就使用該規則指定的出口,後續規則不再參與這條連線的選擇。因此具體規則應放在前面,寬泛規則放在後面。將「所有連接埠」或「大範圍位址」規則寫在最上方,常會遮蔽下方更精確的網域規則。
同一條規則中的多個條件通常必須同時成立。例如同時寫入 inboundTag、domain 與 port,表示來源入口、網域與連接埠都符合時才會命中,而不是符合任一項即可。需要表達「網域條件或位址條件」時,通常拆成兩條指向同一出站的規則,結構更清楚,也更容易從日誌判斷命中路徑。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"inboundTag": [
"local-socks"
],
"domain": [
"full:internal.example.com"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"protocol": [
"bittorrent"
],
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
第一條只處理從 local-socks 進入且目標為指定完整網域的請求。第二條讓私有位址範圍直連,避免本機裝置流量被送往遠端。第三條依可識別的協定處理。最後一條涵蓋剩餘 TCP 與 UDP 流量,作為明確的兜底。所有 outboundTag 都必須存在於 outbounds 中;若標籤改名,路由引用也要同步更新。
domainStrategy 決定何時解析
domainStrategy 會影響路由模組面對網域目標時是否進一步解析位址。AsIs 主要依原始網域進行匹配,不會為了位址規則主動解析;IPIfNonMatch 會先嘗試網域規則,未命中時再解析位址並測試位址規則;IPOnDemand 則會在規則判斷需要位址時更早觸發解析。策略越積極,位址規則越容易參與,但 DNS 行為也會更直接地影響路由結果。
如果設定主要依賴網域分類,且不需要依目標位址判斷,可以從 AsIs 開始。如果同時使用 geoip 或自訂網段,IPIfNonMatch 通常更容易理解:先檢查網域,未匹配後再解析。調整此欄位後若路徑出現變化,應同時檢查 DNS 伺服器選擇、解析結果與快取,不要只檢查路由陣列。
網域匹配形式
| 形式 | 含義 | 適用情況 |
|---|---|---|
full:example.com |
只匹配完整網域 | 單一固定主機 |
domain:example.com |
匹配該網域及其常見子網域範圍 | 依網站網域組織規則 |
regexp:^.+\.example\.com$ |
使用正規表示式匹配 | 結構複雜且前兩種形式無法表達時 |
geosite:category-ads-all |
引用核心可用的網域分類資料 | 用戶端與核心已準備對應資料時 |
正規表示式彈性高,但維護成本也高。句點等字元需要依正規表示式規則轉義,放入 JSON 字串後,反斜線還必須符合 JSON 轉義要求。能用 full: 或 domain: 表達時,優先選擇更直觀的形式。分類資料規則則依賴用戶端隨核心提供的資料檔;若同一條規則在不同裝置上的表現不同,應檢查資料檔來源與更新時間,不要假設分類內容完全一致。
位址、連接埠、來源與網路類型
ip 可填寫單一位址、CIDR 網段或核心支援的位址分類。port 可填寫單一連接埠、範圍或以逗號分隔的組合,例如 53、80-443。source 與 sourcePort 用於依來源資訊限制規則,network 可區分 TCP 與 UDP,inboundTag 用於依入口區分應用程式路徑。這些條件應依實際需求組合,不要為了欄位齊全而全部填入。
依連接埠判斷只能說明目標連接埠,不能可靠代表應用程式或協定。網頁服務可以使用非標準連接埠,其他服務也可能使用常見連接埠。需要穩定識別目標時,優先結合網域、位址與入站來源。依協定識別則取決於核心能否識別對應流量,無法識別時規則不會命中。路由設計應保留清楚的兜底,避免未識別連線落入意外出口。
複雜分流建議從三條規則開始:私有位址直連、明確需要處理的目標走指定出口,其餘流量使用預設出口。確認基礎路徑穩定後,再分批加入網域分類、連接埠與來源條件。一次匯入大量規則會讓衝突位置難以確認。需要理解常見分流術語,可搭配術語手冊查閱;遇到規則已命中但連線仍失敗,請繼續檢查出站與 DNS,不要反覆調整匹配順序。
dns 設定:解析伺服器、網域分組與路由聯動
核心 DNS 與系統 DNS 的界線
dns 定義核心內部發起網域解析時使用的伺服器與匹配方式。它不等同於作業系統的所有 DNS 設定。應用程式可能先在系統層完成解析,再將位址交給代理;也可能透過代理提交網域,由核心或遠端處理。判斷某條 DNS 規則是否參與請求,必須先確認網域在哪一層被解析,以及入站目標識別是否提供網域資訊。
路由中的 domainStrategy 可能觸發核心解析,出站連線的伺服器位址也需要解析,部分 DNS 查詢還可能作為一般流量再次經過路由。設定錯誤時容易形成循環依賴:核心為了連線至代理伺服器而需要解析其網域,解析請求又被路由到尚未建立的代理出站。解決方向是讓啟動鏈上必要的目標擁有明確且可達的解析路徑,並保持規則簡單。
{
"dns": {
"hosts": {
"router.example": "192.168.1.1"
},
"servers": [
{
"address": "223.5.5.5",
"domains": [
"domain:example.cn"
],
"expectIPs": [
"geoip:cn"
]
},
{
"address": "1.1.1.1",
"domains": [
"domain:example.com"
]
},
"localhost"
],
"queryStrategy": "UseIP"
}
}
hosts 提供靜態映射,適合固定的本機服務名稱或少量明確需要覆寫的網域。它不是大型網域清單的替代品。靜態映射變更後不會自動跟隨實際服務變化,因此只應設定容易維護的目標。範例將 router.example 指向私有位址,用於說明結構;實際設定應依本地網路資訊填寫。
servers 依序列出解析伺服器。物件形式可附加 domains,讓特定網域優先交給該伺服器;字串形式可作為通用伺服器或備援項目。localhost 表示使用本機解析能力。若用戶端已管理 DNS,核心設定還可能經過用戶端改寫,最終行為應以執行時設定與日誌為準。
domains 與 expectIPs
domains 決定哪些網域優先使用目前的伺服器,其寫法與路由網域規則相近。精確主機可使用 full:,整個網域範圍可使用 domain:,分類資料可使用對應的分類識別碼。伺服器物件沒有 domains 時,通常會作為通用候選。多台伺服器都符合時,執行細節還會受到核心實作與查詢策略影響,因此應減少範圍重疊。
expectIPs 是對解析結果的預期篩選。範例要求第一組伺服器回傳的位址符合指定位址分類;若結果不符合,核心可以繼續考慮其他候選。它適合表達「該網域群組應解析至某類位址」的限制,但無法修復上游本身不可達、伺服器回應逾時或分類資料缺失。排錯時先暫時移除這項限制,確認基本查詢是否成功,再恢復結果限制。
queryStrategy 與位址族
| 策略 | 主要行為 | 使用前檢查 |
|---|---|---|
UseIP |
允許查詢可用的位址類型 | 系統與出站是否都能處理回傳位址 |
UseIPv4 |
優先限定為 IPv4 查詢結果 | 目標是否提供 IPv4 位址 |
UseIPv6 |
優先限定為 IPv6 查詢結果 | 本地網路與出站是否具備 IPv6 連線能力 |
位址族選擇必須與實際網路能力一致。解析得到 IPv6 位址,不代表目前裝置、路由器、代理伺服器與出站鏈路都能到達該位址。若出現部分網域長時間等待、換網路後恢復的情況,可先檢查回傳位址類型與出站連線能力。反過來,強制使用 IPv4 也可能讓只提供 IPv6 位址的目標無法解析。策略應建立在網路實況上,不應作為通用加速開關。
DNS 請求如何經過路由
當 DNS 伺服器填寫位址時,查詢目標可以直接進入出站選擇;填寫網域時,還需要先解析 DNS 伺服器本身的網域。若希望某組查詢經過代理,應為 DNS 目標編寫可識別且不會形成循環的路由規則。最簡單的檢查方式是畫出兩條路徑:業務網域由誰解析,DNS 伺服器本身由誰解析。任一路徑回到尚未建立的自身連線,都需要重新設計。
網域規則未生效時,先檢查應用程式交給核心的是網域還是位址。若只有位址,可檢查 SOCKS 請求方式、目標識別與路由的 domainStrategy。DNS 回傳正確但連線目標錯誤時,再檢查快取、靜態映射與用戶端產生的附加規則。不要同時更換解析伺服器、修改位址族並重排路由,否則恢復後也無法確定真正原因。
需要進一步理解中國大陸與台灣本地網域分組、遠端解析與位址規則的組合,可閱讀部落格中的V2Ray DNS 設定詳解。文章著重方案設計,本章著重欄位與執行邊界。遇到用戶端介面選項與手寫欄位不一致時,應以目前用戶端支援的核心及實際產生的設定為準。
policy 策略:逾時、使用者等級與統計開關
policy 不負責選擇出站
policy 用於定義連線生命週期與統計開關,不負責依網域或位址分流。常見結構包括 levels 與 system。levels 以使用者等級為鍵,為使用相同等級的使用者設定交握、閒置、上下行保持時間與統計項目;system 控制入站與出站的系統層級統計。若目標是改變某個網域的出口,應修改 routing,而不是在策略中尋找規則欄位。
等級不是速度檔位,也不是優先順序。協定使用者物件可透過 level 引用同名策略群組,未明確設定時通常會使用預設等級。只有確實需要不同連線生命週期時,設定多個等級才有意義。一般用戶端設定通常保留一個等級即可,減少使用者物件與策略物件之間的引用複雜度。
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
}
handshake 控制建立連線階段允許等待的時間。數值過小會讓高延遲網路或較慢的交握過早失敗,數值過大則會讓真正不可達的連線等待更久。它不是網頁載入的總逾時,也不決定應用程式本身的請求期限。遇到交握失敗時,先檢查位址、連接埠、傳輸層與網路可達性,再判斷是否需要調整此值。
connIdle 表示連線在沒有資料活動時可以維持的時間。設定太短可能影響長連線、訊息推送或間歇傳輸;設定過長則會讓不再使用的連線更久占用資源。合理值取決於業務類型,不存在適用於所有網路的統一數字。行動網路頻繁切換時,舊連線即使仍保留在核心中,也可能已無法繼續使用,因此還要結合用戶端的重新連線行為判斷。
uplinkOnly 與 downlinkOnly 用於半關閉狀態下的連線保留時間。當一側資料方向結束後,另一側可能仍需要短暫傳輸。過早結束會截斷尾端資料,保留過久則會延遲資源釋放。一般使用時不建議先調整這兩個欄位;只有日誌與業務表現明確指向半關閉處理時,才進行單項測試。
統計需要同時啟用兩層
statsUserUplink 與 statsUserDownlink 控制使用者層級統計,system 下的欄位控制入站與出站統計。要讓統計資料真正產生,通常還需要頂層存在 stats 物件,並由用戶端或 API 讀取。只開啟策略開關不會自動產生可見圖表,也不會自動將結果寫入某個頁面。
{
"stats": {},
"policy": {
"system": {
"statsInboundUplink": true,
"statsInboundDownlink": true,
"statsOutboundUplink": true,
"statsOutboundDownlink": true
}
}
}
統計會增加一定的處理與記憶體負擔。若只是為了排錯而暫時觀察入站與出站流量,可以按需啟用,完成後恢復必要範圍。使用者層級統計還依賴協定使用者具有對應的等級與識別標記,適用於伺服器管理或明確的資料蒐集情境。一般本機用戶端更常關注出站是否有流量,而不是為每位使用者建立統計層。
| 欄位 | 單位或類型 | 調整風險 |
|---|---|---|
handshake |
秒 | 過短會導致連線建立階段提前終止 |
connIdle |
秒 | 過短會影響長連線,過長會延遲資源釋放 |
uplinkOnly |
秒 | 影響上行結束後的連線保留 |
downlinkOnly |
秒 | 影響下行結束後的連線保留 |
statsInboundUplink |
布林值 | 啟用後會產生對應統計資料與額外負擔 |
策略修改的測試方式
調整連線策略時,應固定節點、路由與 DNS,只修改一個策略值。也要明確測試對象:交握問題用新建連線觀察,閒置問題需要建立連線後等待,半關閉問題則需要能重現單向結束的業務情境。只重新整理一次網頁,無法驗證所有欄位。測試完成後記錄原值、修改值與現象,避免多輪調整後失去基準。
用戶端可能在啟動時產生預設 policy,也可能完全省略並使用核心預設值。省略欄位不代表數值為零。若目前連線穩定,沒有統計或生命週期方面的明確需求,維持預設行為通常比複製一組來源不明的參數更合適。需要比較 v2rayN、v2rayNG 與 v2flyNG 的平台定位,可前往橫向評測;策略欄位是否可用,仍以各自核心與用戶端實作為準。
完整組合、載入檢查與分層排錯
將各段組合成可追蹤的處理鏈
完整設定的重點不是欄位數量,而是每條連線都能沿著明確路徑移動:應用程式連入入站,入站產生目標資訊,DNS 在需要時提供解析結果,路由選擇出站,出站依協定與傳輸設定建立連線,policy 管理生命週期。任何一層發生錯誤,都可能在用戶端表現為「無法連線」。排錯時必須將籠統現象拆解成具體階段。
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
"localhost"
],
"queryStrategy": "UseIP"
},
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "server.example.com",
"port": 443,
"users": [
{
"id": "11111111-1111-4111-8111-111111111111",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "server.example.com",
"allowInsecure": false
}
}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300
}
}
}
}
此範例展示結構關係,伺服器資訊仍需替換為實際資料。私有位址先匹配 direct,其餘 TCP 與 UDP 流量交給 proxy。SOCKS 入站只繫結本機,DNS 使用系統解析能力,策略僅設定基本連線生命週期。設定中雖然定義了 block,但目前沒有路由規則引用它;保留此出口,方便日後新增明確的攔截規則。
第一層:檔案能否讀取
先檢查檔案編碼、JSON 語法、鍵名拼寫與資料類型。常見錯誤包括遺漏逗號、最後一項多出逗號、使用單引號、將連接埠寫成字串、陣列外少一層方括號,以及複製後出現全形標點。核心若在啟動階段直接退出,應優先查看錯誤日誌中的欄位路徑與行列位置。語法尚未通過前,不要討論路由是否命中。
圖形化用戶端使用者還要確認檔案是否真的由目前程序載入。v2rayN 可能依目前伺服器、路由與 DNS 設定重新產生核心設定;v2rayNG 與 v2flyNG 也會依行動端介面狀態產生執行參數。修改未被使用的匯出檔案,不會改變目前連線。可透過用戶端日誌、設定預覽或啟動參數確認實際載入路徑。
第二層:入站是否建立
核心啟動後,檢查本機監聽位址與連接埠是否存在。應用程式的代理類型必須與入站協定一致:SOCKS 應指向 SOCKS 連接埠,HTTP 應指向 HTTP 連接埠。若系統代理已開啟但瀏覽器仍直連,請檢查系統代理指向、瀏覽器獨立代理設定與目前用戶端模式。若應用程式立即提示代理伺服器拒絕連線,通常先檢查核心是否執行、連接埠是否一致與本機防火牆。
只有某個應用程式異常時,不要立即判斷節點失效。該應用程式可能不讀取系統代理,也可能自帶 DNS、HTTP/3 或獨立網路設定。先用明確支援 SOCKS 或 HTTP 代理的測試應用程式驗證入站,再回到目標應用程式檢查代理能力。行動端則檢查分應用程式範圍與系統網路介面是否已建立。
第三層:路由與 DNS 是否產生預期目標
入站收到連線後,查看目標是網域還是位址,再檢查路由第一條命中的規則。如果日誌顯示走了錯誤出站,重點核對規則順序、標籤拼寫與條件組合。若網域規則沒有命中但位址規則生效,檢查應用程式的解析位置、sniffing 與 domainStrategy。若解析逾時,暫時減少 DNS 伺服器與結果限制,確認基本查詢路徑。
路由問題與 DNS 問題經常互相影響。應分別提出兩個問題:目標網域解析成了什麼,解析完成後是哪條規則匹配。只有將這兩步分開,才能判斷是解析結果不符合預期,還是規則順序錯誤。直接反覆更換節點,無法解決本地規則衝突。
第四層:出站能否完成連線
出站階段依固定順序核對:伺服器位址解析、連接埠可達性、協定類型、使用者參數、傳輸類型、安全層、伺服器名稱、路徑或服務名稱。日誌中的逾時通常指向網路可達性或路徑問題,立即斷線則常見於連接埠、協定或交握參數不一致。系統時間明顯錯誤也會影響 TLS 連線。每次只修改一個欄位,並保留可復原的原始設定。
| 現象 | 優先檢查 | 下一步 |
|---|---|---|
| 核心啟動後立即退出 | JSON 語法、欄位類型、連接埠占用 | 查看錯誤日誌中的欄位路徑 |
| 應用程式無法連線至本機代理 | 入站位址、連接埠、協定類型 | 確認應用程式代理設定與核心程序 |
| 部分網域走錯出口 | 規則順序、目標類型、DNS 結果 | 記錄第一條命中的規則 |
| 所有遠端連線逾時 | 伺服器解析、連接埠、網路路徑 | 再核對傳輸與安全層 |
| TCP 正常但 UDP 異常 | 入站 UDP、路由網路類型、出站能力 | 檢查上游與應用程式行為 |
| 修改後重新啟動仍未變化 | 實際載入的檔案、用戶端自動產生設定 | 從執行設定反查來源設定 |
日誌層級與最小重現
日常使用可維持較簡潔的日誌層級。定位問題時,暫時提高日誌資訊量,重現一次明確操作,然後恢復原設定。日誌越多不代表越快得到結論;應圍繞時間點、入站標籤、目標、路由結果與出站錯誤閱讀。分享日誌前,請先處理伺服器位址、使用者識別碼、訂閱內容與本機路徑等敏感資訊。
最小重現設定只保留一個入站、一個代理出站、一個直連出站與最少規則。若最小設定能夠連線,再逐段加入 DNS 分組、額外入站、複雜路由與策略;在哪一步重新出現問題,範圍就落在該段新增內容。若最小設定也失敗,重點回到伺服器參數、網路路徑與核心相容性。這種方法比在完整設定中隨機刪除欄位更穩定。
仍無法判斷時,可在FAQ 故障排查中依現象繼續查找。需要重新安裝用戶端或確認平台對應關係,請前往下載中心選擇 v2rayN、v2rayNG 或 v2flyNG。桌面平台首選 v2rayN;Android 可依所需核心選擇 v2rayNG 或 v2flyNG。重新安裝前,先記錄目前的訂閱、路由與 DNS 設定,避免將設定問題與程式問題混在同一次操作中。