設定參考

V2Ray 設定檔結構與參數說明

從 JSON 頂層結構開始,依序拆解 inboundsoutboundsroutingdnspolicy。每個部分先說明流量經過的位置,再解釋參數填寫方式,最後提供可組合使用的設定片段。

JSON 結構 入站與出站 路由分流 DNS 與策略

如果只是完成用戶端安裝、匯入訂閱與首次連線,先閱讀快速入門教學會更直接。本頁適合在需要了解設定來源、調整本機監聽、增加路由規則或定位啟動錯誤時查閱。使用 v2rayN、v2rayNG 或 v2flyNG 時,圖形介面會代為產生大部分設定;了解這些欄位,仍有助於判斷用戶端選項最終改變了哪些內容。

桌面裝置優先使用 v2rayN,安裝入口集中在取得用戶端頁面。本文範例同時採用 V2Ray 與 Xray 常見的設定寫法,但不同核心支援的擴充欄位並不完全一致。修改前先確認用戶端目前使用的核心,再保留原設定副本,避免將某個核心專用參數直接套用到另一套環境。

01 / JSON STRUCTURE

設定檔結構總覽

先依流量方向理解頂層物件

V2Ray 與 Xray 的設定檔通常是一個 JSON 物件。首先要記住的不是欄位數量,而是流量方向:應用程式先連線到本機的入站監聽,核心讀取路由規則、選擇一個出站,再透過目標出站建立連線。DNS 負責將網域解析為位址,policy 負責工作階段逾時、統計等執行策略,log 則決定記錄位置與紀錄等級。

inboundsoutbounds 都是陣列,因為同一個執行個體可以同時監聽多個本機連接埠,也可以準備多個出口。陣列中的每個物件通常使用 tag 命名,路由規則再透過標籤引用。標籤只是執行個體內部的識別名稱,不會傳送給遠端;名稱可自行決定,但應保持簡短、穩定且能看出用途,例如 socks-inproxydirectblock

一個便於閱讀的設定順序是:先寫入日誌,再寫 DNS,接著是入站、出站、路由與策略。JSON 本身不要求這個順序,但固定排列能縮短排查時間。遇到啟動失敗時,可以從檔案開頭往下檢查;比較兩份設定時,也更容易找出變更。圖形用戶端產生的順序可能不同,只要層級與欄位有效,執行結果不會因物件鍵的排列順序而改變。

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {},
  "inbounds": [],
  "outbounds": [],
  "routing": {},
  "policy": {}
}

JSON 語法與設定語意是兩層檢查

設定能被 JSON 解析,只代表括號、引號、逗號與資料型別符合語法,不表示目前核心會接受所有欄位。例如連接埠寫成字串,可能是合法 JSON,卻不符合該欄位需要整數的要求;出站標籤拼寫不一致,也可能直到套用路由時才暴露問題。排查時要分兩步:先確認 JSON 可以解析,再查看核心日誌中關於未知欄位、型別錯誤、標籤缺失或協定設定不完整的提示。

標準 JSON 不允許註解,也不允許在物件或陣列最後一項後保留多餘逗號。複製範例時尤其要注意這一點。文件為了說明經常展示片段,但片段本身只有放入正確的父層物件才有效。例如單獨複製 routing 物件時,必須將它作為頂層的 "routing" 值,而不是直接貼到檔案末尾。字串必須使用雙引號,布林值使用 truefalse,不能加上引號。

欄位 資料型態 主要用途 常見檢查點
log 物件 控制存取日誌、錯誤日誌與記錄等級 路徑權限、日誌等級是否過低
inbounds 陣列 接收來自瀏覽器、系統或區域網路裝置的連線 監聽位址、連接埠占用、協定類型
outbounds 陣列 定義代理、直連與阻擋等出口 伺服器參數、標籤、傳輸設定
routing 物件 依網域、IP、連接埠或入站標籤選擇出口 規則順序、標籤引用、解析策略
dns 物件 定義解析伺服器、靜態對映與查詢條件 查詢路徑、網域比對、回退行為
policy 物件 控制工作階段逾時、流量統計等執行策略 策略層級、統計開關與統計模組的配合

修改前建立可回復的基準

開始調整前,先讓目前設定在不修改的情況下成功啟動一次,並記下正在使用的本機連接埠、系統代理模式與核心名稱。接著複製設定檔,為副本加上用途明確的檔名。每次只修改一個邏輯單元,例如先增加直連出站,驗證後再加入路由規則。一次改動多個區域雖然較快,但啟動失敗時很難判斷是語法、標籤還是協定參數造成的。

圖形用戶端可能在更新訂閱、切換節點或重新啟動核心時重新產生執行設定。此時直接編輯暫存檔,變更可能無法長期保留。v2rayN 中應優先使用用戶端提供的自訂設定、路由設定或進階選項;Android 用戶端則先確認目前設定來自訂閱節點還是手動設定。想了解某個術語的界線,可同時查看術語表,避免將「入站」、「系統代理」與「路由模式」理解成同一項功能。

