Xray JSON – Advanced
概要
RemnawaveのXRAY_JSONタイプのサブスクリプションテンプレートには、Remnawaveディレクティブが用意されています——JSONテンプレートに追加する特別な指示です。パネルはサブスクリプション生成時にこれらを処理し、最終設定から削除します——クライアントが見ることはありません。
現在、injectHostsディレクティブが利用可能で、ホストのoutbound設定をテンプレートに動的に挿入することができます。これは、ロードバランサー、カスタムルーティング、または複数のoutboundを含む複雑なXray設定を構築する必要があるときに便利で、接続データ(アドレス、ポート、鍵)はパネルから自動的に挿入されます。
以下に示す設定は、インジェクトメカニズムのデモンストレーションのための例です。ご自身のニーズに合わせて調整してください。
Remnawave バージョン 2.6.3 以降が必要です。
動作条件
- 仮想ホスト(インジェクトテンプレートが割り当てられたホスト)は有効で非表示でない必要があります。
- インジェクトするホスト(
selectorを通じて選択されたもの)は有効である必要があります。デフォルトでは非表示のホストのみが選択されます(動作はselectFromで変更できます)。 - すべてのホスト——仮想ホストもインジェクトするホストも——エンドユーザーがアクセスできる必要があります:それらが紐付けられているinboundがユーザーのsquadに含まれている必要があります。
- 仮想ホストから最終設定に引き継がれるのは備考(remark)とサーバー説明(Server Description、設定されている場合)です。
remnawaveの構造
remnawaveオブジェクトはJSONテンプレートのルートレベルに追加されます。以下のフィールドをサポートします:
| フィールド | 説明 |
|---|---|
injectHosts | インジェクトグループの配列。各グループには、ホスト選択のためのセレクタとタグ形成パラメータが含まれます。 |
addVirtualHostAsOutbound | trueの場合——仮想ホストがproxyタグを持つoutboundとしてoutbounds配列の先頭に追加されます。デフォルトはfalse。addVirtualHostAsOutboundを参照。 |
injectHostsフィールドはインジェクトグループの配列です。各グループにはホスト選択のためのセレクタと独自のtagPrefixが含まれます:
"remnawave": {
"injectHosts": [
{
"selector": { "type": "uuids", "values": ["ホスト1-uuid", "ホスト2-uuid"] },
"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のタグはホストのホストタグになります(タグが設定されていない場合は備考が使用されます)。 |
tagPrefix、useHostRemarkAsTag、useHostTagAsTagの3つのフィールドのうちいずれか1つだけを指定する必要があります。
グループの数は任意——それぞれが独自のプレフィックスを持つ独立した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": "^Balancer"
}
上記の例では、備考が「Balancer」で始まるすべての非表示ホスト(例:「Balancer #1」、「Balancer RU」)が選択されます。
tagRegex
ホストタグ(ホスト設定のtagフィールド)が正規表現に一致するホストを選択します。
"selector": {
"type": "tagRegex",
"pattern": "^balancer-"
}
上記の例では、balancer-で始まるタグを持つすべての非表示ホストが選択されます。
sameTagAsRecipient
ホストタグが仮想ホストのタグと一致するすべての非表示ホストを選択します。追加のパラメータは不要です。
"selector": {
"type": "sameTagAsRecipient"
}
ホストを自動的にグループ化したい場合に便利です:仮想ホストとインジェクトするホストに同じタグを割り当てるだけで済みます。
デフォルトでは、すべてのセレクタは非表示ホストのみで動作します。この動作を変更するには、selectFromフィールドを使用します:値"NOT_HIDDEN"は表示されているホスト(有効だが非表示でない)のみを選択し、"ALL"——すべてのホスト(有効、非表示)を選択します。
タグ形成規則
outboundのタグは、インジェクトグループで指定された3つのフィールドのどれによって決まります:
tagPrefix — 最初のホストはtagPrefixに等しいタグを取得します。それ以降は{tagPrefix}-{N}、2から始まります。
3つのホストに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タグの正確な値ではなく、先頭と照合されます。
例えば、設定にproxy、proxy-2、proxy-3、directのタグを持つoutboundがある場合:
| selector / subjectSelektorの値 | 選択されるoutbound |
|---|---|
["proxy"] | proxy、proxy-2、proxy-3 |
["proxy-"] | proxy-2、proxy-3 |
"selector": ["proxy"]— 最初のものを含むすべてのインジェクトされたoutboundをキャプチャします。"selector": ["proxy-"]— 最初を除くすべてをキャプチャします(proxy-2、proxy-3、...のみ)。
選択された最初のホストは常にサフィックス-{N}なしのタグを取得します(単純にproxy)。これにより、ロードバランサーのfallbackTagとして使用できます:selectorのすべてのoutboundが利用不可の場合、トラフィックは最初のホストに流れます。そのためには"selector": ["proxy-"](proxy-2、proxy-3、...のみ)と"fallbackTag": "proxy"を設定します。
addVirtualHostAsOutbound
デフォルトでは、remnawaveディレクティブを使用する場合、インジェクトされたホストのみが最終設定に含まれます。仮想ホスト(recipient)自体はremarksとserverDescriptionのソースとしてのみ使用されます。
仮想ホストもproxyタグを持つoutboundになる必要がある場合は、remnawaveオブジェクトのレベルでaddVirtualHostAsOutbound: trueフィールドを追加してください:
"remnawave": {
"addVirtualHostAsOutbound": true,
"injectHosts": [
{
"selector": { "type": "uuids", "values": ["ホスト1-uuid", "ホスト2-uuid"] },
"tagPrefix": "proxy"
},
{
"selector": { "type": "remarkRegex", "pattern": "^RU-" },
"tagPrefix": "backup"
}
]
}
この場合、最終的なoutbounds配列は次のようになります:
proxyタグを持つ仮想ホストのoutbound。- インジェクトされたoutbound(
injectHostsから)。 - テンプレートの静的outbound(
direct、blockなど)。
これは、ルーティングルールで"outboundTag": "proxy"を使用してメインホスト経由でトラフィックを転送し、インジェクトされたホストが個別のトラフィックグループ(たとえばロードバランサー経由)を処理する場合に便利です。
addVirtualHostAsOutboundはinjectHostsと一緒に使用することも、単独で使用することもできます。injectHostsが指定されていないか空の場合、仮想ホストのoutboundのみが設定に追加されます。
ステップバイステップの例:3つのホストを使ったロードバランサー
この例では、3つのoutboundをleastLoad戦略のロードバランサーに組み合わせ、observatoryで監視する設定を作成します。
ステップ1. ホストの作成
インジェクトに参加するホストをパネルで作成します。この例では:
- Virtual Host — インジェクトテンプレートが割り当てられる仮想ホスト。非表示ではなく、エンドユーザーはこれを通じて設定を取得します。
- Balancer #1、Balancer #2、Balancer #3 — outboundがテンプレートに挿入されるホスト。
ステップ2. インジェクトするホストを非表示にする
各バランサーホスト(Balancer #1、#2、#3)のカードを開き、詳細設定セクションに移動して、ホストを非表示スイッチを有効にします。
非表示のホストは通常のサブスクリプションには表示されません——インジェクトメカニズムを通じてのみアクセスできます。
ステップ3. サブスクリプションテンプレートの作成
XRAY_JSONタイプのサブスクリプションテンプレートを作成します。dns、routing、inbounds、outbounds、burstObservatoryなどの必要なセクションを含む完全な設定を記述します。
outbounds配列には静的なoutboundのみ(direct、block)を配置します——インジェクトするホストの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(proxy、proxy-2、proxy-3)を監視します。"selector": ["proxy"]— ロードバランサーSuper_Balancerは同じoutbound間でトラフィックを分散します。- テンプレートの
outboundsにはdirectとblockのみが指定されています——ホストのoutboundはその前に自動的に追加されます。
ステップ4. テンプレートを仮想ホストに割り当てる
仮想ホスト(Virtual Host)のカードを開き、詳細設定セクションに移動して、Xray JSONテンプレートフィールドで作成したテンプレートを選択します。
仮想ホストのホストを非表示スイッチが無効になっていることを確認してください——サブスクリプションで表示される必要があります。
ステップ5. 結果
サブスクリプションリクエスト時、パネルは自動的に:
- 仮想ホストに割り当てられたテンプレートを取得します。
- そこから
remnawaveオブジェクトを削除します。 injectHostsの各グループについて、selectorで非表示ホストを選択し、それらのoutboundを収集します。- outboundを
outbounds配列の先頭に挿入します。 - 仮想ホストの備考から
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オブジェクトが最終設定から削除されました。- 3つのoutbound(
proxy、proxy-2、proxy-3)がoutbounds配列の先頭(directとblockの前)に挿入されました。 - ロードバランサーの
"selector": ["proxy"]が3つのoutboundすべてを自動的にキャプチャしました(タグがproxyで始まるため、プレフィックスマッチング)。 - observatoryの
"subjectSelector": ["proxy"]も同様に3つのoutboundすべてを監視のためにキャプチャしました。 "remarks": "Virtual Host"— 仮想ホストの備考から取得されました。
仮想ホストのアドレスと実際のinbound
このシナリオでの仮想ホストは、テンプレートとメタデータ(備考、サーバー説明)の「ラッパー」として機能し、実際の接続ポイントではありません。
その設定では任意のアドレス(例:balancer.host.com)を指定できます——それはユーザーの実際の接続には関与しません。
実際の入口は、インジェクトされたホストの特定のinboundです。サブスクリプションをリクエストするユーザーがsquadを通じてそのinboundにアクセスできることが重要です。そうでなければ、仮想ホストはそのサブスクリプションにまったく表示されません。
実際の接続パラメータ(アドレス、ポート、鍵など)は、クライアント側の最終設定にoutbound設定が挿入されるインジェクトされたホストから取得されます。
重要な注意事項
- 仮想ホストは有効で非表示でない必要があります。 どのテンプレートが使用されるかを決定するのはこれであり、
remarksとdescriptionもここから取得されます。 - インジェクトするホストは有効である必要があります。 デフォルトでは非表示のホストのみが選択されます(
selectFrom: "HIDDEN")。この動作は"NOT_HIDDEN"または"ALL"に変更できます。ホストが無効またはセレクタで見つからない場合——スキップされます。 - 参加するすべてのホストはエンドユーザーがアクセスできる必要があります——それらが紐付けられているinboundがユーザーのsquadに含まれている必要があります。
remnawaveオブジェクトは削除されます——クライアントは見ることができません。- outboundは
outbounds配列の先頭に追加されます。addVirtualHostAsOutboundが有効な場合、proxyタグを持つ仮想ホストのoutboundが最初に来て、次にインジェクトされたものが続き、最後にテンプレートの静的outbound(direct、block)が来ます。 - ホストの順序がoutboundの順序と割り当てられるタグを決定します。
uuidsセレクタでは——values配列のUUIDの順序です。tagPrefixの代わりにuseHostRemarkAsTagまたはuseHostTagAsTagを使用して、ホストのプロパティからタグを形成することもできます。 - テンプレートの選択とホストの非表示はホストカードの詳細設定セクションにあります。