跳至主要内容

Xray JSON – Advanced

概述

在 Remnawave 中,XRAY_JSON 類型的訂閱範本提供了 Remnawave 指令 — 這些是您新增到 JSON 範本中的特殊指令。面板在產生訂閱時會處理它們,並從最終設定中移除 — 用戶端永遠不會看到它們。

目前可用的指令是 injectHosts,允許將主機的 outbound 設定動態注入到範本中。當您需要建構帶有負載均衡器、自訂路由或多個 outbound 的複雜 Xray 設定時,這非常有用,而連線資料(位址、端口、金鑰)將從面板自動注入。

提示

以下呈現的設定是用於演示注入機制的範例。請根據您的需求進行調整。

注意

需要 Remnawave 版本 2.6.3 或更高版本。

工作條件

  • 虛擬主機(分配了注入範本的主機)必須已啟用未隱藏
  • 注入主機(透過 selector 選擇的主機)必須已啟用。預設情況下,只選擇隱藏的主機(可透過 selectFrom 變更此行為)。
  • 所有主機 — 包括虛擬主機和注入主機 — 必須對最終使用者可存取:它們繫結的 inbound 必須在使用者的小隊中啟用。
  • 備註 (remark) 和伺服器描述 (Server Description,如果設定了) 將從虛擬主機傳入最終設定。

remnawave 結構

remnawave 物件新增到 JSON 範本的根層級。它支援以下欄位:

欄位描述
injectHosts注入組陣列。每個組包含用於選擇主機的選擇器和標籤形成參數。
addVirtualHostAsOutbound如果為 true — 虛擬主機將作為帶有 proxy 標籤的 outbound 新增到 outbounds 陣列的開頭。預設為 false。參見 addVirtualHostAsOutbound

injectHosts 欄位是注入組的陣列。每個組包含用於選擇主機的選擇器和自己的 tagPrefix

"remnawave": {
"injectHosts": [
{
"selector": { "type": "uuids", "values": ["uuid-хоста-1", "uuid-хоста-2"] },
"tagPrefix": "proxy"
},
{
"selector": { "type": "remarkRegex", "pattern": "^RU-" },
"tagPrefix": "backup"
}
]
},

injectHosts 陣列的每個元素:

欄位描述
selector定義將選擇哪些主機的物件。必填欄位。
selectFrom從哪個主機池中選擇:"HIDDEN"(預設)、"NOT_HIDDEN""ALL"
tagPrefix建立的 outbound 的標籤前綴。參見標籤形成規則
useHostRemarkAsTag如果為 true — outbound 的標籤將是主機的備註 (remark)。
useHostTagAsTag如果為 true — outbound 的標籤將是主機標籤(如果標籤未設定,則使用備註)。
注意

必須指定三個欄位中的恰好一個tagPrefixuseHostRemarkAsTaguseHostTagAsTag

可以有任意數量的組 — 每個組形成帶有自己前綴的獨立 outbound 集合。例如,這允許為每組伺服器設定單獨的負載均衡器。

選擇器類型

uuids

透過 UUID 清單選擇主機。UUID 的順序決定 outbound 的順序。

"selector": {
"type": "uuids",
"values": [
"8478b271-95d3-4312-85ae-ecf63fb53d1d",
"d31d6161-1315-4c1e-9a4b-141ab1c022f6"
]
}

remarkRegex

選擇備註 (remark) 與正規表示式匹配的主機。語法為 JavaScript RegExp。

"selector": {
"type": "remarkRegex",
"pattern": "^Балансер"
}

上面的範例將選擇所有備註以 "Балансер" 開頭的隱藏主機(例如 "Балансер #1"、"Балансер RU")。

tagRegex

選擇主機標籤(主機設定中的 tag 欄位)與正規表示式匹配的主機。

"selector": {
"type": "tagRegex",
"pattern": "^balancer-"
}

上面的範例將選擇所有標籤以 balancer- 開頭的隱藏主機。

sameTagAsRecipient

選擇所有主機標籤與虛擬主機標籤匹配的隱藏主機。不需要額外參數。