02 / INBOUNDS

inbounds 入站設定

監聽位址決定誰能連線

入站是本機應用程式將流量交給核心的入口。最常見的本機入口是 SOCKS 與 HTTP 代理。listen 決定在哪個網路位址監聽,port 決定連接埠,protocol 決定應用程式應使用哪種代理協定。只供目前裝置使用時,建議將監聽位址寫成 127.0.0.1。這個位址只接受本機連線,瀏覽器、系統代理與同一裝置上的其他程式可以使用,區域網路中的其他裝置無法直接接入。

如果需要讓桌面用戶端提供給同一區域網路中的手機、電視或另一台電腦使用,入站通常會監聽 0.0.0.0 或特定的區域網路位址。這麼做還需要同時處理系統防火牆、網路類型與存取控制,不能只修改監聽位址。共用裝置填寫的是執行核心那台電腦的區域網路位址與入站連接埠,而不是 127.0.0.1。相關操作可參考v2rayN 允許區域網路連線設定教學

{
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ]
}

SOCKS、HTTP 與透明接管的界線

SOCKS 入站適合明確支援 SOCKS 代理的應用程式,可承載 TCP,並在設定允許時處理 UDP。HTTP 入站主要供使用 HTTP CONNECT 或一般 HTTP 代理的程式連線。兩者都要求應用程式或系統代理明確指向對應連接埠。程式設定為 HTTP 代理時,不能將位址指向 SOCKS 連接埠;連接埠雖然正確但協定類型選錯,常見表現是連線立即中斷、瀏覽器提示代理回應異常,或日誌中出現無法識別的握手資料。

TUN 模式與一般本機代理不同。它透過虛擬網路介面接收更廣泛的系統流量,用戶端還需要設定路由表、DNS 接管與權限。不要將 TUN 相關設定簡單理解成多加一個 SOCKS 入站。v2rayN 會依據介面中的 TUN 選項組織執行參數,通常應先透過用戶端介面啟用,再檢查日誌,而不是將其他環境中的完整 TUN 片段直接拼入目前設定。一般系統代理已能滿足瀏覽器與常見桌面程式時,沒有必要為了「涵蓋更多」而同時啟用多種接管方式。

sniffing 如何協助網域路由

sniffing 用來從連線中的協定特徵還原目標網域。某些應用程式會先自行解析網域,再將 IP 位址交給代理;如果 routing 只有網域規則,核心看到純 IP 時就無法依網域比對。啟用嗅探後,HTTP 請求中的主機資訊或 TLS 握手中的伺服器名稱,可以協助路由模組取得網域。範例中的 destOverride 表示允許使用辨識出的 HTTP 或 TLS 目標覆寫原始目的位址,讓後續規則進行判斷。

嗅探不是 DNS 的替代品,也不是所有連線都能還原網域。沒有可辨識主機資訊的協定仍然只會呈現 IP;加密握手方式與應用程式行為也會影響結果。排查路由未命中時,可以先查看存取日誌記錄的是網域還是 IP,再決定調整 domainStrategy、增加 IP 規則或檢查嗅探設定。不要在沒有觀察日誌的情況下反覆堆疊相同的網域與 IP 條件,這會讓規則難以維護。

連接埠、驗證與標籤的設定原則

同一個位址上的連接埠不能同時被兩個程序占用,也不能讓兩個入站監聽相同位址與連接埠。用戶端啟動後若立即回報位址已被占用,先關閉重複執行的執行個體,再檢查其他代理工具或舊核心程序。隨意修改連接埠只能解決一半衝突:系統代理、瀏覽器擴充功能與區域網路裝置中的連接埠也必須同步修改。為減少混淆,可以讓 SOCKS 與 HTTP 連接埠相鄰,但不要依賴固定數字判斷協定類型。

auth: "noauth" 適合只監聽回送位址的本機 SOCKS 入站。監聽區域網路位址時,應依用戶端支援情況評估驗證與防火牆限制,並只允許可信任的網路存取。標籤方面,每個入站使用獨立名稱,之後就能透過 inboundTag 為不同入口設定不同路由。例如本機流量使用一般分流,區域網路共用入口限制部分連接埠。修改標籤後,要全文檢查 routing 中的引用,避免規則仍指向舊名稱。

參數 建議理解方式 常見錯誤
listen 決定連線來源範圍 共用時仍填寫回送位址,或本機使用時開放至所有網卡
port 應用程式連線至核心的本機連接埠 與其他程式衝突,修改後未同步系統代理
protocol 定義入站握手方式 應用程式選擇 HTTP,實際連線至 SOCKS 連接埠
tag 供路由規則引用的內部名稱 更名後 routing 仍使用舊標籤
sniffing 協助還原網域並參與分流 誤以為啟用後所有 IP 都能轉換成網域

03 / OUTBOUNDS

outbounds 出站設定

代理、直連與阻擋組成基礎出口

