適合已經會匯入節點,卻還不清楚各設定欄位用途的讀者。先透過一份只包含本機監聽、直連與封鎖的完整設定,了解請求的處理路徑,再拆解連接埠、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 也必須一併修改。
| 欄位或位置 | 範例值 | 實際用途 |
|---|---|---|
protocol | freedom | 選擇直連的出站實作 |
tag | direct | 供路由規則引用的識別名稱 |
settings | {} | 該出站協定的設定物件 |
| 陣列第一個項目 | direct | 沒有規則符合時使用的預設出站 |
一般路由規則都未符合時,核心會使用 outbounds 陣列的第一個項目。範例將直連放在第一位,因此未符合封鎖規則或指定入站規則的流量仍會直連。若將封鎖出站移到第一位,大量未符合規則的請求就會遭到封鎖;這不是「節點突然失效」,而是預設出口改變了。
判斷順序:先確認預設出口,再檢查例外規則
檢查設定時,先找出 outbounds[0].tag,再逐條核對 routing.rules。這樣能先確認未符合規則的流量會送往何處,避免只注意某條網域規則,卻忽略整體行為。
5. routing:依序比對、條件組合與網域解析
routing.rules 會依陣列順序由上而下檢查,第一條符合的規則就會決定出口,不會再繼續尋找「更精確」的後續規則。通常應將具體例外放在前面,適用範圍較大的規則放在後面。如果第一條就是比對所有 TCP 和 UDP 流量的出口規則,後面的網域規則便不會生效。
- 先比對目標網域。請求包含
example.org或其子網域時,第一條規則會選擇blocked。domain:會比對該網域及其子網域;若只要比對一個完整網域,可使用full:。 - 接著比對目標 IP。範例列出的私有位址與回環位址會走
direct。這是依位址範圍比對;網域最後可能解析到私有位址,不代表一定會符合此規則。 - 接著比對來源入站。第三條規則會比對來自
http-in的請求,並選擇直連。但若請求先前已符合網域封鎖規則,就不會再套用這一條。 - 最後使用預設出站。來自
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
}
]
}
}
- 只新增此物件不會自動改變既有流量;還必須讓規則的
outboundTag引用proxy,或將它設為第一個出站,負責處理未符合規則的流量。 - 若希望所有未符合規則的請求都使用上游,可將
proxy移到出站陣列第一位,同時保留必要的直連例外。範例原本的http-in直連規則也應依需求調整。 - 上游連接埠不能填自己的
10808,否則可能形成迴圈。即使使用不同連接埠,也不能讓上游將相同請求轉回本執行個體。 - SOCKS 本身不提供傳輸加密。此處的本機上游範例僅用於說明設定結構;連線至遠端服務時,應依實際協定與網路邊界設計傳輸方式。
7. 驗證設定與 v2rayN 的儲存位置
驗證分為三個層次:JSON 能否解析、核心能否接受欄位,以及實際請求是否符合規則。三者不能互相取代。文字格式正確,不代表引用的 tag 一定存在;核心成功啟動,也不代表系統代理已指向正確的連接埠。
- 先備份原始檔案。保留一份能正常啟動的副本,每次只修改一類設定,例如只改連接埠或只改路由,方便還原。
- 使用相符的核心檢查。先執行隨附核心的說明命令,確認該版本支援的設定測試參數。測試工具必須與實際執行的核心一致,不要用另一種核心的檢查結果替代。
- 查看啟動記錄。若記錄顯示監聽失敗,先檢查位址或連接埠;若顯示設定載入失敗,先核對欄位型別與協定設定。定位問題時可暫時將
loglevel改為info,排查後再還原。 - 送出兩組明確的請求。先驗證直連出口,再驗證封鎖規則;測試時明確指定連接埠,避免受到其他應用程式代理設定的影響。
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、連接埠與協定參數更容易找出原因。