V2Ray config.json 設定檔結構解析:inbounds、outbounds 與 routing

依序解析 config.json 的 log、inbounds、outbounds、routing 與 dns,說明各欄位用途及常見設定方式。

本文重點

適合已匯入訂閱、想看懂核心執行設定的使用者。先釐清應用程式入口、連線出口與路由選擇,再透過一份只含本機監聽、直連與封鎖的完整設定,確認各欄位之間的關係。讀完後即可排查連接埠衝突、標籤拼錯、規則順序失效,以及 DNS 設定變更後未生效等問題。

先釐清:config.json 是核心設定檔,不是訂閱清單

v2rayN 是桌面用戶端,V2Ray 與 Xray 則是處理連線的核心。用戶端會儲存訂閱、節點與介面設定,再依選用的核心產生執行設定。因此,訂閱中的 VMess 或 VLESS 分享連結,不等於完整的 config.json:它通常只包含遠端連線參數,沒有本機入口、記錄、DNS 與分流規則。

本文採用 V2Ray 傳統 JSON 設定格式,說明 V2Ray 與 Xray 常見欄位之間的關係。V2Ray v5 也提供另一種設定格式,不能只憑副檔名判斷格式,更不能混用兩種格式的欄位。協定與傳輸欄位的設定,仍須以實際執行的核心版本為準。

應用程式請求 本機入站 路由比對 選定出站 目標服務

閱讀時可沿著這條流程找出問題。網頁請求必須先進入某個入站,才會進行路由比對;路由選取的是出站標籤,不是訂閱群組名稱。DNS 可支援網域解析及部分路由判斷,但不是所有流量都會經過的「代理出口」。

log:先確認能看到哪些資訊,再調整連線參數

頂層的 log 用來控制記錄輸出。排查問題時可先使用 info,問題解決後通常可改回 warning。直接啟用 debug 容易產生大量細節,反而讓簡單的連接埠衝突被淹沒在輸出內容中。

{
  "log": {
    "loglevel": "info"
  }
}

這是欄位片段,不是完整的執行設定。常見記錄層級包括 debug、info、warning、error 與 none。此處未設定記錄檔路徑,方便先透過終端機或用戶端記錄面板查看啟動結果;若設定 access、error 檔案,必須確認目標目錄已存在,且執行帳戶具有寫入權限。

inbounds:應用程式從哪個位址與連接埠進入

inbounds 是陣列,一份設定可同時接收 SOCKS 與 HTTP 代理請求。listen 指定監聽位址,port 指定本機連接埠,protocol 則決定應用程式要使用哪種代理協定連線。這些都不是遠端節點的位址與連接埠。

10808
本文的 SOCKS 入站連接埠
10809
本文的 HTTP 入站連接埠
127.0.0.1
僅供本機連線的監聽位址

以上是本文明確指定的連接埠,不代表所有用戶端版本的預設值。若 v2rayN 已占用其中一個連接埠,測試用核心就無法再次繫結;請先停止占用該連接埠的程序,或同時修改設定與測試指令中的連接埠。不要只修改其中一處。

SOCKS 入站

tag
local-socks
listen
127.0.0.1
port
10808
protocol
socks
settings
auth 設為 noauth,udp 設為 false

本例只測試 TCP;關閉 UDP 轉送不影響一般 HTTPS 連線。

HTTP 入站

tag
local-http
listen
127.0.0.1
port
10809
protocol
http
settings
空物件,使用此入站的預設設定

HTTPS 網站通常會透過 HTTP 代理的 CONNECT 方法建立通道。

本機應用程式的 HTTP 代理請設為 127.0.0.1:10809,或將 SOCKS5 代理設為 127.0.0.1:10808。兩種協定不能只憑連接埠就任意互換。將監聽位址改為 0.0.0.0 會擴大可連線範圍;若沒有存取控制與防火牆限制,不應將未經驗證的代理公開於其他裝置可連線的網路。

outbounds:出口標籤與出口協定是兩回事

outbounds 同樣是陣列。tag 是設定內部引用的名稱,protocol 才是實際的出站方式。將標籤命名為 proxy,不會自動取得代理功能;若該項目的協定是 freedom,它仍然代表直連。

{
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}

這兩個出站都不需要遠端帳號:freedom 使用本機網路連線至目標,blackhole 則會丟棄符合條件的流量。在本文這份未設定負載平衡器等額外功能的設定中,若路由未符合任何規則,就會使用陣列中的第一個出站,因此此處的預設出口是 direct。

結論:修改出口前,先確認標籤指向的協定

排查「規則已符合,但流量仍走本機網路」時,先找出對應出站的 protocol;若值為 freedom,就應修正出口設定,而不是反覆調整網域比對條件。

routing:由上而下比對,標籤必須能找到對應項目

routing.rules 會依序檢查,第一條符合的規則便決定流量去向。常見條件包括網域 domain、目標 IP ip、連接埠 port 與入站標籤 inboundTag。一條規則包含不同類型的條件時,通常必須同時符合;同一網域清單中的多個項目則是候選比對條件。

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:blocked.example"],
        "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"
      }
    ]
  }
}

full:blocked.example 只會比對這個完整網域;domain:example.org 則可比對該網域及其子網域。本文使用保留的範例網域測試封鎖,避免依賴實際網站。規則中的 outboundTag 必須分別對應已定義的 block 與 direct,大小寫也必須一致。

domainStrategy比對行為閱讀設定時的重點
AsIs依據請求中已有的目標資訊比對,不會為路由主動解析網域網域請求不會自動符合以解析後 IP 為條件的規則
IPIfNonMatch網域未符合規則時,解析後再嘗試比對 IP檢查 DNS 結果,以及可能增加的解析等待時間
IPOnDemand路由比對需要 IP 資訊時進行解析IP 規則的位置可能導致提早解析