出站定義核心要將流量送往何處。完整設定通常至少包含代理出口與直連出口,需要明確拒絕某類連線時再增加阻擋出口。代理出口保存伺服器位址、連接埠、使用者識別碼、加密或傳輸設定;直連出口讓核心直接存取目標;阻擋出口則主動終止符合規則的連線。routing 不負責建立連線,只負責將目前請求交給某個出站標籤。

出站陣列的順序值得留意。當某條連線沒有命中任何路由規則時,常見實作會使用第一個出站作為預設出口。因此,將代理放在第一項,還是將直連放在第一項,會直接影響未命中流量的去向。不要只依賴預設順序表達重要策略,關鍵流量應明確寫出規則;同時仍要讓第一項符合整體預期,避免新增網域或遺漏條件時產生意外結果。

{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-2222-4333-8444-555555555555",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "server.example.com"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {
        "response": {
          "type": "none"
        }
      }
    }
  ]
}

協定身分參數與傳輸參數要分開檢視

排查代理出站時,先將欄位分成兩組。第一組是協定身分參數,例如伺服器位址、連接埠、使用者 ID 與協定要求的附加設定;第二組是 streamSettings 中的傳輸參數,例如 TCP、WebSocket、gRPC、TLS 或 REALITY。兩組參數各自正確但組合關係不一致,連線仍然無法建立。例如遠端使用 WebSocket,而本機設定成 TCP;伺服器憑證對應的名稱與 serverName 不同;使用者識別碼正確,但連接埠指向另一項服務。

訂閱匯入的價值之一,就是將服務提供者給出的協定、傳輸、安全層與主機參數一併寫入用戶端。手動遷移時不要只複製位址與連接埠。看到「節點能測試但網頁打不開」時,也不要立即認定出站身分參數全部正確:用戶端測試方法可能只涵蓋部分鏈路,實際應用還會涉及 DNS、UDP、路由與系統代理。應結合執行日誌判斷失敗發生在解析、連線至遠端、握手還是存取目標階段。

直連出口同樣會受到 DNS 與網路環境影響

freedom 表示由目前裝置直接建立目標連線。它不是繞過整個設定流程,而是仍經過入站與 routing 後,由核心執行直連。直連失敗時要檢查本機網路、系統 DNS、目標位址以及出站的網域策略。若規則依網域選擇 direct,但目標在建立連線前需要解析,解析結果與位址族會影響後續行為。某些環境中 IPv6 記錄存在但實際連線條件不完整,也可能表現為等待較久後逾時。

可以為 freedom 出站設定適當的網域解析策略,但不同核心支援的值與行為可能有差異。沒有明確需求時,先保留用戶端產生的預設值。除錯過程中若想判斷問題是否來自分流,可以暫時建立一條範圍很小、目標明確的規則送往 direct,而不是刪除全部規則。驗證完成後再復原,避免臨時測試改變其他應用程式的流量路徑。

代理鏈與多出口應從簡單結構開始

一個設定可以包含多個代理出站,並透過路由標籤選擇,也可以讓一個出口經由另一個出口建立底層連線。這種結構適合有明確鏈路需求的環境,但標籤依賴會迅速增加。開始設定前先畫出「入站 → 路由 → 第一出口 → 底層出口」的順序,確保不存在互相引用。若 proxy-a 依賴 proxy-b,而 proxy-b 又回到 proxy-a,核心便無法得到有效鏈路。

多節點選擇通常由 v2rayN、v2rayNG 或 v2flyNG 的設定管理功能完成。用戶端切換節點時,會調整目前使用的出站或重新產生執行設定。直接在產生檔案中塞入大量伺服器物件,不一定能配合用戶端的切換邏輯。桌面環境優先讓 v2rayN 管理節點,只將穩定的自訂路由與 DNS 需求放到用戶端支援的擴充位置,這比長期手動維護整份節點清單更容易復原。

標籤範例 協定 用途 排查重點
proxy 依節點實際協定 連線至遠端伺服器並轉送目標流量 位址、連接埠、身分、傳輸與安全層必須成套一致
direct freedom 從本機網路直接存取目標 本地網路、DNS、位址族與目標可達性
block blackhole 終止符合規則的流量 規則範圍是否過寬,是否誤傷必要連線

04 / ROUTING

routing 路由規則

規則由上至下比對,第一個結果生效

路由模組會依連線的目標網域、IP、連接埠、網路類型、協定特徵或入站標籤選擇出站。最重要的行為是規則順序:規則通常由上至下檢查,一旦某條規則符合,就使用該規則指定的 outboundTag,後續規則不再參與。因此,較具體的規則應放在前面,較寬泛的規則放在後面。若將「所有 TCP 流量走代理」寫在第一條,後面的直連網域規則就沒有機會生效。

