V2Ray 設定檔 JSON 結構解析:逐段看懂 inbounds、outbounds 與 routing

以完整的 config.json 為例,逐段解析入站監聽、出站 tag 與路由規則的比對順序,以及三者如何透過 tag 串接。

本文重點

適合已經會匯入節點,卻還不清楚各設定欄位用途的讀者。先透過一份只包含本機監聽、直連與封鎖的完整設定,了解請求的處理路徑,再拆解連接埠、tag 與規則順序,最後說明如何加入實際的代理出站,以及如何避免修改 v2rayN 暫存產生的檔案後又被覆寫。

1. config.json 的請求處理路徑

config.json 是核心讀取的設定檔,不等同於訂閱連結,也不是用戶端設定檔。訂閱通常提供節點資訊;用戶端則依據節點、路由與本機監聽設定產生核心設定。了解這層關係,才能判斷應在節點編輯、路由設定或自訂設定中進行修改。

應用程式送出請求 入站接收 比對路由 出站連線 目標服務

inbounds 說明「請求從哪裡進入」,outbounds 說明「請求如何送出」,routing 則決定「這次請求要走哪個出口」。瀏覽器必須先將請求送到本機代理連接埠,路由規則才有機會處理;只修改路由,不會讓所有應用程式自動使用代理。

本文採用 V2Ray 常見的 JSON 設定結構。V2Fly 與 Xray 共用部分欄位,但協定功能、欄位選項與命令列參數仍須依實際使用的核心區分。v2rayNG 使用 Xray 核心,v2flyNG 使用 V2Fly 核心;v2rayN 桌面版則應先確認目前設定實際呼叫的核心,不能只憑用戶端名稱判斷。

2. 完整設定:雙入站、直連與封鎖