本例採用 AsIs,因此直接請求 192.168.1.1 可以符合私有 IP 規則;但若存取解析至私有位址的網域,不會只因為這條規則就觸發路由解析。直連出站最終仍可能需要解析網域,這是出站連線階段的工作,不能與路由策略混為一談。

dns:內建解析器不代表接管所有 DNS 請求

頂層的 dns 用來設定內建解析器。只有在路由需要網域對應的 IP,或某個出站設定要求使用內建解析結果時,才會參與相應流程。僅設定 dns.servers,不會自動接管瀏覽器的加密 DNS、系統的所有解析,也不會憑空建立本機 DNS 監聽連接埠。

{
  "dns": {
    "servers": ["localhost"]
  }
}

此處的 localhost 是呼叫系統解析功能的特殊值,不代表必須在 127.0.0.1:53 執行 DNS 服務。本文使用此設定讓範例保持簡單,但它不是 DNS 隔離方案。若要指定解析出口,還需一併檢查核心的 DNS 行為、相關路由,以及出站的網域解析策略。

  1. 先確認應用程式傳送了什麼:HTTP 代理的 CONNECT 請求通常會帶上網域;SOCKS 請求則可能帶上網域,也可能帶上應用程式已解析的 IP。
  2. 接著確認路由是否會解析:routing.domainStrategy 決定路由在什麼情況下需要將網域轉換為 IP。
  3. 最後確認出站如何連線:freedom 的解析策略屬於出站設定,與路由層的同名概念位於不同位置;不要將欄位複製到錯誤的層級。

例如使用 curl 時,socks5://127.0.0.1:10808 通常會由 curl 在本機解析目標;socks5h://127.0.0.1:10808 則會將網域交由 SOCKS 代理端處理。測試網域分流時,建議優先使用後者,否則核心只會取得 IP,網域規則可能沒有比對機會。

完整設定:以直連與封鎖驗證五個頂層欄位

以下是一份完整的傳統 JSON 格式設定。它只提供本機 HTTP、SOCKS 入口,以及直連、封鎖兩種出口,不包含遠端代理節點,也不會讓本機原本無法直連的網站自動變得可連線。這份設定用來先驗證結構、連接埠監聽與規則引用,再逐步加入實際節點參數。

{
  "log": {
    "loglevel": "info"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": false
      }
    },
    {
      "tag": "local-http",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:blocked.example"],
        "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"
      }
    ]
  },
  "dns": {
    "servers": ["localhost"]
  }
}

JSON 物件的頂層欄位順序不會決定執行順序;本文依閱讀脈絡排列。真正影響行為的是規則陣列順序、預設出站的位置,以及欄位之間的引用關係。儲存時請使用 UTF-8,鍵名與字串使用英文雙引號,最後一項後方不要加逗號,也不要將說明用註解複製到檔案中。

驗證順序:分別檢查語法、啟動、入站與路由

將完整範例儲存為目前目錄下的 config.json。以下以 Linux 終端機為例,先檢查 JSON 語法,再讓實際使用的核心檢查設定。語法檢查通過只代表 JSON 可供解析,不保證協定欄位、檔案相依項目或網路連線都正確。

python3 -m json.tool config.json > /dev/null

# 使用 Xray 時執行
xray run -test -config config.json

# 使用支援此命令格式的 V2Ray v5 時執行
v2ray test -c config.json

請依實際使用的核心,從兩條核心檢查指令中擇一執行,不要為了測試而同時執行兩套服務。舊版執行檔的子命令可能不同,請先執行 xray help 或 v2ray help 確認。檢查通過後,使用該版本支援的執行指令載入同一個檔案,例如 Xray 的 xray run -config config.json。

# 在另一個終端機檢查 TCP 監聽
ss -lntp 'sport = :10808 or sport = :10809'

# 透過 HTTP 入站測試直連出站
curl --noproxy "" --proxy http://127.0.0.1:10809 --max-time 15 -I https://example.org/

# 將網域交給 SOCKS 入站,測試封鎖規則
curl --noproxy "" --proxy socks5h://127.0.0.1:10808 --max-time 5 -I https://blocked.example/

第一個 curl 是否成功,仍取決於本機網路、系統解析與目標網站;這不是代理節點速度測試。第二個請求預期無法取得目標 HTTP 回應,因為目標網域符合 block 規則。實際錯誤訊息會依核心與連線階段而異,請搭配記錄確認,不能只憑一次逾時就認定路由已生效。

結論:每次只驗證一個環節

先確認監聽正常,再透過明確指定的代理參數確認請求已進入核心,最後對照記錄判斷出口。如此可將「應用程式未使用代理」與「流量進入代理後規則有誤」拆成兩個問題,避免同時修改連接埠、DNS 與節點而造成新的干擾。

  1. 連線遭拒:確認程序是否已啟動,以及監聽位址與連接埠是否一致。此時不必優先排查遠端節點參數。
  2. 入站已有請求,但出口不正確:檢查規則順序、請求帶入的是網域還是 IP,以及預設出站是否放錯位置。
  3. 規則正確但連線失敗:接著檢查解析結果、目標是否可連線、遠端驗證與傳輸安全參數。
  4. 重新啟動後修改消失:確認修改的是手動維護的設定,還是用戶端產生的暫存執行檔。使用用戶端時,可返回使用指南,從相應的設定入口進行調整。

掌握這套結構後,閱讀 v2rayN 產生的設定會更容易:先找入站連接埠,再找預設出口,接著查看規則,最後確認 DNS 實際參與的位置。若要確認平台安裝與核心準備步驟,可繼續參閱完整文件,不必一開始就把所有進階欄位塞進同一份檔案。

下載v2rayN