設計規則時,先寫出預設策略,再列出例外。如果預設出口是代理,可以優先放置阻擋條件與明確直連條件,其餘流量落到預設代理;如果預設出口是直連,則先列出需要代理的目標。不要同時依賴出站陣列順序、複雜網域清單與多條兜底規則來表達同一件事。選擇一種清楚的預設行為,規則只描述例外,之後維護時更容易判斷新增項目應放在哪裡。

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "protocol": [
          "bittorrent"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "domain:intranet.example.com",
          "full:printer.example.net"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

網域比對方式決定規則界線

網域條件常見寫法包括完整比對、網域及其子網域比對、關鍵字比對與預設網域集合。full:printer.example.net 只比對完整主機名稱,適合界線明確的單一服務;domain:example.com 通常涵蓋該網域及其子網域,適合一組相關主機;沒有前綴的字串在不同情境下可能以特定方式解讀,維護時最好明確寫出比對類型,避免日後忘記原意。

關鍵字比對範圍較廣,一個短字串可能意外命中不相關網域。除非確實需要依名稱片段分類,否則優先使用 full 或 domain。規則未命中時,先確認核心看到的目標是不是網域。如果應用程式已將目標解析為 IP,而入站嗅探沒有還原網域,那麼再精確的網域規則也不會執行。此時可以檢查存取日誌、啟用適當的 sniffing,或為已知位址範圍補充 IP 條件。

domainStrategy 串連網域規則與 IP 規則

domainStrategy 控制路由模組在什麼情況下為了比對 IP 規則而解析網域。AsIs 強調依收到的目標形式判斷,網域不會僅為了路由比對而主動轉換成 IP;IPIfNonMatch 通常表示網域規則未命中後,再解析位址並嘗試比對 IP 規則;其他策略可能會更積極地進行解析。策略越積極,網域流量越可能參與 IP 分類,但也會增加 DNS 行為與路由結果之間的耦合。

選擇策略時要先問:目前規則主要依賴網域還是 IP?如果大部分規則是明確網域,只有少數網段需要補充判斷,IPIfNonMatch 會比較容易理解。如果所有網域都要先依位址分類,就必須確保 DNS 設定與預期出口一致。否則同一網域因解析伺服器、快取或位址族不同而得到不同結果,路由也會改變。修改 domainStrategy 後,應測試網域規則、IP 規則與未命中目標三種情況,而不是只開啟一個網頁判斷成功與否。

IP、連接埠、網路與入站標籤可以組合

IP 條件可以寫單一位址、CIDR 網段或核心支援的預設集合。私有位址通常應直連,避免存取路由器、印表機或區域網路服務時被送往遠端。連接埠條件適合限制明確的服務範圍,例如 5380,443,也可以表示區間。網路條件常用 tcpudp 或兩者組合。同一條規則中放入多個不同欄位時,通常需要同時符合;同一欄位陣列中的多個值則表示符合任一值。

inboundTag 很適合區分來源。例如 socks-in 走一般分流,lan-in 只允許使用指定出口。這樣不必為每種來源啟動多個核心執行個體。設定時應先確認入站標籤確實存在,並將來源限制寫在規則前段,避免被更寬泛的目標規則搶先比對。阻擋連接埠與協定時也要保守,範圍過寬會表現為部分應用程式能開啟首頁,卻無法播放、登入或同步。

用日誌驗證規則,不靠猜測

驗證路由最有效的方法,是準備幾個目標明確的測試項目:一個應直連的內部網域、一個應進入代理的目標,以及一個應被阻擋的條件,再查看存取日誌中的出站標籤。若日誌只顯示目標,未顯示預期標籤,可以暫時提高日誌詳細程度,測試完成後再恢復到較克制的等級,避免日誌持續增長。修改規則後要重新啟動或重新載入核心,確認用戶端沒有繼續使用舊的執行設定。

當規則數量變多時,為每組規則在設定檔外撰寫維護說明,記錄「為什麼需要這條」,比只記錄網域清單更有價值。標準 JSON 不能寫註解,可在獨立文件中保存說明。訂閱更新一般會影響節點與代理出站,不應順手覆蓋手動路由;如果用戶端每次更新後都遺失規則,表示編輯位置可能是暫存產生檔,應改用用戶端提供的路由設定入口。

05 / DNS

dns 解析設定

先分清系統解析與核心解析

DNS 設定容易出錯,是因為一台裝置上可能同時存在多條解析路徑。應用程式可以先呼叫系統 DNS 取得 IP,再將 IP 交給代理;核心也可以為了路由判斷主動解析網域;TUN 情境還可能由用戶端接管系統查詢。設定檔中的 dns 主要定義核心自身如何解析,並不會自動確保所有應用程式查詢都經過這裡。判斷問題前,先確認日誌中進入核心的是網域還是已解析好的 IP。

如果應用程式將網域直接交給 SOCKS 或 HTTP 代理,核心有機會依自己的 DNS 設定處理。若應用程式先在本地解析,routing 看到的可能只有位址,此時 DNS 設定對該次原始查詢不一定生效。sniffing 可以從部分連線中還原網域,但不能取代完整的查詢接管。因此,「已經寫了 dns 物件」與「所有程式都使用該 DNS」並不是同一回事。

{
  "dns": {
    "hosts": {
      "router.home.arpa": "192.168.1.1"
    },
    "servers": [
      {
        "address": "1.1.1.1",
        "domains": [
          "domain:example.com"
        ],
        "skipFallback": true
      },
      "localhost"
    ],
    "queryStrategy": "UseIP"
  }
}

servers 陣列既有順序,也可以附帶條件

servers 可以包含簡單位址,也可以使用物件為某個伺服器附加網域條件、預期位址範圍或回退行為。簡單設定從一至兩個穩定的解析來源開始即可。伺服器越多,不代表解析越可靠;如果各伺服器的使用條件不清楚,失敗時很難判斷查詢實際送往何處。物件中的 domains 用來讓指定網域優先交給該伺服器,適合內部網域或有明確解析來源的服務。

skipFallback 的用途,是控制符合目前伺服器條件的查詢是否還參與後續回退。啟用前要確認該伺服器確實能解析所列網域,否則查詢失敗後可能不會再嘗試其他來源。對於區域網路主機名稱,直接使用本地解析伺服器或 hosts 靜態對映通常更清楚。將內部名稱交給公共解析來源,不僅得不到結果,還可能讓排查方向偏離本地網路。

hosts 適合穩定對映,不適合維護動態位址

hosts 可以將網域對映至固定位址,也可以用於少量別名關係。它在測試新服務、覆寫區域網路主機名稱或暫時繞過錯誤解析時很方便。由於對映優先於一般查詢,寫錯後會持續將連線送往錯誤目標。使用 hosts 排錯時,要記錄新增項目,並在驗證後決定是否保留,避免數週後位址已經變更,設定卻仍固定在舊值。

對映值的資料型態要符合核心要求,網域鍵也應寫成預期的完整名稱。如果目標同時有 IPv4 與 IPv6,單一固定對映會改變正常的位址選擇。對於由服務提供者動態調度的網域,不建議使用 hosts 長期固定某個結果;看似縮短了一次查詢,實際上可能失去故障切換與位址更新能力。遇到偶發連線問題,應先比較解析結果與連線日誌,而不是立即將目前 IP 寫死。

queryStrategy 影響位址族選擇

queryStrategy 用來控制查詢 IPv4、IPv6 或兩類位址的傾向。不同核心支援的具體值可能有所差異,應以目前用戶端所使用核心的有效設定為準。裝置所在網路只有穩定 IPv4 時,強制只回傳 IPv6 會導致目標無法連線;網路具備 IPv6 並不表示每條遠端鏈路都適合優先使用它。選擇策略時要結合本地網路、代理伺服器位址與目標出站的能力。

典型現象是網域解析很快,但連線在某個位址族上持續等待,之後回退或逾時。此時可以分別查看解析得到的 A 與 AAAA 記錄,再觀察核心實際嘗試的目標位址。不要將所有 timeout 都歸咎於節點故障。若切換查詢策略後恢復,應繼續確認是本地 IPv6 路由、遠端伺服器監聽還是目標網路路徑的問題,而不是永久依賴一個偶然有效的設定。

DNS 與 routing 需要閉環檢查

domainStrategy 需要解析網域以比對 IP 規則時,routing 會呼叫 DNS;解析查詢本身又可能透過某個出站傳送。設計不當會出現循環依賴:為了決定網域應走哪個出口而先發起查詢,但查詢出口又依賴尚未完成的網域分類。簡單環境應避免為 DNS 設計過度複雜的路由鏈。先確保基本查詢可用,再為明確的解析伺服器位址新增直連或代理規則。

檢查閉環可以分四步進行:第一,看應用程式交給入站的是網域還是 IP;第二,看路由策略是否需要解析;第三,看查詢由哪個伺服器處理;第四,看查詢連線本身透過哪個出站。任何一步與預期不同,最終都會表現為網頁無法開啟或分流錯誤。v2rayN 的日誌可以協助定位查詢與連線階段,閱讀方法可參考V2Ray 執行日誌怎麼看

現象 優先檢查 不要先做什麼
網域失敗,直接存取 IP 有回應 查詢伺服器、DNS 出站路徑、應用程式是否使用系統解析 一次加入許多解析伺服器
網域規則未命中 入站看到的是網域還是 IP、sniffing、domainStrategy 重複新增相同網域關鍵字
區域網路主機名稱無法解析 本地 DNS、hosts 對映、搜尋網域 交給與區域網路無關的解析來源
解析成功但連線長時間等待 位址族、目標路由、出站實際嘗試的位址 只依解析速度判斷節點狀態

06 / POLICY

policy 策略與統計

policy 控制執行行為,不決定分流方向

policy 經常被誤認為 routing 的補充,實際上它主要控制連線工作階段的逾時、閒置判定與統計開關。流量走代理還是直連,仍由 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 處理不同階段

handshake 限制連線建立階段允許等待的時間。它針對尚未完成握手的連線,不等同於整個網頁的載入時限。設定過短時,在網路波動或遠端回應稍慢的情況下會提前失敗;設定過長則會讓明顯無法建立的連線占用資源更久。看到握手逾時時,應先排查伺服器位址、連接埠、傳輸層與本地網路,而不是立即將數值調得很大。

connIdle 關注連線在沒有資料活動時保留多久。閒置連線關閉後,應用程式通常會重新建立,但某些程式會將它表現為工作階段中斷。除錯時可以比較問題發生的時間間隔是否穩定:如果每次都在相近的閒置時長後斷線,值得檢查策略;如果斷線時間隨機且日誌顯示遠端重設,則更可能是鏈路或伺服器行為。

uplinkOnlydownlinkOnly 用於處理只有單向資料活動的連線。它們不是上傳、下載速度限制,也不會為某個應用程式分配頻寬。不了解現有連線行為時,不建議為了「最佳化」而隨意縮短。圖形用戶端產生的預設策略通常適合一般使用,只有長時間連線、資源受限或明確的服務情境才需要單獨評估。

統計開關只負責採集許可

statsUserUplinkstatsUserDownlink 以及 system 下的入站、出站統計欄位,用於允許核心記錄對應方向的流量資訊。開啟這些布林值不一定會自動出現可見圖表或介面數字,還需要設定受支援的統計模組與查詢方式。若用戶端沒有使用這些資料,單純開啟全部統計項目只會增加不必要的狀態維護。

不要將統計項目當作連線成功檢測。某個方向出現位元組變化,只表示曾有資料經過對應的計數範圍,無法單獨證明目標內容完整返回,也無法說明路由選擇符合預期。判斷連線品質仍應結合存取結果與錯誤日誌。用戶端介面顯示的流量統計可能來自系統介面、核心介面或自身計數,具體口徑未必與 policy 中每個開關完全一致。

多使用者等級需要明確的關聯關係

當設定包含多個使用者物件時,可以為使用者指定不同的 level,再於 policy 的 levels 中定義對應策略。等級鍵在 JSON 中以字串形式出現,例如 "0""1"。如果使用者引用了尚未設定的等級,核心可能採用預設行為或回報相關問題,具體取決於實作。維護時應將使用者等級與策略等級一起檢查,避免只複製其中一半。

一般用戶端出站通常不需要複雜的等級體系。節點訂閱提供的使用者身分主要用於遠端協定驗證,並不代表本機一定要為每個節點建立 policy 等級。只有作為入站服務、需要區分工作階段策略時,多等級才較常見。本頁聚焦於用戶端設定,因此建議保持單一預設等級,將精力放在入站安全、出站參數與路由可讀性上。

日誌等級與策略排查要互相配合

策略問題經常表現為「連線建立後又中斷」,需要日誌提供時間線。日常執行可使用 warning 等較克制的等級;排查期間再暫時提高詳細程度,並記錄開始時間與重現步驟。日誌路徑若寫入無權限的目錄,核心可能無法啟動或無法留下診斷資訊。圖形用戶端通常已處理日誌位置,手動設定獨立核心時才需要特別檢查檔案路徑。

重現後先比較三個時間點:連線開始、最後一次資料活動、連線關閉。若關閉時間緊接策略門檻,可調整一項後再次測試;若日誌明確顯示由遠端關閉或底層連線失敗,policy 並不是主要方向。完成除錯後恢復合理的日誌等級,並刪除僅為測試而開啟的統計項目,保持執行設定簡潔。

欄位 控制階段 不負責的事項
handshake 連線握手等待 網頁完整載入時間
connIdle 保留無資料活動的連線 網路速度限制
uplinkOnly 僅上行活動後的連線處理 上傳頻寬分配
downlinkOnly 僅下行活動後的連線處理 下載頻寬分配
statsInboundUplink 允許記錄入站上行統計 自動產生視覺化報告

07 / ASSEMBLY

組合完整設定與啟動前檢查

先建立最小閉環,再逐層增加功能

組合設定時,最可靠的順序是先建立最小閉環:一個只監聽本機的 SOCKS 入站、一個有效的代理出站、一個直連出站,以及少量方向明確的路由規則。最小設定能夠啟動並完成連線後,再增加 HTTP 入站、DNS 條件、阻擋規則與 policy。這樣每次新增的範圍有限,出現問題時可以直接回復到上一份可用設定。

完整檔案中的每個標籤都要形成引用閉環。routing 使用的 outboundTag 必須能在 outbounds 中找到;inboundTag 必須與 inbounds 的標籤一致;使用者 level 若關聯 policy,也要存在對應策略。標籤區分大小寫時,Proxyproxy 會被視為不同名稱。建議只使用小寫字母、數字與短橫線,減少輸入錯誤。

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": [
      "localhost"
    ],
    "queryStrategy": "UseIP"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-2222-4333-8444-555555555555",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "server.example.com"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  },
  "policy": {
    "levels": {
      "0": {
        "handshake": 4,
        "connIdle": 300
      }
    }
  }
}