"selector": {
"type": "sameTagAsRecipient"
}

當您想自動對主機進行分組時很方便:只需為虛擬主機和注入主機分配相同的標籤即可。

提示

預設情況下,所有選擇器只處理隱藏的主機。要變更此行為,請使用 selectFrom 欄位:"NOT_HIDDEN" 值只選擇可見的主機(已啟用但未隱藏),"ALL" — 所有主機(已啟用,已隱藏)。

標籤形成規則

outbound 的標籤由注入組中指定的三個欄位中的哪一個決定:

tagPrefix — 第一個主機獲得等於 tagPrefix 的標籤。此後每個主機獲得 {tagPrefix}-{N},從 2 開始。

三個主機使用 tagPrefix: "proxy" 的範例:

順序outbound 標籤
第1個proxy
第2個proxy-2
第3個proxy-3

useHostRemarkAsTag — 每個 outbound 獲得等於主機備註 (remark) 的標籤。

{
"selector": { "type": "tagRegex", "pattern": "^ru-" },
"useHostRemarkAsTag": true
}

如果主機的備註是"莫斯科"、"聖彼得堡"、"喀山" — outbound 將獲得 莫斯科聖彼得堡喀山 標籤。

useHostTagAsTag — 每個 outbound 獲得等於主機標籤的標籤。如果主機標籤未設定,則使用其備註。

{
"selector": { "type": "tagRegex", "pattern": "^ru-" },
"useHostTagAsTag": true
}

Xray 中的前綴匹配

Xray 中的 selector(在 routing.balancers 中)和 subjectSelector(在 burstObservatory 中)欄位作為前綴匹配器工作 — 它們與 outbound 標籤的開頭匹配,而不是與其精確值匹配。

例如,如果設定中有標籤為 proxyproxy-2proxy-3direct 的 outbound:

selector / subjectSelector 值將選擇哪些 outbound
["proxy"]proxyproxy-2proxy-3
["proxy-"]proxy-2proxy-3
  • "selector": ["proxy"] — 將捕獲所有注入的 outbound,包括第一個。
  • "selector": ["proxy-"] — 將捕獲除第一個之外的所有(僅 proxy-2proxy-3、...)。
透過第一個主機的回退

第一個選擇的主機始終獲得沒有 -{N} 後綴的標籤(簡單地為 proxy)。這允許將其用作負載均衡器中的 fallbackTag:如果 selector 中的所有 outbound 都不可用,流量將轉到第一個主機。為此,設定 "selector": ["proxy-"](僅 proxy-2proxy-3、...)和 "fallbackTag": "proxy"

addVirtualHostAsOutbound

預設情況下,使用 remnawave 指令時,最終設定中出現注入的主機。虛擬主機本身(recipient)僅用作 remarksserverDescription 的來源。

如果您需要虛擬主機也成為帶有 proxy 標籤的 outbound,請在 remnawave 物件層級新增欄位 addVirtualHostAsOutbound: true

"remnawave": {
"addVirtualHostAsOutbound": true,
"injectHosts": [
{
"selector": { "type": "uuids", "values": ["uuid-хоста-1", "uuid-хоста-2"] },
"tagPrefix": "proxy"
},
{
"selector": { "type": "remarkRegex", "pattern": "^RU-" },
"tagPrefix": "backup"
}
]
}

在這種情況下,最終 outbounds 陣列將如下所示:

  1. 帶有 proxy 標籤的虛擬主機 Outbound
  2. 注入的 outbound(來自 injectHosts)。
  3. 範本中的靜態 outbounddirectblock 等)。

當路由規則使用 "outboundTag": "proxy" 透過主要主機路由流量,而注入的主機處理單獨的流量組(例如,透過負載均衡器)時,這很有用。

提示

addVirtualHostAsOutbound 可以與 injectHosts 一起使用,也可以不使用。如果 injectHosts 未指定或為空,則只有虛擬主機的 outbound 會被新增到設定中。

分步範例:帶三個主機的負載均衡器

