V2Ray 與 Xray 設定檔的核心任務,是將一條連線從「應用程式發出的本機請求」轉換為「由指定出口處理的網路請求」。設定並不是數個獨立欄位的簡單集合,而是一條有明確先後順序的資料路徑:應用程式先連線至入站監聽連接埠,核心讀取目標位址並執行流量探測,路由模組依據網域、IP、連接埠或入站標籤選擇出站,DNS 模組在需要時參與解析,最後由對應出站建立連線。理解這條路徑後,許多看似隨機的故障都能還原為某個環節未取得預期資訊。
v2rayN 是 Windows、macOS 與 Linux 桌面端的主要圖形客戶端,v2rayNG 與 v2flyNG 則分別面向 Android。圖形客戶端通常會根據介面選項產生執行設定,因此直接編輯暫存設定可能在下次啟動或切換伺服器後被覆寫。長期設定應優先透過客戶端提供的路由、DNS、參數設定或自訂設定入口完成;需要選擇安裝套件時可前往下載頁,若只需要完成首次連線,則應先走快速入門主線。
JSON 結構總覽與設定載入順序
頂層物件如何協同運作
完整設定以一個 JSON 物件作為根節點。常見頂層欄位包括 log、dns、inbounds、outbounds、routing、policy 與 stats。其中,入站和出站是連線路徑的兩端,路由負責將兩端連結起來;DNS 為網域匹配與目標解析提供結果;策略模組控制逾時、統計及不同使用者等級的行為;日誌欄位則決定執行時保留多少診斷資訊。設定可以缺少某些選用模組,但至少要有能接收請求的入站和能處理請求的出站,否則核心即使啟動,也無法形成完整的資料路徑。
陣列順序和標籤會同時影響設定行為。每個入站或出站都可以透過 tag 取得固定名稱,路由規則再使用 inboundTag 或 outboundTag 引用它。標籤只是設定內部識別,不是伺服器名稱,也不會改變協定本身。建議使用簡短、語意固定的英文標籤,例如 socks-in、proxy、direct 與 block。同一作用域內不要重複使用標籤,否則閱讀設定時難以判斷規則最終指向哪個物件,部分實作甚至可能直接拒絕載入。
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
"1.1.1.1",
"localhost"
]
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
JSON 語法與資料型別
JSON 對格式的要求比許多設定語言嚴格。物件使用大括號,陣列使用方括號,鍵名與字串必須放在英文雙引號中;布林值只能寫成小寫的 true 或 false,數字不能額外加上引號。物件最後一個欄位和陣列最後一個元素後面不能保留逗號。標準 JSON 也不接受註解,因此不要把說明文字直接寫進要載入的設定。需要維護備註時,可以記錄在外部文件,或使用客戶端專門提供的備註欄位;自行加入核心不認識的欄位,可能被忽略,也可能在嚴格解析模式下觸發錯誤。
欄位的資料型別不能只因外觀看起來接近就互相替換。例如連接埠通常是數字 10808,而不是字串 "10808";網域清單必須是陣列,即使只有一項,也應寫成 ["domain:example.com"]。規則中的 port 則常用字串表達範圍,如 "53" 或 "80,443,1000-2000"。這類差異來自欄位定義,而非統一語法。編輯前應先確認欄位屬於數字、字串、布林值、物件還是陣列,避免設定能通過 JSON 解析,卻在核心讀取欄位時失敗。
設定載入與連線處理順序
核心載入設定時,首先完成 JSON 解析與模組初始化,接著繫結入站監聽位址。連接埠已被其他程式佔用、監聽位址不屬於本機、欄位型別錯誤,都會讓啟動階段提前終止。啟動成功只代表設定結構和本機資源基本可用,並不代表遠端協定參數一定正確。真正的遠端連線通常要等應用程式請求到來後才建立,因此「核心已啟動」和「目標可以存取」是兩個不同的檢查階段。
請求進入後,核心先確定入站標籤、目標位址、目標連接埠和網路類型。啟用 sniffing 時,還可能從 HTTP 請求或 TLS 握手中識別網域。接著 routing 由上到下檢查規則,通常由第一條完整匹配的規則決定出口;若沒有規則命中,則使用預設出站,預設出站通常與出站陣列的首項或客戶端產生邏輯有關。DNS 是否介入,取決於目標是否需要解析以及 domainStrategy 的選擇。最後,出站模組依據協定、傳輸層、安全層和伺服器參數建立連線。排查時沿著相同順序檢查,比反覆切換選項更有效。
維護設定時應維持單一職責:入站只描述本機接入方式,出站只描述出口能力,路由只表達選擇條件,DNS 只處理解析路徑,policy 只控制連線生命週期和統計。把多個目的混在一條規則中,短期可能減少行數,長期卻會增加規則覆寫和回歸測試的難度。建議每次只修改一個模組,儲存前確認 JSON 語法,啟動後查看 warning 或 info 等級日誌,再用明確的網域、IP 和連接埠情境逐項測試。
inbounds 入站:監聽位址、連接埠與流量探測
入站負責接收什麼
inbounds 是入站物件陣列,每個物件描述一種本機接入方式。桌面客戶端最常見的是 SOCKS 入站和 HTTP 入站:支援 SOCKS 的應用程式連線至 SOCKS 連接埠,只支援 HTTP 代理的應用程式連線至 HTTP 連接埠;系統代理模式通常由客戶端將作業系統代理設定指向其中一個本機連接埠。透明接管、虛擬網卡或重新導向入站涉及額外的平台權限與網路堆疊設定,不應與一般本機代理連接埠混為一談。
listen 決定在哪個本機位址監聽。寫成 127.0.0.1 時,只接受本機連線,是個人桌面環境的常見選擇;寫成 0.0.0.0 時,會在所有可用的 IPv4 介面上監聽,區域網路內其他裝置可能存取該連接埠。v2rayN 中「允許來自區域網路的連線」這類選項,本質上會影響監聽範圍及相關防火牆條件。只有明確需要為同一區域網路的其他裝置提供入口時,才應擴大監聽範圍,並同步確認作業系統防火牆和網路環境。
port 必須是本機未被佔用的有效連接埠。常見的本機 SOCKS 監聽連接埠是 10808,但它不是協定強制值,可依本機環境調整。修改後,瀏覽器、開發工具、系統代理或其他呼叫端也必須同步更新;只修改核心連接埠而不修改應用程式設定,會表現為應用程式無法連線本機代理。多個入站不能繫結同一位址上的同一連接埠,即使協定不同也會發生衝突。
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"],
"routeOnly": true
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
SOCKS、HTTP 與 UDP 行為
SOCKS 入站的 settings.udp 決定是否接受 UDP 請求。啟用後並不表示所有應用程式都會自動使用 UDP,也不保證對應出站和遠端協定能處理所有 UDP 情境。應用程式必須透過相容方式將 UDP 請求交給 SOCKS 入站,路由規則也不能將其誤送到不適合的出口。排查「網頁正常但部分即時應用程式異常」時,需要分別確認應用程式接入方式、入站 UDP 開關、路由網路條件和出站協定能力。
HTTP 入站主要接收 HTTP 代理請求,以及透過 CONNECT 方法建立的 HTTPS 通道。它不是一般網頁伺服器,也不會自動處理任意傳送到該連接埠的協定。部分應用程式只讀取系統 HTTP 代理設定,部分應用程式支援獨立 SOCKS 設定,另有一些應用程式完全忽略系統代理。設定入站時應先確認呼叫端實際支援哪種接入方式,而不是同時增加許多監聽連接埠。連接埠越多,排查連接埠佔用、規則來源和防火牆行為時就越複雜。
當監聽位址擴大到區域網路時,可以考慮在入站設定中加入驗證,但驗證能力取決於具體入站協定和客戶端產生方式。更穩妥的做法是先限制網路邊界,只允許受控裝置存取,並避免將本機代理連接埠暴露在不受信任的網路中。若僅供本機使用,維持回環位址通常已足夠。Windows、macOS 與 Linux 對防火牆提示和網路權限的呈現不同,但判斷原則一致:先確認核心確實在預期位址監聽,再確認呼叫裝置能夠抵達該位址和連接埠。
sniffing 如何輔助路由
流量探測 sniffing 用於從連線內容中識別目標網域,常見識別來源包括 HTTP Host、TLS Server Name 和 QUIC 中可見的目標資訊。它的價值在於:應用程式可能先將網域解析為 IP,再把純 IP 目標交給代理;如果路由只看見 IP,geosite 或網域後綴規則就無法命中。啟用探測後,核心可以使用識別出的網域參與路由,讓網域規則取得更穩定的輸入。
destOverride 指定允許從哪些協定特徵覆寫或補充目標資訊,常用值為 http、tls 和 quic。routeOnly 為 true 時,探測結果主要用於路由判斷,不直接改寫最終連線目標,有助於減少目標替換帶來的副作用。是否啟用此項應配合實際規則設計:如果只使用 IP 規則,探測的效益有限;如果大量使用 geosite、完整網域和後綴規則,探測通常更有價值。
探測不是通用解密,也不是所有連線都能識別。加密應用程式協定、非標準握手、直接存取 IP 或提前建立的多工連線,都可能無法提供可用網域。規則設計不能假設每條連線必然取得探測網域,應保留合理的 IP 規則與預設出口。出現網域規則偶爾未命中時,可以先將日誌等級暫時調整為 info,比較應用程式原始目標、探測結果和最終出站標籤;完成診斷後再恢復 warning,避免長期累積過多日誌。
多個入站還可以透過不同標籤配合路由。例如將瀏覽器指向 browser-in,將開發工具指向 dev-in,再用 inboundTag 為兩類請求選擇不同出口。這樣比依程序名稱匹配更容易跨平台重複使用,但前提是各應用程式能設定獨立代理連接埠。若使用 v2rayN 的系統代理模式,通常只需保留客戶端產生的標準入站;只有存在明確隔離需求時,才增加自訂入口。
outbounds 出站:協定參數、標籤與傳輸層
出站陣列與預設出口
outbounds 描述連線離開核心時採用的處理方式。代理協定出站負責連線遠端伺服器,freedom 出站用於直接存取目標,blackhole 出站則用於終止匹配的連線。實務上通常至少保留 proxy、direct 和 block 三個語意清晰的標籤,讓路由規則能分別表達代理、直連和阻斷。標籤名稱可以自行設定,但規則中的 outboundTag 必須與之完全一致,包括大小寫。
沒有命中路由規則時使用哪個出口,需要結合核心行為和客戶端產生方式判斷。許多設定會將主要代理出站放在陣列首位,使其成為未匹配流量的預設處理路徑;另一些客戶端會額外產生兜底規則。閱讀實際執行設定時,不能只看介面中顯示的伺服器,還要查看出站順序,以及路由末尾是否存在 catch-all 規則。若希望行為明確,可以在規則末尾加入涵蓋完整網路範圍的兜底條件,但應避免過寬的規則提前攔截所有流量。
{
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "server.example.com",
"port": 443,
"users": [
{
"id": "11111111-1111-4111-8111-111111111111",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "www.example.com",
"fingerprint": "chrome",
"publicKey": "dGVzdC1wdWJsaWMta2V5LWZvci1kb2N1bWVudA",
"shortId": "0123456789abcdef",
"spiderX": "/"
}
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIP"
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {
"response": {
"type": "none"
}
}
}
]
}
以上代理參數使用文件範例位址與範例憑證,只用於展示欄位層級,不能直接建立實際連線。真實設定中的位址、連接埠、使用者識別、傳輸方式、安全層參數必須成組保持一致。訂閱匯入通常會自動產生這些欄位;手動調整時,不應只根據協定名稱替換單一值,因為同一協定還可能組合 TCP、WebSocket、gRPC、TLS、REALITY 和不同流控方式。
協定設定與 streamSettings 的分工
protocol 決定應用層代理協定,settings 儲存該協定所需的伺服器與使用者資訊;streamSettings 則描述底層傳輸網路與安全層。以 VLESS 為例,伺服器位址、連接埠和使用者識別位於 settings.vnext,TCP、WebSocket 或 gRPC 位於 streamSettings.network,TLS 或 REALITY 位於 streamSettings.security。這些層級彼此關聯,卻不能互換位置。
VMess、VLESS、Trojan 與 Shadowsocks 的使用者欄位結構不同。VMess 常見使用者資訊包含 id 和安全設定;VLESS 使用 id、encryption,並可能搭配 flow;Trojan 使用密碼;Shadowsocks 使用加密方法與密碼。客戶端訂閱能減少手動輸入錯誤,但匯入後仍應核對協定、傳輸類型、TLS 伺服器名稱和連接埠是否完整。若訂閱更新失敗或分享連結格式異常,可參考訂閱更新失敗自我檢查清單逐項確認。
mux 多路複用可讓多個邏輯連線共用較少的底層連線。它不是任何環境下都應啟用的加速開關,是否有收益取決於協定、傳輸、伺服器設定和業務類型。某些長連線或對時序敏感的請求可能不適合額外複用。出現連線建立正常但持續傳輸不穩定時,可以將 Mux 作為獨立變數關閉測試,而不是同時修改協定、安全層和路由。
direct、block 與出口限制
freedom 出站會直接連線目標,常用於私有位址、本地區域網域或明確希望由本地網路處理的請求。它仍會受到本機 DNS、網路路由和防火牆影響,因此「direct」只表示不經過代理協定,並不保證目標一定可達。settings.domainStrategy 可控制 freedom 遇到網域時如何處理解析,具體選擇應與頂層 DNS 和 routing 的網域策略協調,避免同一網域在不同階段得到不一致結果。
blackhole 不會向目標建立正常連線,適合阻斷已知不需要的網域、IP 或連接埠。阻斷規則應盡量具體,並放在需要優先執行的位置。過寬的阻斷條件可能讓更新、登入或區域網路服務表現為逾時。除錯時可以暫時將可疑規則的出口改為 direct 或獨立標籤,確認是否由規則造成,再恢復預期行為。
部分設定會使用 sendThrough 指定出站連線從某個本機位址發出,或使用 sockopt 調整底層通訊端選項。這類欄位適合多網卡、特定路由表或進階網路環境,不應作為一般連線故障的第一處理手段。若位址並未配置給本機介面,出站會直接失敗。桌面端首先應維持客戶端預設值,只有在能明確描述目標網卡、位址族和路由需求時,才增加繫結設定。
| 出站角色 | 常用 protocol | 主要用途 | 常見檢查點 |
|---|---|---|---|
| 代理出口 | vless、vmess、trojan、shadowsocks | 依遠端協定建立連線 | 位址、連接埠、使用者參數、傳輸與安全層是否一致 |
| 直接連線 | freedom | 使用本地網路存取目標 | 本機 DNS、預設路由、防火牆與位址族 |
| 阻斷連線 | blackhole | 終止命中規則的請求 | 規則範圍與順序是否過寬 |
維護出站時應優先保持標籤穩定。路由規則引用的是標籤而非陣列位置,穩定的標籤可以讓伺服器參數更新與路由策略解耦。切換訂閱節點後,客戶端可能重建代理出站,但 direct 和 block 的語意通常不需要變更。若自訂設定引用了客戶端可能改名的內部標籤,應在每次更新後檢查實際產生結果,避免規則指向不存在的出口。
routing 路由規則:匹配順序、網域與 IP 分流
規則依順序匹配
routing.rules 是路由規則陣列。常用規則類型為 field,可以組合網域、IP、連接埠、網路類型、入站標籤、協定和使用者等條件。規則由上到下檢查,較具體、優先級較高的條件應放在前面,範圍較寬的規則放在後面。若一條規則已經匹配,請求通常不會繼續尋找更後方的替代規則,因此順序本身就是策略的一部分。
同一條 field 規則中的不同條件通常形成「同時滿足」的關係。例如同時寫入 domain 與 port,表示網域條件和連接埠條件都滿足時才使用該出口;同一陣列內的多個網域值則通常形成「任一命中」的關係。把多個無關條件塞進同一條規則,容易誤以為它們彼此獨立。更清楚的做法是依業務目的拆分規則,並為每條規則保留單一、可解釋的命中原因。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"domainMatcher": "hybrid",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn",
"domain:example.cn",
"full:service.example.cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
此範例先處理私有 IP,再處理指定網域和區域網域,接著處理區域 IP,然後阻斷特定分類,最後將剩餘 TCP 與 UDP 請求交給 proxy。實際使用時,阻斷規則是否應放在區域直連之前,取決於分類資料與目標策略;如果一個網域同時屬於兩個集合,位置較前的規則會取得控制權。修改規則順序前,應列出可能重疊的集合,而不是只根據規則名稱判斷。
domainStrategy 決定何時解析
domainStrategy 控制路由模組在網域規則無法直接給出結果時,是否將網域解析為 IP 再嘗試 IP 規則。AsIs 通常只使用目前已有的目標形式,網域目標不會為了匹配 IP 規則而主動解析;IPIfNonMatch 會先嘗試網域規則,沒有匹配時解析 IP,再檢查 IP 規則;IPOnDemand 會在路由過程中更積極地準備 IP 結果。具體行為還會受到核心實作和設定組合影響,但選擇原則很明確:只有需要讓網域目標參與 geoip 或 CIDR 規則時,才需要在路由階段引入解析。
解析並非沒有成本。它會增加 DNS 查詢,也可能讓路由結果受到解析伺服器、快取和位址族影響。若所有重要目標都能由 geosite、完整網域或後綴規則覆蓋,AsIs 更容易理解;若依賴 geoip:cn 或自訂 CIDR 為網域目標分流,則 IPIfNonMatch 通常更合適。不要只因某個範本使用特定值就照搬,應根據規則中是否存在 IP 條件,以及應用程式是否提交網域來選擇。
啟用 sniffing 後,路由可能取得從流量中識別出的網域;未啟用時,若應用程式提交的是 IP,網域規則便沒有可匹配的物件。反過來,應用程式提交網域時,IP 規則是否參與又取決於 domainStrategy。由此可見,入站探測、路由網域策略和 DNS 並不是三個孤立的開關。排查規則時,需要記錄請求最初是網域還是 IP、探測是否取得網域、路由是否觸發解析,以及最終取得哪些 IP。
網域、IP、連接埠與標籤條件
網域規則常見寫法包括 full:、domain:、regexp: 和 geosite:。full:example.com 只匹配完整網域;domain:example.com 可涵蓋該網域及其子網域;正規表示式提供更靈活的模式,但複雜表達式會降低可讀性,也更容易產生意外匹配;geosite 使用分類資料集合,適合維護範圍較大的規則。單一明確網站優先使用 full 或 domain,只有集合規模較大時再使用分類資料。
IP 規則可寫 CIDR,例如 192.168.0.0/16,也可以引用 geoip:private 與其他資料集合。私有位址規則通常應較早直連,否則區域網路管理頁、檔案服務和本機開發環境可能被送往代理出口。需要注意的是,網域解析到私有位址時是否命中該規則,仍取決於路由是否執行了解析。僅加入 private 規則不能自動解決所有區域網路網域問題。
port 支援單一連接埠、逗號清單與範圍,network 常用 tcp、udp 或兩者組合。連接埠只描述連線目標連接埠,不等同於應用程式類別。許多服務可能共用 443,單靠連接埠無法判斷具體網域;53 也可能承載不同形式的 DNS 請求。連接埠規則適合表達明確的網路策略,不適合取代網域識別。
inboundTag 可以根據請求來自哪個入站進行分流,對多個本機連接埠的隔離很實用。protocol 條件則依賴核心的識別結果,例如在探測後識別特定協定。使用這些進階條件時,應保留末尾兜底規則,避免未識別流量沒有明確出口。完成路由修改後,至少測試私有 IP、明確直連網域、明確代理網域、一般未分類網域和 UDP 請求五種情境,並查看實際出站標籤。
v2rayN 的路由設定介面通常會將預設、規則集和目前代理模式組合成最終設定。在介面中選擇「全域」或其他模式時,可能改變預設出口或產生額外規則,因此手動片段與客戶端模式應一併核對。需要理解不同協定與路由情境的取捨時,可繼續閱讀VMess、VLESS、Trojan、Shadowsocks 協定比較。
DNS 設定:解析伺服器、匹配網域與位址族
內建 DNS 與系統 DNS 的界線
頂層 dns 模組為核心需要執行的網域解析提供伺服器、靜態映射和查詢策略。它不會自動接管裝置上的所有 DNS 請求。只有進入核心處理路徑、被路由模組要求解析,或由特定 DNS 入站交給核心的查詢,才會使用這裡的設定。應用程式自行連線外部解析服務、瀏覽器啟用獨立安全 DNS,或請求完全繞過代理時,頂層 dns 設定可能不會參與。
這項區分對排查非常重要。看到某個網域的解析結果與設定預期不同時,先確認查詢由誰發起:是作業系統解析器、應用程式自己的解析器,還是 Xray 內建 DNS。不要同時修改系統 DNS、瀏覽器設定、核心伺服器清單和路由規則,否則即使結果發生變化,也無法判斷是哪一層生效。建議先關閉應用程式的獨立解析功能進行對照,再透過日誌觀察核心是否發出查詢。
{
"dns": {
"hosts": {
"domain:internal.example": "192.168.10.20",
"full:router.example": "192.168.1.1"
},
"servers": [
{
"address": "1.1.1.1",
"port": 53,
"domains": [
"geosite:geolocation-!cn"
],
"skipFallback": true
},
{
"address": "223.5.5.5",
"port": 53,
"domains": [
"geosite:cn"
],
"expectIPs": [
"geoip:cn"
]
},
"localhost"
],
"queryStrategy": "UseIP",
"disableCache": false,
"disableFallback": false,
"disableFallbackIfMatch": true
}
}
範例透過 domains 限定解析伺服器的適用範圍,並保留 localhost 作為後續選擇。實際是否需要公共解析位址、系統解析器或其他傳輸形式,應依所在網路與目標環境決定。伺服器順序、匹配網域和 fallback 開關會共同影響最終選擇,不能把 servers 簡單理解為依序輪詢的清單。
servers、hosts 與查詢策略
servers 中可以使用字串形式,也可以使用物件形式。物件形式可附加連接埠、匹配網域、預期 IP 範圍和 fallback 行為。domains 用於指定哪些網域優先由該伺服器處理,寫法與路由網域規則類似。expectIPs 用於判斷返回位址是否符合預期範圍;它更接近結果篩選條件,不是將任意位址強制改成目標區域。設定不當時,正常結果可能遭拒絕並觸發後續查詢。
hosts 提供靜態網域映射,適合固定的區域網路服務或明確的測試目標。它不是大型 hosts 檔案的替代方案,條目過多會增加維護成本。完整網域應使用 full: 限定,需涵蓋子網域時再使用 domain:。映射到私有位址後,還應確認 routing 中的 private 規則能讓連線走 direct,否則解析正確但出口選擇仍可能不符合預期。
queryStrategy 控制需要哪一類位址結果。常見策略包括同時允許 IPv4 與 IPv6、只使用 IPv4 或只使用 IPv6,具體名稱以目前核心支援的欄位為準。選擇只使用某一位址族前,應先確認本地網路和遠端服務確實支援該路徑。若本機存在 IPv6 位址但網路出口不穩定,網域可能優先返回 IPv6,之後連線失敗;反過來,強制使用 IPv4 會放棄僅提供 IPv6 的目標。穩妥做法是分別測試解析結果和實際路由,而不是只看裝置是否顯示某種位址。
fallback、快取與路由閉環
fallback 機制用於在首選解析結果不符合條件或沒有結果時嘗試其他伺服器。skipFallback 表示特定伺服器不參與一般回退,disableFallback 可整體關閉回退,disableFallbackIfMatch 則用於網域已命中特定伺服器時限制繼續回退。多個開關疊加後容易出現「設定了伺服器卻從未被呼叫」的現象,因此應從最小設定開始:先確認單一伺服器能正常運作,再加入網域範圍和回退限制。
快取可以減少重複查詢,但會讓修改設定後的結果在短時間內不會立即變化。disableCache 適合短期診斷,不建議因為一次舊結果就長期關閉快取。排查時還要考慮作業系統和應用程式本身的快取,它們與核心快取彼此獨立。重新啟動核心只能清除核心持有的狀態,不一定會清除瀏覽器或系統解析快取。
DNS 與路由會形成閉環:路由可能為了匹配 IP 規則而發起 DNS 查詢,而 DNS 伺服器本身的連線也要經過路由。若解析伺服器位址是網域,又需要先解析該網域才能連線,就可能出現依賴鏈過長甚至循環。基礎解析伺服器優先使用明確位址,或確保其網域能透過系統解析器穩定取得結果。若希望 DNS 查詢走特定出站,應建立清楚的標籤與規則,並避免該規則再次觸發相同的解析路徑。
典型問題是「網域規則看似正確,最終卻走了錯誤出口」。檢查順序應為:應用程式提交的是網域還是 IP;sniffing 是否識別網域;網域規則是否先命中;domainStrategy 是否執行解析;DNS 使用了哪個伺服器;返回的是 IPv4、IPv6 還是兩者;IP 規則是否涵蓋該結果;最終出站標籤是什麼。逐項記錄這條鏈路後,問題通常能定位到明確環節。
| 欄位 | 作用 | 適用情境 | 常見誤區 |
|---|---|---|---|
| hosts | 提供靜態網域映射 | 區域網路服務與固定測試目標 | 誤以為會改寫所有應用程式的系統解析 |
| domains | 限定解析伺服器的匹配網域 | 依網域集合選擇解析路徑 | 忽略伺服器順序與 fallback 條件 |
| expectIPs | 篩選符合範圍的解析結果 | 需要判斷返回位址的範圍 | 將它當成固定位址映射 |
| queryStrategy | 控制查詢使用的位址族 | 處理 IPv4 與 IPv6 路徑差異 | 未測試網路能力就強制使用單一位址族 |
v2rayNG 與 v2flyNG 執行於 Android 網路環境中,系統的私人 DNS、應用程式內解析和客戶端核心 DNS 也可能同時存在。判斷方式與桌面端相同:先釐清請求路徑,再確認哪一層負責解析。不要把系統設定中的 DNS 選項與設定檔頂層 dns 欄位視為同一個開關。
policy 策略:連線逾時、使用者等級與統計
level 策略如何關聯使用者
policy 用於設定連線生命週期、使用者等級和系統統計行為。它不負責選擇伺服器,也不會改變路由出口。levels 物件以等級數字作為鍵,每個等級可以設定握手逾時、閒置逾時、上下行僅剩單向活動時的連線保留時間,以及使用者流量統計開關。協定使用者項目中的 level 與這裡的等級鍵相連;若使用者未明確指定,通常會使用預設等級。
等級不是服務品質評分,也不會自動提供頻寬優先級。它只是將一組策略參數套用到對應使用者。桌面客戶端作為本機單一使用者工具時,常見設定只需要等級 0。伺服器端多使用者設定可能依使用者分配不同等級,但本頁重點是客戶端執行設定:不要為了「效能最佳化」隨意增加許多等級,應先確認實際使用者物件是否引用它們。
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false,
"bufferSize": 4
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
},
"stats": {}
}
數值單位和允許範圍應以目前核心的欄位定義為準。範例展示常見結構,不表示所有網路都適合相同的逾時設定。過短的握手時間會讓高延遲網路在連線尚未完成前就被終止;過長則會讓失敗連線佔用資源更久。閒置逾時也不能只理解為「越長越穩定」,長期維持大量無活動連線會增加資源消耗。
握手、閒置與單向連線逾時
handshake 控制連線建立階段允許等待的時間。遠端無法連線、網域解析緩慢、安全層參數不一致,都可能耗用這段時間。若日誌持續出現握手逾時,應先檢查位址、連接埠、傳輸和網路可達性,而不是直接把數值調得很大。適度增加僅適用於已確認網路路徑較慢,且連線最終能夠成功的情況。
connIdle 控制連線在沒有上下行活動時可以保留多久。網頁短連線通常不需要很長的閒置時間,但訊息同步、遠端終端機或長輪詢可能在一段時間內沒有明顯流量。若特定應用程式總是在固定閒置時間後中斷,可以比較應用程式心跳間隔與 connIdle;同時也應檢查遠端伺服器、傳輸層和中間網路設備,因為任何一層都可能主動關閉連線。
uplinkOnly 與 downlinkOnly 處理只剩單向活動的情況。一個方向結束後,核心會等待另一個方向完成,而不是立即關閉整條連線。數值過短可能截斷尚未傳送完的資料,過長則會延遲釋放資源。一般客戶端通常沿用核心或客戶端產生的合理預設值,只有日誌與擷取到的連線狀態明確指向單向關閉問題時,才需要調整。
bufferSize 與連線緩衝有關。更大的緩衝不一定帶來更高速度,也會增加每條連線的記憶體使用量。低效能裝置、大量並行連線和大檔案傳輸對緩衝的需求不同。最佳化時應一次只變更一個值,並觀察記憶體、連線穩定性與實際吞吐量的變化;不要將面向伺服器高並行環境的參數套用到一般桌面客戶端。
統計開關與執行負擔
statsUserUplink 和 statsUserDownlink 控制使用者層級的上下行統計,system 下的欄位控制入站和出站方向統計。頂層 stats 用於啟用統計模組,但只有空物件並不會自動讓所有維度產生資料,還需要對應的 policy 開關以及讀取統計的介面。v2rayN 介面是否顯示某些統計,也取決於客戶端如何啟動核心和讀取資料。
若不需要統計,保持相關開關關閉可以減少不必要的狀態維護。若需要確認某個入站或出站是否產生流量,可以短期啟用對應維度,但不能把流量變化直接等同於連線品質。統計只能說明資料經過某個方向,不能證明網域規則、DNS 結果或遠端應用程式回應完全正確。診斷仍需結合日誌與明確的測試請求。
策略模組常見的誤區,是把連線故障歸因於逾時值。實際上,協定參數錯誤、DNS 回傳無法連線的位址、路由選錯出口、連接埠遭佔用都更常見。正確順序是先確認結構載入、入站監聽、規則命中和出站握手,再判斷連線是否因生命週期策略而提前關閉。只有日誌顯示連線已建立,並在某個可重複的時間點結束時,policy 才是重點檢查對象。
Windows、macOS、Android 與 Linux 的前景和背景網路行為不同,尤其是行動裝置可能在應用程式進入背景後限制網路活動。這類系統層級行為不能只靠增加 connIdle 解決。若 v2rayNG 或 v2flyNG 在背景停止運作,應先檢查系統對應用程式網路與電量使用的限制;若 v2rayN 在桌面端啟動後立即退出,則應先查看連接埠、設定解析和核心啟動日誌。
policy 適合在設定已經穩定後做細部調整,而不是首次連線的必填模組。簡單的客戶端設定可以完全依賴預設策略。只有對長連線、統計或資源使用有明確需求時,才需要加入明確的 policy。欄位越少,升級核心與遷移客戶端時需要維護的相容性節點也越少。
設定驗證、日誌閱讀與系統化排錯
先區分解析、啟動與連線階段
設定故障應先分成三個階段。第一階段是 JSON 解析:括號不成對、缺少雙引號、尾逗號或欄位型別錯誤,都會讓設定無法讀取。第二階段是核心啟動:連接埠衝突、監聽位址無效、模組欄位不受支援,會讓程序無法正常進入執行狀態。第三階段是請求處理:伺服器參數、DNS、路由、安全層或網路環境問題,通常要等應用程式發出請求後才會出現。分清階段可以避免在 JSON 語法錯誤時反覆更換伺服器,也能避免在遠端握手失敗時誤查本機連接埠。
在圖形客戶端中看到「啟動」狀態,只能表示程序可能已經執行。應繼續確認本機連接埠是否正在監聽、系統代理是否指向正確連接埠、應用程式是否實際發送請求,以及請求最終選擇了哪個出站。v2rayN 的參數設定中可檢查 Core 類型、本機 SOCKS 監聽連接埠、區域網路連線開關、sniffing、Mux、日誌等級和系統代理模式。v2rayNG 與 v2flyNG 則應確認目前設定、連線模式和系統網路權限。
直接編輯 JSON 時,可以先使用本機 JSON 解析工具檢查語法,但不要將包含真實伺服器參數的完整設定提交至不受控的線上工具。更穩妥的方法是使用本機編輯器的 JSON 語法支援,或讓核心以測試設定方式讀取檔案。不同核心和安裝方式的命令參數可能不同,因此應以客戶端實際呼叫方式為準,不要直接套用其他程式的參數。
{
"log": {
"access": "",
"error": "",
"loglevel": "warning",
"dnsLog": false
}
}
warning 適合日常執行,能保留主要異常而不會過度增加輸出。需要追蹤規則和 DNS 時,可以短期切換至 info;完成診斷後應恢復較低的輸出量。日誌中可能包含目標網域、位址和連線時間等執行資訊,分享日誌前應刪除與問題無關的敏感內容。不要只截取最後一行錯誤,前面的解析、規則和握手資訊往往更能說明原因。
依資料路徑逐項定位
第一步檢查入站。確認客戶端顯示的 SOCKS 或 HTTP 連接埠與應用程式設定一致,連接埠未被其他程式佔用,監聽位址符合本機或區域網路使用方式。可以先用一個明確支援代理設定的應用程式測試,避免系統代理、瀏覽器獨立設定和應用程式忽略代理等因素同時出現。若應用程式連本機連接埠都無法建立連線,暫時不需要檢查遠端協定。
第二步檢查路由輸入。記錄應用程式提交的是網域還是 IP、sniffing 是否啟用、目標協定能否被識別。然後從 rules 第一條開始檢查條件,不要只查看預期命中的那一條。重點尋找較前方的寬範圍規則,例如涵蓋所有連接埠、所有網路或大型網域集合的規則。確認命中後,再核對 outboundTag 是否存在且拼寫一致。
第三步檢查 DNS。若網域規則已直接命中,DNS 可能只在出站連線目標時使用;若依賴 geoip 規則,則 routing 可能先解析目標。查看使用了哪個解析伺服器、返回哪類位址,以及 fallback 是否改變結果。可以分別使用完整網域和解析後的單一 IP 進行測試:網域失敗而 IP 成功時,重點查看 DNS 與網域規則;兩者都失敗時,再檢查出口和網路可達性。
第四步檢查出站。代理協定的位址、連接埠、使用者參數、傳輸類型、安全層和伺服器名稱必須成組一致。若匯入訂閱後欄位缺失,先更新訂閱並確認客戶端支援該分享格式。REALITY 與 XTLS Vision 等組合依賴 Xray 核心及相符的遠端參數,相關原理可參考REALITY 與 XTLS Vision 握手和流控說明。不要透過猜測逐一替換 flow、fingerprint 或 serverName,這會讓原始問題失去可重現性。
第五步檢查系統路徑。系統代理只會影響遵循該設定的應用程式,不能代表裝置的所有連線都經過本機入站。若某個應用程式正常、另一個應用程式直連,先確認後者是否支援系統代理。Windows、macOS 和 Linux 的代理設定入口不同,Android 客戶端則通常透過系統提供的網路連線能力接管流量。平台安裝與客戶端選擇可參考客戶端比較。
| 現象 | 優先檢查 | 下一步 |
|---|---|---|
| 核心無法啟動 | JSON 語法、欄位支援、連接埠佔用 | 還原最小設定,再逐段加入模組 |
| 應用程式無法連線本機代理 | 監聽位址、連接埠、應用程式代理類型 | 確認 SOCKS 與 HTTP 設定沒有混用 |
| 部分網域出口錯誤 | 規則順序、sniffing、domainStrategy | 查看網域與 IP 兩種輸入的命中差異 |
| 網域失敗但 IP 可以連線 | DNS 伺服器、hosts、位址族 | 檢查 fallback 與應用程式獨立解析 |
| 連線建立後在固定時間中斷 | connIdle、單向逾時、系統背景限制 | 對照日誌中的建立與關閉時間 |
最小設定與二分復原法
當設定經過多次修改後無法判斷是哪一段出錯,最有效的方法是還原最小設定。保留一個本機 SOCKS 入站、一個已知參數完整的代理出站、direct 出站和一條簡單兜底規則,暫時移除自訂 DNS、複雜路由、統計和策略。如果最小設定能夠運作,再依模組逐次復原,每次只加入一組相關欄位並完成固定測試。
規則很多時可以使用二分法:先停用一半自訂規則進行測試,如果問題消失,故障就在被停用的部分;如果仍然存在,則位於保留部分或其他模組。繼續縮小範圍,通常比逐條隨機移動更快。DNS 伺服器清單和 hosts 映射也可以使用相同方法。每輪測試都應維持伺服器、應用程式、目標網域和網路環境不變,否則測試結果無法比較。
建議為穩定設定保留一份結構化紀錄,包括客戶端類型、Core 類型、入站連接埠、出站標籤、路由規則目的、DNS 選擇理由和調整過的 policy 欄位。記錄理由比只保存設定更重要,因為資料集合、網路環境和客戶端產生邏輯改變後,舊規則未必仍然適用。定期刪除已無法說明用途的例外規則,避免設定逐漸變成只敢增加、不敢修改的狀態。
圖形客戶端更新訂閱或切換核心後,應重新檢查自訂欄位是否仍被寫入最終執行設定。v2rayN 的 Avalonia 桌面版與 Windows WPF 版在介面和平台支援上有所差異,但核心排查路徑一致,具體選擇可參閱v2rayN 桌面版與 WPF 版差異。macOS 首次啟動或網路權限異常時,可查看macOS 安裝與網路權限處理步驟。
如果錯誤訊息仍無法分類,可前往疑難排解,依基礎認知、安裝設定、使用技巧和故障排除分類繼續定位。提問或記錄問題時,應包含可重現步驟、客戶端名稱、作業系統、核心類型、相關設定片段和經過處理的日誌,而不是只描述「無法使用」。資訊越接近實際資料路徑,就越容易判斷故障屬於入站、路由、DNS、出站還是系統網路層。
設定檔的目標不是堆疊最多欄位,而是讓每條連線的處理過程可預測。先使用客戶端產生的預設結構建立可運作的基線,再依明確需求增加路由、DNS 和策略;每項修改都保留測試情境與復原路徑。這樣既能使用 v2rayN、v2rayNG 或 v2flyNG 的圖形管理能力,也能在出現問題時直接閱讀執行設定並定位到具體模組。