範例完整不代表節點參數可以直接使用

上面的 JSON 層級完整,可用於理解各部分如何組合,但其中的伺服器網域與使用者 ID 是文件範例。實際設定必須替換為自己的訂閱或服務資訊中的完整參數,並讓 streamSettings 與遠端一致。如果實際節點使用的不是範例中的協定或傳輸方式,應替換整個代理出站物件,而不是只修改協定名稱。協定物件內部結構不同,僅修改一個字串會留下不相容欄位。

使用 v2rayN、v2rayNG 或 v2flyNG 時,優先匯入節點後觀察用戶端產生的出站結構,再將需要的路由思路套用到用戶端支援的位置。不要為了使用本文範例而放棄用戶端已正確產生的節點參數。設定參考的用途是解釋結構與協助排錯,不是讓每位使用者都從空白檔案手動寫出全部連線資訊。

執行語法檢查與核心設定檢查

第一層檢查可以使用支援 JSON 的編輯器確認括號、引號與逗號。第二層需要讓實際核心讀取設定。獨立執行 Xray 時,常見測試方式是執行 xray run -test -config config.json;獨立執行 V2Ray 時,可依目前可執行檔支援的命令使用 v2ray test -c config.json。命令名稱與參數應以本機核心的說明輸出為準,因為用戶端封裝方式與可執行檔位置可能不同。

