01 / STRUCTURE
JSON 結構與設定範圍
先分清用戶端設定與核心設定
V2Ray 生態系中的圖形化用戶端與代理核心負責不同工作。v2rayN、v2rayNG、v2flyNG 提供伺服器管理、訂閱更新、介面設定與啟動控制;核心則負責監聽連接埠、建立連線、比對路由及處理資料。介面上的一個切換選項,可能會產生多個 JSON 欄位,也可能只變更系統代理,並不寫入核心設定。因此,排錯時要先確認問題出在用戶端、作業系統還是核心,不能只憑介面文字推測實際行為。
用戶端通常會依據目前的伺服器與全域設定產生執行用設定檔。檔案可能位於工作目錄或暫存目錄,也可能在重新啟動後重新產生。直接編輯產生出的檔案,不一定能長期保留變更。若要持續生效,建議優先使用用戶端提供的路由、DNS 或自訂設定入口。入口名稱會依用戶端介面而異;判斷依據應是設定儲存後實際執行的設定,而不是磁碟上某個剛好名為 config.json 的檔案。
頂層物件與參照關係
基本設定以一個物件為根節點;inbounds 與 outbounds 是陣列,可定義多個入口與出口;routing、dns、policy 則是物件。入站將應用程式連線交給核心,路由決定連線使用哪個出站,出站則決定直接連線或經由遠端伺服器轉送。DNS 為需要解析的環節提供結果,策略則控制特定使用者等級的逾時或統計行為。這些並非互不相關的功能清單。
以下是一份可用於本機連線測試的完整基本設定:應用程式透過 SOCKS 入口連線,核心使用直連出站,不包含遠端代理伺服器。這份設定適合檢查監聽位址、連接埠及應用程式代理設定是否正確,不適合用來驗證遠端協定。執行前請確認連接埠未被占用,並使用所選核心支援的設定入口載入;在圖形化用戶端中,應使用自訂設定功能,而非將整份 JSON 貼到伺服器位址欄。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
語法正確不代表設定正確
嚴格 JSON 的鍵名與字串都必須使用雙引號;布林值寫作 true 或 false,陣列最後一個項目後方不能加逗號。連接埠通常是數字,不要為了格式一致而全部寫成字串。部分設定載入器允許註解或其他擴充語法,但複製到其他用戶端時,不一定也支援這些語法。本頁範例使用不含註解的 JSON,說明文字則放在程式碼區塊之外,方便分辨可解析內容與說明。
tag 是設定內部使用的參照名稱,不是協定名稱,也不必與介面上的伺服器備註相同。路由中的 outboundTag 必須對應實際出站;拼字、大小寫與連字號都必須一致。準備複雜設定時,先整理標籤之間的關係,再補上協定欄位。同一個物件內不要重複定義同名鍵;不同解析器處理重複鍵的方式可能不同,不能把重複鍵當成覆寫機制。
閱讀時可沿著連線流程逐步理解:先確認入口接收到什麼,再確認出口能否建立連線,接著處理路由與 DNS。不要一次加入所有章節的欄位。基本連線流程穩定後,每次只新增一個物件或一條規則,並記錄預期變化與實際結果。這樣的設定更容易復原,也能避免將語法錯誤、參照錯誤和網路問題混在同一輪測試中。
02 / INBOUNDS
inbounds:本機入站監聽
監聽位址決定可連入的範圍
inbounds 描述核心接收連線的入口。桌面用戶端常見 SOCKS 和 HTTP 代理入口,應用程式必須使用相符的協定,連線至指定位址與連接埠。listen 設為 127.0.0.1 時,只允許本機透過這個 IPv4 迴路位址存取。它不是伺服器位址,也不是遠端節點的出口位址。若僅供本機應用程式使用,維持迴路監聽通常更容易控管存取範圍。
將監聽位址改為 0.0.0.0,表示監聽所有本機 IPv4 網路介面;這不代表所有系統防火牆規則都已開啟,也不保證網路中的其他裝置一定能連上該連接埠。若確實需要讓區域網路裝置連入,還要檢查裝置位址、防火牆入站規則、網路隔離及驗證設定。迴路位址指的是發起存取的裝置本身;手機要使用電腦代理時,不能用手機上的迴路位址代替電腦的區域網路位址。
SOCKS 與 HTTP 入口的用途
以下片段用來替換基本設定中的 inbounds 陣列。兩個入口使用不同的連接埠與標籤,出站和路由沿用原設定。SOCKS 入口已啟用 UDP 支援,但應用程式仍須透過相應機制發出 UDP 代理請求;HTTP 入口則適合只提供 HTTP 代理設定的應用程式。兩個入口同時存在,不代表同一個應用程式會自動在兩者之間切換。
[
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
},
{
"tag": "local-http",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
| 欄位 | 用途 | 檢查重點 |
|---|---|---|
listen | 本機監聽位址 | 迴路與區域網路存取範圍 |
port | 監聽連接埠 | 是否被占用、呼叫端設定是否一致 |
protocol | 入口協定 | 勿混用 SOCKS 與 HTTP |
tag | 入口標籤 | 供路由參照的入站條件 |
sniffing | 協定與目標資訊探測 | 是否確實需要比對網域 |
嗅探不能取代 DNS
sniffing 可從部分連線的協定內容中擷取網域線索,例如 HTTP 主機名稱或 TLS 交握中的伺服器名稱。但它無法保證還原每條連線原本的網域,也不會解密應用程式內容。啟用後的目標處理方式還取決於核心支援的具體欄位,因此不能簡單將「啟用嗅探」理解為「所有網域規則都會命中」。遇到只剩 IP 位址的連線時,應先檢查應用程式如何完成解析。
destOverride 指定可用於目標覆寫的協定類型。目標覆寫和僅供路由判斷的行為並不完全相同;部分核心提供額外欄位控制這點,不能將擴充欄位直接套用到所有核心。若服務依賴原始目的位址,或同一個 IP 上有特殊連線邏輯,變更嗅探設定後應個別驗證。沒有明確需求時,先使用最少的探測類型,避免無目的地增加設定變數。
連接埠、系統代理與流量接管方式
連接埠占用錯誤發生在監聽階段,與遠端伺服器是否上線無關。處理時先關閉重複執行的用戶端,確認目前使用該連接埠的程序,再決定是否更換。修改入站連接埠後,也要同步修改瀏覽器、開發工具和系統代理中的對應連接埠。若只修改核心,卻保留舊的系統代理位址,應用程式就會連線遭拒;此時反覆更新訂閱並無法解決問題。
系統代理只是告知遵循系統設定的應用程式使用某個代理入口,不保證所有應用程式的流量都會經過核心。TUN 類型的流量接管還涉及虛擬介面、系統路由與權限,不能以新增 SOCKS 入站取代。Android 用戶端的系統流量接管,也由用戶端與平台機制共同完成。要確認流量是否進入核心,應查看實際連線記錄,而不是只檢查介面上的系統代理開關。
驗證入口時,固定使用一個測試應用程式和一個已知可連線的目標;先觀察是否產生連線,再確認是否選擇預期的出站。若沒有任何連線記錄,請優先檢查應用程式是否使用代理、位址與協定是否正確,以及是否仍使用快取的舊設定;若已有連線記錄,排查範圍就應轉向出站與路由。首次設定的操作順序可參考v2rayN 初次設定重點。
03 / OUTBOUNDS
outbounds:出站協定與標籤
出站描述下一跳連線
outbounds 決定核心如何處理已接收的連線。freedom 表示直接連線至目標,blackhole 用於阻擋連線,VLESS 等代理協定則會將連線交給設定中的遠端伺服器。出站不是一條具體的路由規則:多條規則可以參照同一個出站,單一規則也可以比對多個網域後,統一選擇同一個出口。如此一來,協定參數與流量分類便能分開維護。
未命中路由規則時,一般設定會使用出站陣列的第一個項目作為預設出口,因此陣列順序具有實際意義。將 direct 放在第一個位置,不只是調整顯示順序,也可能改變所有未命中流量的處理方式。設定時應先決定預設行為,再新增例外規則。若預設要走代理,就將可用的代理出站放在前面;若預設要直連,則明確保留直連出站為第一個項目。
直連與阻擋可分開測試
以下陣列可用於直連與阻擋測試,替換基本設定中的 outbounds 即可。兩個標籤可供路由參照,預設仍是第一個項目的直連出站。blackhole 是會主動丟棄連線的出站,不是備援線路,也不會自動尋找其他可用伺服器。若將它用於某個測試網域,應用程式連線失敗是預期結果;請搭配路由記錄確認規則是否命中,不要因此判定整個用戶端故障。
[
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
VLESS 參數必須與伺服器一致
以下是 VLESS 出站物件的結構範例,並非可直接連線的公開伺服器。your-server.example 是教學用網域,範例 UUID 也只用來展示格式;實際使用時,必須替換成有效且獲授權使用的伺服器參數。此物件包含 TCP 與 TLS 設定,遠端伺服器也必須支援相同組合。將它加入陣列,不會讓既有的其他協定伺服器自動接受 VLESS 連線。
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "your-server.example",
"port": 443,
"users": [
{
"id": "00000000-0000-4000-8000-000000000001",
"encryption": "none",
"level": 0
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "your-server.example",
"allowInsecure": false
}
}
}
address 是伺服器連線位址,port 是伺服器監聽連接埠,id 是協定使用者識別碼。VLESS 使用者物件中的 encryption 與傳輸安全層不是同一項設定;設為 none 不代表外層 TLS 已關閉。傳輸安全由 streamSettings.security 等欄位決定。不要把名稱相近的「加密」選項混為一談,否則容易遇到協定雖可匯入、卻無法建立連線的情況。
使用者物件中的 level 可與 policy.levels 建立關聯;它不是節點優先順序,也不會控制路由規則順序。flow 等擴充參數,只有在伺服器、核心與傳輸組合都支援時才應使用;不能只因匯入連結中出現某個值,就替所有伺服器一律加上。匯入後應核對位址、連接埠、使用者識別碼、傳輸方式與安全層,並特別留意用戶端是否提示未知欄位。
分開判斷協定與用戶端選擇
用戶端名稱不等於協定支援清單。桌面版建議優先使用 v2rayN;Android 可依實際核心需求選擇 v2rayNG 或 v2flyNG。某項擴充功能能否使用,最終取決於目前的核心與設定組合,而不是用戶端備註中是否出現該協定名稱。選擇時可參考三款用戶端的核心差異,安裝檔則統一由下載頁面取得。
出站故障可分為伺服器無法連線、協定驗證失敗與傳輸交握失敗三類。位址或連接埠錯誤通常發生在建立底層連線時;使用者識別碼不符則發生在協定處理階段;TLS 名稱錯誤則屬於安全層問題。先根據記錄確認失敗階段,再核對對應欄位。若一次同時更換位址、使用者識別碼與傳輸方式,即使恢復連線,也無法確認真正原因,不利於日後維護。
04 / STREAM SETTINGS
傳輸方式與 TLS 安全層
分開理解協定、傳輸與安全層
代理協定說明雙方如何組成代理請求,傳輸方式說明資料透過什麼通道承載,安全層則處理交握、身分驗證與加密連線。三者通常會一同出現在出站物件中,但不能任意搭配。介面上同為 VLESS 的兩台伺服器,可能要求不同的傳輸方式與安全層;若將其中一台的傳輸參數複製到另一台,可能在協定驗證之前就失敗。
streamSettings.network 用來選擇傳輸類型,對應的設定物件則會繼續描述具體參數。TCP 的結構相對直接;WebSocket 通常還需要路徑,也可能涉及 HTTP 主機名稱。若遠端經過反向代理,公開連接埠與路徑會由伺服器部署方式共同決定。用戶端填入的每個值都應有伺服器端的依據,不能靠隨意嘗試常見路徑來代替核對參數。
WebSocket 範例的欄位分層
以下物件用來說明常見的 WebSocket 與 TLS 組合,應替換出站中的整個 streamSettings,不能替換頂層設定。網域與路徑都是教學範例。address 仍位於協定的伺服器物件中,用來決定實際連線目的地;此處的主機名稱、伺服器名稱與路徑則用於上層交握。實際部署若要求不同值,應逐項填寫,不能假設三者永遠相同。
{
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "your-server.example",
"allowInsecure": false
},
"wsSettings": {
"path": "/proxy",
"headers": {
"Host": "your-server.example"
}
}
}
| 欄位 | 所在層級 | 用途 |
|---|---|---|
address | 協定伺服器物件 | 決定底層連線目標 |
serverName | TLS 設定 | 伺服器名稱與憑證名稱驗證 |
Host | WebSocket 要求標頭 | 選擇 HTTP 虛擬主機 |
path | WebSocket 設定 | 符合伺服器端要求路徑 |
security | 傳輸設定 | 選擇傳輸安全層 |
憑證錯誤先檢查名稱與效期
TLS 連線需要驗證憑證適用的名稱與有效期限。系統時間明顯不準、伺服器名稱與憑證不符、憑證鏈部署不完整,都可能導致交握失敗。使用 IP 位址連線時,若憑證是簽發給網域,仍須依伺服器端要求填入正確的伺服器名稱。不要將伺服器位址、HTTP 主機名稱與憑證名稱視為可以互換的同義欄位;它們可能剛好相同,但用途不同。
allowInsecure 控制是否略過憑證驗證中的部分檢查,並非修復憑證部署的選項。本頁範例維持 false。發生憑證錯誤時,先同步系統時間,再核對伺服器名稱、憑證涵蓋範圍與伺服器端憑證鏈。長期停用驗證會改變連線的身分驗證條件,也可能掩蓋名稱填寫錯誤。排錯步驟可參考TLS 交握與憑證錯誤說明。
擴充欄位與連線多工的適用範圍
REALITY 是特定核心支援的安全層方案,不能視為一般 TLS 設定的別稱。伺服器名稱、公鑰及其他配套參數須依實際伺服器要求成組填寫,不能只修改 security 字串。同樣地,部分傳輸名稱與擴充設定在不同核心之間也有差異。遷移設定前,先確認實作方式與支援範圍;若出現未知欄位提示,不要只刪除提示欄位後,就假設行為仍然相同。
Mux 多工會在特定條件下重用底層連線;它不是分流功能,也無法修正協定參數。是否適合啟用,取決於協定、伺服器支援情況、應用程式的連線模式及目前核心的限制。排查單一連線失敗時,先關閉多工並確認基本連線穩定,再單獨測試。不要將多工與傳輸層本身已有的多工能力混為一談,也不要同時變更多工、DNS 和路由後再比較結果。
排查傳輸時,固定使用同一台伺服器與同一個測試目標,依序檢查底層連線、TLS 交握、傳輸交握與代理請求。連線逾時通常應先檢查位址與可達性;若已收到憑證錯誤,就應檢查名稱與憑證;若 WebSocket 路徑不符,則需檢查請求轉送規則。記錄提供的是失敗階段的線索,不是完整結論;必須搭配伺服器參數與用戶端實際產生的設定交叉確認。
05 / ROUTING
routing:規則比對與出口選擇
規則順序與預設出口比規則數量重要
routing.rules 會依設定順序檢查規則,命中後通常就使用該規則指定的出口,不會為了尋找「更精確」的網域而繼續往下比對。若將範圍寬泛的規則放在前面,後面的細分規則可能永遠不會命中。維護規則時,先寫明確的特殊例外,再寫範圍較大的分類,最後保留清楚的預設出口。規則多不代表涵蓋範圍正確,順序混亂反而會增加理解難度。
同一條規則中的多個不同條件欄位通常必須同時成立;同一條件陣列中的多個候選值,則表示該欄位可比對其中任一值。例如同時設定 inboundTag 與 domain,代表連線必須來自指定入口,且目標網域也符合條件,而不是任一條件成立即可。若要表達兩組各自獨立的例外,通常拆成兩條規則會更容易檢查。
網域策略與網域比對是不同設定
domainStrategy 決定路由比對時何時為網域取得 IP 位址。AsIs 保留目標原有形式;IPIfNonMatch 會在網域未命中時嘗試解析,再比對 IP 規則;IPOnDemand 則會在比對過程需要 IP 資訊時觸發解析。它不會強制所有應用程式使用 DNS,也無法憑空還原應用程式已解析掉的原始網域。選擇策略時,也要考量輸入目標的實際形式。
以下物件可用來替換頂層的 routing,前提是出站中已定義 direct。私有位址使用一般 IP 網段表示,方便理解比對條件;網域例外則使用保留的範例網域。未命中時仍會回到第一個出站,因此若基本設定只有直連出站,整個範例就不會產生代理出口。若要採用其他預設行為,必須同時設定實際可用的對應出站。
{
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"full:example.com",
"domain:example.org"
],
"outboundTag": "direct"
}
]
}
比對前綴決定涵蓋範圍
full:example.com 用於完整網域比對;domain:example.org 用於該網域及其子網域;regexp: 用來指定正規表示式,須留意 JSON 字串中的反斜線跳脫。沒有前綴的字串可能採用核心定義的關鍵字比對方式,不適合在範圍不明時取代完整網域比對。若要精確控制單一主機,優先使用語意明確的前綴,再依實際請求補上子網域。
geosite: 參照網域分類資源,geoip: 參照 IP 分類資源,例如常見的 geosite:cn 與 geoip:private。它們不是線上自動查詢指令;執行環境必須提供相符的資料檔案,且檔案中包含對應分類。分類名稱、資料內容與更新狀態都可能影響比對結果。若找不到分類或載入規則失敗,應檢查資源與核心,而不是將錯誤歸咎於目標網站。
從請求條件反推規則
除錯時記錄入口標籤、目標是網域或 IP、目標連接埠及預期出口,再從第一條規則開始逐項檢查。若網域規則未命中,先確認核心是否取得網域;若 IP 規則未命中,再檢查解析時機、回傳的位址類型與網段範圍。沒有證據時不要直接新增範圍寬泛的規則,因為它可能暫時掩蓋問題,卻同時改變其他連線的出口。
修改規則只會影響新連線的選擇;既有的長連線可能繼續沿用原本路徑。測試前應關閉測試應用程式中的相關連線,或重新發出請求,以免將舊連線的結果誤認為規則未生效。更完整的語法與順序範例請見自訂路由規則寫法;查詢術語時,可前往術語表了解網域分類、位址網段與出口標籤的差異。
06 / DNS
dns:解析來源與查詢路徑
先確認由誰發起解析
一次應用程式請求可能涉及多處解析:應用程式自行解析目標網域、作業系統解析伺服器位址、核心為路由比對解析目標,或由出站在建立連線時要求解析。頂層 dns 只會影響使用內建解析器的相關環節,不會自動接管所有應用程式的 DNS 請求。瀏覽器或其他應用程式若使用獨立的加密解析功能,也可能採用自己的連線路徑;不能只修改核心 DNS,就推斷它們的行為已改變。
排錯前先說明問題對象:是代理伺服器的網域無法解析,還是目標網站的網域無法解析;是解析失敗,還是已取得位址但無法連線;是系統解析異常,還是只有路由比對階段出問題。這些情況需要檢查不同設定。伺服器網域解析是建立代理連線前的必要條件;目標網域則可能在本機或遠端解析,不能將兩者一概歸納為「DNS 無法連線」。
hosts、servers 與位址類型
以下是頂層 dns 的結構範例。hosts 為教學網域指定文件用途的位址,用來說明靜態對應格式,並非可連線的服務。兩個數值型解析器位址用來展示伺服器陣列的寫法;實際設定時,應選擇目前網路可連線且符合需求的解析服務。將這個物件加入設定後,還需要有會呼叫內建解析器的相關行為,才能觀察它的作用。
{
"hosts": {
"example.test": "192.0.2.10"
},
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"queryStrategy": "UseIP"
}
hosts 適合用於明確且穩定的對應,不適合長期硬編碼經常變動的服務位址。目標可能使用多個位址、依地區調度,或調整憑證與服務入口;過期對應會繞過正常解析結果。排錯完成後應移除暫時對應,並檢查系統 hosts 檔案或用戶端其他 DNS 設定是否仍有覆寫。否則即使更換了解析伺服器,請求仍可能繼續使用舊的靜態結果。
queryStrategy 控制查詢的位址類型,常見值包括 UseIP、UseIPv4 與 UseIPv6;實際支援情況依目前核心而定。它不是用來啟用或停用作業系統 IPv6 的開關。網路沒有可用的 IPv6 路徑時,取得 IPv6 位址不代表能成功建立 IPv6 連線;同樣地,只查詢 IPv4 也無法修復代理伺服器本身的連線問題。先確認位址類型與路由實際可用,再調整查詢範圍。
DNS 查詢流量也有出口相依性
核心發出的 DNS 查詢經由哪個路徑傳送,取決於解析器類型、核心實作及相關路由設定。一般遠端查詢、系統解析呼叫,以及某些具有本機語意的解析方式,不保證會經過同一套分流機制。設定加密 DNS 時,還會增加解析器主機名稱、TLS 名稱與連線可達性等相依條件。僅憑位址採用加密查詢格式,無法判定查詢最後會從哪個出口離開。
特別要避免循環相依:代理伺服器使用網域,但解析該網域的查詢又被要求經由尚未建立的同一代理;或加密解析器的網域只能由該解析器本身解析。解決方式是在啟動階段提供可連線的解析路徑,必要時使用明確的引導解析或伺服器端認可的連線位址。不要直接將所有 DNS 相關位址都指向代理出口,再期待核心自動解開相依循環。
| 現象 | 優先檢查 | 不要直接推斷 |
|---|---|---|
| 伺服器網域解析失敗 | 啟動解析路徑、系統網路 | 目標網站的路由錯誤 |
| 網域可解析但連線逾時 | 回傳位址、位址類型與出口 | 解析伺服器一定故障 |
| 修改後仍回傳舊位址 | 應用程式、系統與核心快取 | 新設定未儲存 |
| 只有部分應用程式異常 | 應用程式本身的解析與代理設定 | 所有流量使用同一個 DNS |
同時驗證快取與分流
DNS 快取可能存在於應用程式、系統、核心與上游解析器。調整設定後,即使重新啟動核心,應用程式仍可能重用快取或舊連線。測試時固定使用一個網域,記錄回傳位址與連線出口,再逐一確認快取來源。不要同時清除所有設定並更換多個解析器,否則前後結果將失去可比較性。對於有多個位址的服務,單次查詢結果不同也不一定代表設定不穩定。
網域規則與 IP 規則並存時,應將 DNS 視為路由的輸入來源,而不是獨立的最佳化開關。網域先命中規則時,可能不需要本機解析;進入 IP 比對後,解析結果又可能改變出口選擇。因此設計分流時,應同時說明「何時解析」以及「解析後如何比對」。若只是要修正單一網域的異常,先進行局部測試,再決定是否套用到全域設定。
07 / POLICY & LOG
policy:連線策略、記錄與統計
使用者等級是策略索引
policy 用來定義連線處理與統計相關策略。levels 以使用者等級作為索引,協定使用者物件中的 level 可與相應策略建立關聯。這個等級不是帳戶權限排名,不代表伺服器效能,也不會控制路由優先順序。只有在特定協定與連線使用相應等級時,相關設定才會發揮預期作用;替未被參照的等級填入參數,不會自動改變所有連線。
在 JSON 物件中,等級鍵會寫成字串,例如 "0";協定使用者的等級欄位則通常是數字。兩者名稱相似,但所在位置與資料類型不同。管理多個等級時,應記錄每個等級的使用對象與調整目的,避免只留下難以說明的一組數字。多數一般用戶端情境不需要頻繁修改策略;維持預設行為,比套用來源不明的「通用最佳化參數」更容易排錯。
不同逾時欄位作用於不同階段
以下物件展示常見策略欄位,可供頂層 policy 參考。數值單位為秒,代表範例策略,不是通用建議。handshake 控制相應交握階段的時間限制;connIdle 與閒置連線有關;uplinkOnly 和 downlinkOnly 則處理僅單向仍有活動的階段。它們不能一概視為同一個總連線逾時,實際生效位置也會受協定實作影響。
{
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
閒置策略設得太短,可能讓互動式終端、通知連線或暫時沒有資料的工作階段更常重新建立;設得太長,則可能讓無用連線保留更久。應用程式本身也有心跳、讀寫逾時與重新連線機制,因此觀察到定期中斷時,應同時比對應用程式設定與核心記錄。不要只因中斷間隔接近某個策略數值,就認定已找到原因;網路設備與遠端服務也可能有各自的逾時限制。
交握失敗時,應先檢查協定、位址與安全層參數,而不是立即延長交握時間。參數不符不會因為多等一會兒就變正確;若網路環境確實較慢,適度增加時間限制可能有幫助,但應以可重複的測試結果為依據。調整時一次只變更一個欄位,並記錄開始交握的時間與錯誤階段。若故障發生在傳輸交握之前,修改應用程式資料階段的閒置策略通常無濟於事。
記錄等級決定記錄詳細程度
記錄設定位於頂層 log,不在 policy 之內。日常可使用 warning;需要定位問題時,再短暫改為 info 或更詳細的等級。以下物件只設定記錄詳細程度,輸出位置則由用戶端與核心的執行方式決定。若未指定磁碟路徑,不要假設記錄已儲存在某個固定目錄;請先查看用戶端的記錄面板,或其明確提供的記錄檔入口。
{
"loglevel": "warning"
}
連線記錄可能包含目標網域、IP、入口標籤與錯誤原因。公開排錯資訊前,應移除訂閱網址、使用者識別碼及個人路徑等不必要內容。若要保留排錯價值,可用一致的範例標籤取代敏感名稱,但應保留錯誤階段、欄位類型及標籤之間的參照關係。只截取一行「連線失敗」通常不足以說明問題,前後的初始化與交握資訊也很重要。
統計開關不等於統計介面
策略中的統計開關代表是否收集相應計數,不會憑空產生用戶端圖表。要讀取統計資料,還需要核心統計功能、介面與用戶端支援等配套設定。部分使用者統計依賴協定使用者的識別資訊;啟用系統統計不代表就能自動取得每個應用程式或每台伺服器的獨立資料。若只是要定位連線失敗,通常先查看記錄即可,不必為此額外啟用整套介面。
記錄與統計是觀察工具,不是連線成功的必要條件。錯誤調整策略可能讓問題更複雜,沒有圖表也不代表代理未執行。設定完成後先驗證實際請求,再依維護需求選擇記錄詳細程度。若用戶端已提供統計功能,優先使用既有入口,避免重複開放不需要的管理介面。詳細記錄完成後,請恢復日常記錄等級,並清理不再需要的暫存診斷檔案。
08 / APPLY & DIAGNOSE
設定套用、訂閱管理與分層排錯
先建立可復原的修改流程
套用新設定前,先儲存目前可正常運作的用戶端設定與自訂設定副本,並記錄這次修改涉及的欄位及預期行為。備份應放在自己能辨識的位置,不要與用戶端的暫存執行檔案混用。復原時也要考慮伺服器選擇、系統代理、路由模式與 DNS 設定;只還原一段 JSON 不一定能恢復完整的用戶端狀態。單次修改的範圍越明確,復原就越可靠。
設定的實際來源可能分成多層:訂閱提供伺服器參數,用戶端全域設定提供入口與路由範本,自訂設定則可能覆寫部分欄位。排錯時請確認目前啟動的是一般伺服器設定還是完整自訂設定,以及哪個入口具有最終決定權。若啟動模式不同,同一個介面選項可能不再影響執行結果。不要反覆修改未使用的自訂檔案,卻誤以為核心沒有讀取設定。
訂閱不等於完整的執行設定
訂閱通常用於分發伺服器項目或分享資訊,不保證包含本機監聽、系統代理、路由與 DNS 的完整策略。更新訂閱後,伺服器名稱、位址與選用參數可能變更;本機自訂分流是否保留則取決於用戶端實作。訂閱網址也應視為需要妥善保管的資訊,不要放進公開截圖、文章或故障討論中。匯入成功只代表用戶端讀取了內容,不代表每項伺服器參數都適用。
在多台裝置間同步時,應區分共用的伺服器來源與各裝置的設定。電腦和手機可使用同一份合法訂閱,但監聽連接埠、系統流量接管方式與網路權限不必相同。不宜將整份桌面版執行設定直接覆寫到行動裝置用戶端。若要移轉,先同步伺服器項目,再依裝置分別檢查入口、路由與 DNS;操作方式可參考訂閱、分享連結與設定匯出的同步說明。
依連線階段定位故障
第一階段檢查設定載入與啟動。若出現 JSON 解析錯誤,先檢查附近的引號、逗號與括號;若提示不支援欄位,請檢查核心與欄位所屬位置;若提示監聽失敗,則檢查連接埠占用與權限。這些問題都發生在實際代理請求之前,暫時不需要調整遠端伺服器。修正後確認核心仍在執行,再進入下一階段;避免程序已退出時還進行網路測試。
第二階段檢查請求是否進入核心。選擇一個明確設定為使用代理的測試應用程式,重新發起連線並查看記錄。若沒有記錄,核對應用程式的代理協定、迴路位址與連接埠,並檢查系統代理是否仍指向舊入口。若已有記錄但出口不符預期,則檢查路由順序、入口標籤與目標形式。此時反覆重新安裝用戶端,通常無法取代對實際請求路徑的確認。
| 階段 | 常見現象 | 優先檢查 |
|---|---|---|
| 載入設定 | 啟動後立即結束 | JSON、欄位支援、標籤參照 |
| 監聽入口 | 連接埠繫結失敗 | 重複程序、位址、權限 |
| 應用程式連入 | 沒有請求記錄 | 應用程式代理與系統流量接管 |
| 選擇出口 | 命中非預期出站 | 規則順序、目標形式、預設出口 |
| 建立遠端連線 | 逾時或交握錯誤 | 伺服器位址、協定、傳輸安全 |
| 連線至目標 | 只有部分服務異常 | DNS、位址類型、目標規則與應用程式行為 |
第三階段檢查遠端伺服器與目標。無法連上伺服器時,核對位址、連接埠與啟動解析;交握失敗時,核對協定使用者、傳輸路徑及憑證名稱;若已連上伺服器但只有部分目標異常,再檢查目標 DNS、規則與位址類型。至少使用兩個目標,區分單一服務故障與全域設定問題,但每輪測試都應維持其他變數不變。一次成功只能證明目前路徑可用,不足以證明所有規則都符合預期。
修改後的驗收與清理
驗收至少涵蓋本機入口、預設出口、明確的直連例外,以及一項預期會遭阻擋的測試條件;若沒有設定阻擋規則,就不必為驗收額外新增。每項檢查都應寫明輸入條件與預期出口,並透過新連線驗證。長連線與快取可能保留舊結果,因此應重新建立測試工作階段。確認設定已儲存後,再透過用戶端正常重新啟動一次,檢查執行中的設定是否仍與修改內容一致。
最後恢復日常記錄等級,移除暫時的 hosts 對應與實驗規則,並保留簡短的變更記錄。首次使用者仍應回到快速入門說明完成用戶端操作流程;查閱欄位時則依本頁目錄逐段確認。維護設定的重點不是累積更多開關,而是讓入口、解析、路由與出口之間的關係始終說得清楚、驗證得到,並能在故障時準確復原。