以下是一份結構完整的教學設定:SOCKS 監聽 127.0.0.1:10808,HTTP 監聽 127.0.0.1:10809。連線至範例網域 example.org 及其子網域時會封鎖,其餘請求預設直連。此設定不含遠端代理節點,因此不能用來連線遠端代理。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "blocked",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": [
          "domain:example.org"
        ],
        "outboundTag": "blocked"
      },
      {
        "type": "field",
        "ip": [
          "10.0.0.0/8",
          "172.16.0.0/12",
          "192.168.0.0/16",
          "127.0.0.0/8",
          "::1/128"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "inboundTag": [
          "http-in"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

這是嚴格的 JSON:鍵名與字串使用雙引號,不含註解,也沒有多餘的尾隨逗號。陣列可以包含多個物件,但每個物件都必須符合對應協定的欄位定義。不要直接把介面顯示的「節點名稱」當成核心設定鍵,也不要任意在頂層新增 subscription 欄位;訂閱管理是用戶端功能。

3. inbounds:監聽位址、連接埠與入站 tag

listen 是本機繫結位址,不是遠端節點位址;port 是應用程式連線的本機連接埠,不是伺服器連接埠。監聽位址設為 127.0.0.1,代表只接受本機 IPv4 回環連線。改成監聽所有網路介面會擴大可存取範圍,牽涉區域網路的存取控制,不應當成連線失敗時的通用解法。

SOCKS 入站

protocol
socks
listen
127.0.0.1
port
10808
tag
socks-in

應用程式必須透過 SOCKS 協定連線;UDP 是否可用,還取決於應用程式與後續的出站鏈路。

HTTP 入站

protocol
http
listen
127.0.0.1
port
10809
tag
http-in

連線至 HTTPS 目標通常會透過 CONNECT 通道,不需要將入站協定改成 https。

tag 是設定內部使用的識別名稱。入站的 socks-in 可供路由規則透過 inboundTag 引用;它不會決定協定,也不會自動產生同名的出站。建議為每個入站與出站使用各自唯一且穩定的 tag;修改名稱時,也要同步檢查所有引用。

範例中的 udp: true 只代表 SOCKS 入站允許 UDP。應用程式必須支援 SOCKS UDP ASSOCIATE,出站也必須能承載這類流量;開啟此設定不代表系統的所有 UDP 流量都會經過核心,更不代表一般 HTTP 系統代理能攔截遊戲流量。

4. outbounds:協定實作與預設出口

範例中的 freedom 代表直連,blackhole 代表封鎖;direct 和 blocked 只是自行指定的 tag。將 direct 改名為 office-direct 不會改變其行為,但所有引用它的 outboundTag 也必須一併修改。

欄位或位置範例值實際用途
protocolfreedom選擇直連的出站實作
tagdirect供路由規則引用的識別名稱
settings{}該出站協定的設定物件
陣列第一個項目direct沒有規則符合時使用的預設出站

一般路由規則都未符合時,核心會使用 outbounds 陣列的第一個項目。範例將直連放在第一位,因此未符合封鎖規則或指定入站規則的流量仍會直連。若將封鎖出站移到第一位,大量未符合規則的請求就會遭到封鎖;這不是「節點突然失效」,而是預設出口改變了。

判斷順序:先確認預設出口,再檢查例外規則

檢查設定時,先找出 outbounds[0].tag,再逐條核對 routing.rules。這樣能先確認未符合規則的流量會送往何處,避免只注意某條網域規則,卻忽略整體行為。

5. routing:依序比對、條件組合與網域解析

routing.rules 會依陣列順序由上而下檢查,第一條符合的規則就會決定出口,不會再繼續尋找「更精確」的後續規則。通常應將具體例外放在前面,適用範圍較大的規則放在後面。如果第一條就是比對所有 TCP 和 UDP 流量的出口規則,後面的網域規則便不會生效。

  1. 先比對目標網域。請求包含 example.org 或其子網域時,第一條規則會選擇 blocked。domain: 會比對該網域及其子網域;若只要比對一個完整網域,可使用 full:。
  2. 接著比對目標 IP。範例列出的私有位址與回環位址會走 direct。這是依位址範圍比對;網域最後可能解析到私有位址,不代表一定會符合此規則。
  3. 接著比對來源入站。第三條規則會比對來自 http-in 的請求,並選擇直連。但若請求先前已符合網域封鎖規則,就不會再套用這一條。
  4. 最後使用預設出站。來自 socks-in 且未符合前兩條規則的請求,會使用陣列第一個項目 direct。

同一條規則中的不同條件欄位通常必須同時符合。例如同時設定 inboundTag 和 domain,代表指定入站中的指定網域;同一個網域陣列內的多個項目則是可符合其中之一的選項。將「或」的關係誤寫成一條包含多個條件欄位的規則,是分流設定無法生效的常見原因。

domainStrategy 位於 routing 內,用來控制路由比對階段如何處理網域。AsIs 不會為了比對 IP 規則而主動解析網域;IPIfNonMatch 會在網域未符合時嘗試解析,再進行比對;IPOnDemand 則會在比對需要 IP 資訊的規則時觸發解析。它不是「所有 DNS 都一律走代理」的開關。

6. 加入代理出站:先確認上游,再修改引用

遠端代理需要有效的伺服器參數。VMess、VLESS 等出站的位址、連接埠、身分資訊與傳輸安全設定都必須與伺服器一致,不能只改一個 protocol 名稱就完成轉換。若已有節點,建議透過用戶端匯入並檢查產生的設定,避免手動拼湊不同核心的協定欄位。

為了單獨示範「新增出站再引用」的流程,以下使用本機 SOCKS 上游。前提是另一個獨立服務確實正在監聽 127.0.0.1:10810,且不需要驗證。此物件應加入 outbounds 陣列;它只是設定片段,不是完整檔案。

{
  "tag": "proxy",
  "protocol": "socks",
  "settings": {
    "servers": [
      {
        "address": "127.0.0.1",
        "port": 10810
      }
    ]
  }
}

7. 驗證設定與 v2rayN 的儲存位置

驗證分為三個層次:JSON 能否解析、核心能否接受欄位,以及實際請求是否符合規則。三者不能互相取代。文字格式正確,不代表引用的 tag 一定存在;核心成功啟動,也不代表系統代理已指向正確的連接埠。

  1. 先備份原始檔案。保留一份能正常啟動的副本,每次只修改一類設定,例如只改連接埠或只改路由,方便還原。
  2. 使用相符的核心檢查。先執行隨附核心的說明命令,確認該版本支援的設定測試參數。測試工具必須與實際執行的核心一致,不要用另一種核心的檢查結果替代。
  3. 查看啟動記錄。若記錄顯示監聽失敗,先檢查位址或連接埠;若顯示設定載入失敗,先核對欄位型別與協定設定。定位問題時可暫時將 loglevel 改為 info,排查後再還原。
  4. 送出兩組明確的請求。先驗證直連出口,再驗證封鎖規則;測試時明確指定連接埠,避免受到其他應用程式代理設定的影響。
curl --proxy socks5h://127.0.0.1:10808 --connect-timeout 5 https://example.com/
curl --proxy socks5h://127.0.0.1:10808 --connect-timeout 5 https://example.org/
curl --proxy http://127.0.0.1:10809 --connect-timeout 5 https://example.com/

socks5h 會將目標主機名稱交由代理處理,適合用來驗證本例的網域規則。在外網可連線的前提下,第一與第三個測試應透過直連出站嘗試存取,第二個則應遭到封鎖。實際錯誤訊息會因核心與 curl 版本而異,不能只憑某個錯誤碼判斷符合哪條規則,還應同時查看記錄。在 Windows 上,如果終端機別名攔截了命令,可明確執行 curl.exe。

在 v2rayN 中,先透過「設定」→「參數設定」確認本機監聽連接埠,再透過「設定」→「路由設定」檢查目前啟用的路由設定;不同版本的群組或名稱可能略有差異,請以目前介面為準。一般節點執行時使用的設定通常由用戶端重新產生;切換節點、更新訂閱或重新啟動核心後,直接修改產生檔案的內容可能會被覆寫。

儲存位置:常用規則應保留在用戶端設定中

若要長期保留連接埠與分流規則,應修改用戶端中的對應設定;若要完整控制 JSON,則使用用戶端的自訂設定功能,並確認該項目呼叫的是哪個核心。不要同時維護介面規則與暫存檔案,還假設兩者會自動合併。

8. 常見設定問題

已選取節點,為什麼範例仍然直連?

本例的第一個出站是 freedom,沒有遠端代理參數。在用戶端選取節點,不會自動改寫一份獨立執行的 JSON。請先確認實際載入的檔案,再檢查 outbounds[0] 與符合規則的 outboundTag。

更改 tag 名稱後,為什麼規則就失效了?

在檔案中搜尋舊 tag,逐一核對 outboundTag 與 inboundTag。引用值必須與對應物件的 tag 完全一致,包括大小寫。修改後請重新測試並重新啟動核心;只儲存檔案而繼續使用舊的執行程序是不夠的。

已開啟系統代理,為什麼有些應用程式仍未經過 10809?

系統代理只對遵循該設定的應用程式有效。請先用上方的 HTTP 測試命令確認監聽正常,再檢查該應用程式是否有自己的代理設定。不要試圖擴大監聽位址來解決應用程式未使用代理的問題,兩者屬於不同層面的設定。

可以直接把訂閱內容貼進 config.json 嗎?

不能把任意訂閱文字當成核心 JSON。請先在 v2rayN 的訂閱管理中匯入並更新,確認節點協定受所選核心支援;若要研究設定結構,再查看用戶端產生的設定,分享前記得隱藏位址與身分資訊。

繼續查閱欄位定義時,可使用JSON 手冊核對監聽、出站與路由各段。實際排查也應依相同順序進行:應用程式是否已接入、入站是否正在監聽、規則是否符合、出站是否能連線。每次只驗證一個層次,比同時修改 DNS、連接埠與協定參數更容易找出原因。

v2rayN 下載