圖形用戶端使用者通常不需要手動開啟終端機測試暫存設定。重新啟動核心後查看用戶端日誌即可。若用戶端在啟動前會重新產生檔案,應在它提供的編輯入口中儲存變更。測試結果回報未知欄位時,先確認目前使用的是 V2Fly 還是 Xray 核心,再檢查該欄位屬於頂層、入站設定、協定設定還是 streamSettings。將正確欄位放錯層級,同樣會被判定為無效。

依資料流進行啟動後的四段驗證

設定通過讀取後,還要驗證執行鏈路。第一段檢查入站:確認連接埠正在監聽,應用程式的代理類型與連接埠相符。第二段檢查路由:存取一個目標,查看日誌選擇的是 proxy 還是 direct。第三段檢查出站:觀察遠端連線與握手是否完成。第四段檢查目標回應:確認應用程式取得實際內容,而不只是建立了本機代理連線。

如果第一段失敗,重點查看連接埠占用與監聽位址;第二段錯誤,檢查規則順序、目標形式與標籤;第三段失敗,檢查節點、網路與傳輸參數;前三段正常但第四段異常,再查看 DNS、目標服務與應用程式自身行為。這種分段方法比不停更換節點更有效,也能避免將本機連接埠問題誤判為遠端故障。

用戶端覆寫設定時如何保留變更