在此範例中,我們將建立一個設定,其中三個 outbound 使用 leastLoad 策略組合成負載均衡器,並由 Observatory 監控。

步驟 1. 建立主機

在面板中建立將參與注入的主機。在我們的範例中:

  • Virtual Host — 將分配注入範本的虛擬主機。未隱藏,最終使用者透過它獲取設定。
  • Balancer #1Balancer #2Balancer #3 — outbound 將注入範本的主機。
主機清單

步驟 2. 隱藏注入主機

開啟每個負載均衡器主機的卡片(Balancer #1、#2、#3),進入 Advanced 部分並啟用 Hide Host 開關。

隱藏的主機不會出現在普通訂閱中 — 它們只能透過注入機制存取。

隱藏負載均衡器主機

步驟 3. 建立訂閱範本

建立 XRAY_JSON 類型的訂閱範本。在其中描述完整設定:dnsroutinginboundsoutboundsburstObservatory 及其他所需部分。

outbounds 陣列中只放靜態 outbound(directblock)— 注入主機的 outbound 將自動新增。

在 JSON 根層級新增帶有隱藏主機選擇器的 remnawave 物件。

範本範例

{
"remnawave": {
"injectHosts": [
{
"selector": {
"type": "uuids",
"values": [
"8478b271-95d3-4312-85ae-ecf63fb53d1d",
"d31d6161-1315-4c1e-9a4b-141ab1c022f6",
"5749f69e-cd1b-4012-9407-450434085196"
]
},
"tagPrefix": "proxy"
}
]
},
"burstObservatory": {
"pingConfig": {
"timeout": "3s",
"interval": "1m",
"sampling": 1,
"destination": "http://www.gstatic.com/generate_204",
"connectivity": ""
},
"subjectSelector": ["proxy"]
},
"dns": {
"servers": ["1.1.1.1", "1.0.0.1"],
"queryStrategy": "UseIP"
},
"routing": {
"balancers": [
{
"tag": "Super_Balancer",
"selector": ["proxy"],
"strategy": {
"type": "leastLoad",
"settings": {
"maxRTT": "1s",
"expected": 2,
"baselines": ["1s"],
"tolerance": 0.01
}
},
"fallbackTag": "direct"
}
],
"rules": [
{
"protocol": ["bittorrent"],
"outboundTag": "direct"
},
{
"network": "tcp,udp",
"balancerTag": "Super_Balancer"
}
],
"domainMatcher": "hybrid",
"domainStrategy": "IPIfNonMatch"
},
"inbounds": [
{
"tag": "socks",
"port": 10808,
"listen": "127.0.0.1",
"protocol": "socks",
"settings": {
"udp": true,
"auth": "noauth"
},
"sniffing": {
"enabled": true,
"routeOnly": false,
"destOverride": ["http", "tls", "quic"]
}
},
{
"tag": "http",
"port": 10809,
"listen": "127.0.0.1",
"protocol": "http",
"settings": {
"allowTransparent": false
},
"sniffing": {
"enabled": true,
"routeOnly": false,
"destOverride": ["http", "tls", "quic"]
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
]
}

請注意:

  • "subjectSelector": ["proxy"] — Observatory 將監控標籤以 proxy 開頭的所有 outbound(即 proxyproxy-2proxy-3)。
  • "selector": ["proxy"]Super_Balancer 負載均衡器將在相同的 outbound 之間分配流量。
  • 範本的 outbounds 中只指定了 directblock — 主機的 outbound 將自動新增在它們之前。

步驟 4. 將範本分配給虛擬主機

開啟虛擬主機 (Virtual Host) 的卡片,進入 Advanced 部分,在 Xray JSON Template 欄位中選擇建立的範本。

確保虛擬主機的 Hide Host 開關已關閉 — 它應該在訂閱中可見。

將範本分配給虛擬主機

步驟 5. 結果

請求訂閱時,面板會自動:

  1. 取得分配給虛擬主機的範本。
  2. 從中移除 remnawave 物件。
  3. 對於 injectHosts 中的每個組,透過 selector 選擇隱藏主機並組裝其 outbound。
  4. 將 outbound 插入到 outbounds 陣列的開頭
  5. 從虛擬主機的備註設定 remarks

用戶端收到的最終設定

[
{
"dns": {
"servers": ["1.1.1.1", "1.0.0.1"],
"queryStrategy": "UseIP"
},
"routing": {
"rules": [
{
"protocol": ["bittorrent"],
"outboundTag": "direct"
},
{
"network": "tcp,udp",
"balancerTag": "Super_Balancer"
}
],
"balancers": [
{
"tag": "Super_Balancer",
"selector": ["proxy"],
"strategy": {
"type": "leastLoad",
"settings": {
"maxRTT": "1s",
"expected": 2,
"baselines": ["1s"],
"tolerance": 0.01
}
},
"fallbackTag": "direct"
}
],
"domainMatcher": "hybrid",
"domainStrategy": "IPIfNonMatch"
},
"inbounds": [
{
"tag": "socks",
...omitted...
},
{
"tag": "http",
...omitted...
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {...omitted...},
"streamSettings": {...omitted...}
},
{
"tag": "proxy-2",
"protocol": "vless",
"settings": {...omitted...},
"streamSettings": {...omitted...}
},
{
"tag": "proxy-3",
"protocol": "vless",
"settings": {...omitted...},
"streamSettings": {...omitted...}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"burstObservatory": {
"pingConfig": {
"timeout": "3s",
"interval": "1m",
"sampling": 1,
"destination": "http://www.gstatic.com/generate_204",
"connectivity": ""
},
"subjectSelector": ["proxy"]
},
"remarks": "Virtual Host"
}
]

發生了什麼:

  • remnawave 物件已從最終設定中移除。
  • 三個 outbound(proxyproxy-2proxy-3)被插入到 outbounds 陣列的開頭,在 directblock 之前。
  • 負載均衡器中的 "selector": ["proxy"] 自動捕獲了所有三個 outbound,因為它們的標籤以 proxy 開頭(前綴匹配)。
  • Observatory 中的 "subjectSelector": ["proxy"] 同樣捕獲了所有三個 outbound 進行監控。
  • "remarks": "Virtual Host" — 取自虛擬主機的備註。
備註

虛擬主機位址和實際 inbound

在此場景中,虛擬主機作為範本和中繼資料(備註、伺服器描述)的「包裝器」,而不是實際的連線點。 在其設定中可以指定任何位址(例如 balancer.host.com)— 它不參與使用者的實際連線。 實際入口點是注入主機的特定 inbound。重要的是,請求訂閱的使用者透過小隊可以存取此 inbound,否則虛擬主機根本不會出現在他們的訂閱中。 實際連線參數(位址、端口、金鑰等)取自注入主機,其 outbound 設定被注入到用戶端的最終設定中。

重要說明

  • 虛擬主機必須已啟用且未隱藏。 正是它決定將使用哪個範本,remarksdescription 都取自它。
  • 注入主機必須已啟用。 預設只選擇隱藏主機(selectFrom: "HIDDEN")。此行為可以變更為 "NOT_HIDDEN""ALL"。如果主機被停用或未透過選擇器找到 — 將被跳過。
  • 所有參與主機必須對最終使用者可存取 — 它們繫結的 inbound 必須在使用者的小隊中啟用。
  • remnawave 物件將被移除 — 用戶端不會看到它。
  • Outbound 新增到開頭 outbounds 陣列。如果啟用了 addVirtualHostAsOutbound,帶有 proxy 標籤的虛擬主機 outbound 排在第一位,然後是注入的,然後是範本中的靜態 outbound(directblock)。
  • 主機順序決定 outbound 的順序和分配給它們的標籤。對於 uuids 選擇器 — values 陣列中的 UUID 順序。可以使用 useHostRemarkAsTaguseHostTagAsTag 代替 tagPrefix,以便從主機屬性產生標籤。
  • 範本選擇和主機隱藏在主機卡片的 Advanced 部分。