v2rayN 在切換伺服器、更新訂閱或變更代理模式後,可能重新組織核心執行設定。需要長期保留的內容,應放進用戶端支援的自訂路由、DNS 或自訂設定功能,而不是只編輯執行目錄中的暫存 JSON。修改前先匯出或記錄目前設定,更新後再確認自訂規則仍被合併。首次安裝與設定檔位置相關的注意事項,可查看v2rayN 首次安裝與初始設定完整流程

Android 用戶端也可能將單節點設定、訂閱項目與執行設定分開儲存。編輯某個節點只會改變該節點的協定參數,不一定會改變全域路由。先確認目前頁面修改的是節點、路由還是應用程式設定,再進行測試。v2rayNG 首推使用 Xray 核心路徑,v2flyNG 則作為 v2fly 核心的備選;兩者擴充欄位存在差異時,不應直接互相複製完整 JSON。

08 / TROUBLESHOOTING

設定錯誤與連線故障排查

啟動立即失敗:先看第一個明確錯誤

核心啟動失敗時,日誌後面可能跟著多條連鎖訊息,真正原因通常出現在最早的一個明確錯誤附近。常見類型包括 JSON 解析失敗、未知欄位、資料型別不符、連接埠占用、檔案路徑無法存取,以及 routing 引用的標籤不存在。先處理第一處錯誤,再重新啟動;不要一次依據後續訊息修改多個區域,因為後續錯誤可能只是前一處失敗的結果。

JSON 解析錯誤通常會提供行號或字元位置。檢查該行前後是否少了逗號、多了尾逗號、引號未閉合,或複製時混入全形標點。錯誤位置有時指向解析器發現問題的地方,而真正遺漏的內容可能在上一行。若檔案很長,可以暫時移除最近新增的整個物件,確認基本設定恢復後,再逐層放回片段。

核心運作中但應用程式無法連線本機代理

這種情況先不要檢查遠端節點。確認應用程式代理位址是否為 127.0.0.1,連接埠是否與入站一致,代理類型是否相符。若使用系統代理,檢查用戶端是否已啟用相應模式;只啟動核心不一定會自動修改系統設定。瀏覽器擴充功能、應用程式內代理與系統代理同時存在時,可能形成重複代理或指向舊連接埠,測試時應保留一條清楚的路徑。

在 Windows、macOS 或 Linux 桌面環境中,連接埠被舊程序占用並不少見。退出用戶端後確認核心程序是否隨之結束,再重新開啟。若修改了入站連接埠,系統代理也要同步更新。Android 用戶端使用系統提供的網路介面接管應用程式流量,排查重點與桌面本機 SOCKS 連接埠不同,應先查看用戶端是否處於已連線狀態,以及執行日誌是否顯示核心成功啟動。

本機代理可連線,但遠端握手失敗

日誌出現連線遭拒、握手失敗或遠端提前關閉時,依「位址與連接埠 → 使用者身分 → 協定 → 傳輸 → 安全層」的順序檢查。網域能解析不代表連接埠對應正確服務,TCP 能建立也不代表 TLS 名稱與應用層傳輸一致。訂閱節點應先執行一次正常更新,確認目前項目沒有使用舊參數;手動節點則逐項與原始設定資訊比較。

系統時間明顯不正確會影響依賴時間的安全連線,應先讓裝置時間恢復正常。網路切換後若問題消失,表示還要檢查目前網路、DNS 或位址族,而不是只修改協定。節點逾時可以依節點逾時排查順序逐層驗證,避免跳過本地網路與系統時間,直接反覆修改出站物件。

只有部分網站或應用程式失敗

部分目標失敗通常表示基本入站與至少一個出站已可用,接下來應重點查看路由、DNS、UDP 與目標特徵。先比較成功目標與失敗目標分別使用哪個出站,再查看失敗項目進入核心時是網域還是 IP。如果錯誤規則將某個網域送往 direct,節點本身再正常也不會參與這次連線;如果 domainStrategy 觸發了不同的位址解析,結果也可能與預期的網域規則不一致。

應用程式的登入、語音、影片或同步功能可能使用不同網域、連接埠與網路類型。首頁能開啟,只能表示其中一部分請求成功。不要根據主頁結果將整個應用程式網域歸入一條過寬的規則。重現時記錄失敗功能對應的日誌目標,逐一補充必要條件。涉及 UDP 時,檢查 SOCKS 入站是否允許 UDP、代理協定與伺服器是否支援目前路徑,以及 routing 是否將 UDP 送往正確出口。

規則看似正確但始終未命中

先確認規則位置。前面是否存在更寬泛的 domain、IP、network 或 port 條件?其次確認目標形式:日誌看到的是完整網域、子網域、IP,還是透過 sniffing 還原的名稱?然後檢查比對前綴是否符合需求,full 不會自動涵蓋所有子網域,關鍵字又可能過寬。最後檢查 outboundTag 拼寫與目前執行檔案,避免修改的是備份檔,而用戶端實際載入的是另一份設定。

為了驗證某條規則,可以暫時將它移到前段,並將目標限制為一個明確網域。測試後查看日誌中的出站標籤。如果仍未命中,問題在目標形式或設定未載入;如果移到前段後命中,表示原本位置之前有規則攔截。確認原因後重新整理順序,不要長期依賴將所有新規則堆在最上方,否則具體規則之間也會逐漸互相覆蓋。

連線一段時間後中斷

先判斷中斷是否發生在固定時間間隔。若每次都接近 connIdle 或單向連線策略的時間,檢查 policy;若時間隨機,查看遠端重設、網路切換、裝置休眠與位址變化。筆記型電腦從一個網路切換到另一個網路後,舊連線失效是正常現象,用戶端通常需要重新建立鏈路。不要將一次睡眠喚醒後的中斷直接歸因於節點參數。

日誌中的 timeout、context canceled 或 connection reset 代表不同階段與觸發方,不能只看到「錯誤」就採用同一種處理方式。timeout 需要結合前一筆記錄判斷是 DNS、撥號還是握手;context canceled 可能來自上層請求主動結束;reset 表示連線被某一端重設。先找出時間線上最早的異常,再判斷後續錯誤是否只是取消與清理動作。

建立可重現的排查記錄

複雜設定最好保留一份簡短記錄,包含用戶端名稱、目前核心家族、入站連接埠、預設出站、最近修改區域與重現步驟。記錄不需要保存節點敏感資訊,只要能說明結構即可。每次測試寫下「修改了什麼、預期什麼、實際日誌是什麼」,兩三輪後通常就能排除大部分猜測。反覆切換多個選項卻不做記錄,容易在問題偶然消失後仍無法確認原因。

需要復原時,先回到最小可用設定,再逐項加入 DNS、分流與策略。如果最小設定仍然失敗,問題更可能位於用戶端安裝、本地網路或節點本身,可回到快速入門主線重新確認匯入與連線步驟。若只有自訂規則失敗,則保留已驗證的節點出站,集中檢查 routing 與目標日誌,不必重新安裝用戶端。

故障層級 典型現象 優先動作
JSON 與欄位 核心無法啟動 處理第一個解析或欄位錯誤,檢查最近的變更
入站 應用程式無法連線本機代理 核對位址、連接埠、協定類型與連接埠占用
路由 目標走錯出口或規則未命中 查看目標形式、規則順序與實際出站標籤
DNS 網域失敗或解析結果異常 確認查詢路徑、伺服器條件與位址族
出站 遠端拒絕、握手失敗或逾時 成套核對位址、身分、協定、傳輸與安全層
策略與工作階段 連線在固定閒置時間後中斷 對照 policy 門檻與日誌時間線
下載v2rayN