Zum Hauptinhalt springen

Xray JSON – Advanced

Übersicht

Für Abonnement-Vorlagen vom Typ XRAY_JSON in Remnawave stehen Remnawave-Direktiven zur Verfügung — spezielle Anweisungen, die Sie in die JSON-Vorlage einfügen. Das Panel verarbeitet sie bei der Generierung des Abonnements und entfernt sie aus der endgültigen Konfiguration — der Client wird sie nie sehen.

Derzeit ist die Direktive injectHosts verfügbar, die es ermöglicht, Outbound-Konfigurationen von Hosts dynamisch in die Vorlage einzufügen. Dies ist nützlich, wenn Sie eine komplexe Xray-Konfiguration mit Load-Balancern, benutzerdefiniertem Routing oder mehreren Outbounds aufbauen möchten, wobei die Verbindungsdaten (Adresse, Port, Schlüssel) automatisch aus dem Panel übernommen werden.

Hinweis

Die unten dargestellten Konfigurationen sind Beispiele zur Demonstration des Inject-Mechanismus. Passen Sie sie an Ihre Bedürfnisse an.

Achtung

Erfordert Remnawave Version 2.6.3 oder neuer.

Betriebsbedingungen

  • Der virtuelle Host (der Host, dem die Vorlage mit Inject zugewiesen ist) muss aktiviert und nicht versteckt sein.
  • Die zu injizierenden Hosts (über selector ausgewählt) müssen aktiviert sein. Standardmäßig werden nur versteckte Hosts ausgewählt (das Verhalten kann über selectFrom geändert werden).
  • Alle Hosts — sowohl der virtuelle als auch die zu injizierenden — müssen für den Endbenutzer zugänglich sein: Der Inbound, dem sie zugeordnet sind, muss in der Squad des Benutzers aktiviert sein.
  • Aus dem virtuellen Host werden in die endgültige Konfiguration die Bemerkung (remark) und die Serverbeschreibung (Server Description, falls vorhanden) übernommen.

remnawave-Struktur

Das remnawave-Objekt wird auf der Root-Ebene der JSON-Vorlage hinzugefügt. Es unterstützt die folgenden Felder:

FeldBeschreibung
injectHostsArray von Inject-Gruppen. Jede Gruppe enthält einen Selektor zur Host-Auswahl und Parameter zur Tag-Bildung.
addVirtualHostAsOutboundWenn true — wird der virtuelle Host als Outbound mit dem Tag proxy am Anfang des outbounds-Arrays hinzugefügt. Standard ist false. Siehe addVirtualHostAsOutbound.

Das Feld injectHosts ist ein Array von Inject-Gruppen. Jede Gruppe enthält einen Selektor zur Host-Auswahl und ein eigenes tagPrefix:

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

Jedes Element des injectHosts-Arrays:

FeldBeschreibung
selectorObjekt, das definiert, welche Hosts ausgewählt werden. Pflichtfeld.
selectFromAus welchem Pool Hosts ausgewählt werden: "HIDDEN" (Standard), "NOT_HIDDEN" oder "ALL".
tagPrefixTag-Präfix für die zu erstellenden Outbounds. Siehe Tag-Bildungsregeln.
useHostRemarkAsTagWenn true — wird die Bemerkung (remark) des Hosts als Tag des Outbounds verwendet.
useHostTagAsTagWenn true — wird der Tag des Hosts als Tag des Outbounds verwendet (wenn kein Tag gesetzt ist, wird die Bemerkung verwendet).
warnung

Es muss genau eines der drei Felder angegeben werden: tagPrefix, useHostRemarkAsTag oder useHostTagAsTag.

Es kann beliebig viele Gruppen geben — jede bildet ihre eigene unabhängige Menge von Outbounds mit eigenem Präfix. Dies ermöglicht beispielsweise, einen separaten Load-Balancer für jede Servergruppe zu erstellen.

Selektor-Typen

uuids

Wählt Hosts anhand einer UUID-Liste aus. Die Reihenfolge der UUIDs bestimmt die Reihenfolge der Outbounds.

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

remarkRegex

Wählt Hosts aus, deren Bemerkung (remark) mit dem regulären Ausdruck übereinstimmt. Syntax — JavaScript RegExp.

"selector": {
"type": "remarkRegex",
"pattern": "^Balancer"
}

Das obige Beispiel wählt alle versteckten Hosts aus, deren Bemerkung mit «Balancer» beginnt (z.B. «Balancer #1», «Balancer RU»).

tagRegex

Wählt Hosts aus, deren Host-Tag (Tag-Feld in den Host-Einstellungen) mit dem regulären Ausdruck übereinstimmt.

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

Das obige Beispiel wählt alle versteckten Hosts mit einem Tag aus, das mit balancer- beginnt.

sameTagAsRecipient

Wählt alle versteckten Hosts aus, deren Host-Tag mit dem Tag des virtuellen Hosts übereinstimmt. Erfordert keine zusätzlichen Parameter.

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

Praktisch, wenn Sie Hosts automatisch gruppieren möchten: Es reicht aus, dem virtuellen und den zu injizierenden Hosts denselben Tag zuzuweisen.

tipp

Standardmäßig arbeiten alle Selektoren nur mit versteckten Hosts. Um dieses Verhalten zu ändern, verwenden Sie das Feld selectFrom: Der Wert "NOT_HIDDEN" wählt nur sichtbare Hosts (aktiviert, aber nicht versteckt) aus, und "ALL" — alle Hosts (aktivierte, versteckte).

Tag-Bildungsregeln

Der Tag eines Outbounds wird dadurch bestimmt, welches der drei Felder in der Inject-Gruppe angegeben ist:

tagPrefix — Der erste Host erhält einen Tag, der gleich tagPrefix ist. Jeder folgende — {tagPrefix}-{N}, beginnend mit 2.

Beispiel für drei Hosts mit tagPrefix: "proxy":

ReihenfolgeTag des Outbounds
1.proxy
2.proxy-2
3.proxy-3

useHostRemarkAsTag — Jeder Outbound erhält einen Tag, der gleich der Bemerkung (remark) des Hosts ist.

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

Wenn Hosts die Bemerkungen «Moskau», «Petersburg», «Kasan» haben — erhalten die Outbounds die Tags Moskau, Petersburg, Kasan.

useHostTagAsTag — Jeder Outbound erhält einen Tag, der gleich dem Tag des Hosts ist. Wenn kein Host-Tag gesetzt ist, wird seine Bemerkung verwendet.

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

Präfix-Matching in Xray

Die Felder selector (in routing.balancers) und subjectSelector (in burstObservatory) in Xray funktionieren als Präfix-Matcher — sie gleichen den Anfang des Outbound-Tags ab, nicht seinen genauen Wert.

Wenn die Konfiguration beispielsweise Outbounds mit den Tags proxy, proxy-2, proxy-3, direct enthält:

Wert von selector / subjectSelectorWelche Outbounds werden ausgewählt
["proxy"]proxy, proxy-2, proxy-3
["proxy-"]proxy-2, proxy-3
  • "selector": ["proxy"] — erfasst alle injizierten Outbounds, einschließlich des ersten.
  • "selector": ["proxy-"] — erfasst alle außer dem ersten (nur proxy-2, proxy-3, ...).
Fallback über den ersten Host

Der erste ausgewählte Host erhält immer einen Tag ohne das Suffix -{N} (einfach proxy). Dies ermöglicht seine Verwendung als fallbackTag im Load-Balancer: Wenn alle Outbounds aus selector nicht verfügbar sind, geht der Traffic an den ersten Host. Setzen Sie dafür "selector": ["proxy-"] (nur proxy-2, proxy-3, ...) und "fallbackTag": "proxy".

addVirtualHostAsOutbound

Standardmäßig gelangen bei Verwendung der remnawave-Direktive nur die injizierten Hosts in die endgültige Konfiguration. Der virtuelle Host (Recipient) selbst wird nur als Quelle für remarks und serverDescription verwendet.

Wenn Sie möchten, dass der virtuelle Host ebenfalls ein Outbound mit dem Tag proxy wird, fügen Sie das Feld addVirtualHostAsOutbound: true auf Ebene des remnawave-Objekts hinzu:

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

In diesem Fall sieht das endgültige outbounds-Array folgendermaßen aus:

  1. Outbound des virtuellen Hosts mit dem Tag proxy.
  2. Injizierte Outbounds (aus injectHosts).
  3. Statische Outbounds aus der Vorlage (direct, block usw.).

Dies ist nützlich, wenn in Routing-Regeln "outboundTag": "proxy" verwendet wird, um Traffic über den Haupt-Host zu leiten, während die injizierten Hosts separate Traffic-Gruppen bedienen (z.B. über Load-Balancer).

tipp

addVirtualHostAsOutbound kann zusammen mit injectHosts oder ohne es verwendet werden. Wenn injectHosts nicht angegeben oder leer ist, wird nur der Outbound des virtuellen Hosts zur Konfiguration hinzugefügt.

Schritt-für-Schritt-Beispiel: Load-Balancer mit drei Hosts

In diesem Beispiel erstellen wir eine Konfiguration, in der drei Outbounds in einem Load-Balancer mit der Strategie leastLoad zusammengefasst und von einem Observatory überwacht werden.

Schritt 1. Hosts erstellen

Erstellen Sie im Panel die Hosts, die am Inject beteiligt sein werden. In unserem Beispiel sind das:

  • Virtual Host — der virtuelle Host, dem die Vorlage mit Inject zugewiesen wird. Er ist nicht versteckt und der Endbenutzer erhält die Konfiguration über ihn.
  • Balancer #1, Balancer #2, Balancer #3 — Hosts, deren Outbounds in die Vorlage eingefügt werden.
Host-Liste

Schritt 2. Zu injizierende Hosts verstecken

Öffnen Sie die Karte jedes Balancer-Hosts (Balancer #1, #2, #3), navigieren Sie zum Abschnitt Erweitert und aktivieren Sie den Schalter Host verstecken.

Versteckte Hosts erscheinen nicht im regulären Abonnement — sie sind nur über den Inject-Mechanismus zugänglich.

Balancer-Hosts verstecken

Schritt 3. Abonnement-Vorlage erstellen

Erstellen Sie eine Abonnement-Vorlage vom Typ XRAY_JSON. Beschreiben Sie darin die vollständige Konfiguration: dns, routing, inbounds, outbounds, burstObservatory und andere benötigte Abschnitte.

Platzieren Sie im outbounds-Array nur die statischen Outbounds (direct, block) — die Outbounds der zu injizierenden Hosts werden automatisch hinzugefügt.

Fügen Sie auf der Root-Ebene des JSON das remnawave-Objekt mit dem Selektor für versteckte Hosts hinzu.

Beispiel-Vorlage

{
"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"
}
]
}

Beachten Sie:

  • "subjectSelector": ["proxy"] — das Observatory wird alle Outbounds überwachen, deren Tag mit proxy beginnt (d.h. proxy, proxy-2, proxy-3).
  • "selector": ["proxy"] — der Load-Balancer Super_Balancer wird den Traffic auf dieselben Outbounds verteilen.
  • Im outbounds-Array der Vorlage sind nur direct und block angegeben — die Outbounds der Hosts werden automatisch davor hinzugefügt.

Schritt 4. Vorlage dem virtuellen Host zuweisen

Öffnen Sie die Karte des virtuellen Hosts (Virtual Host), navigieren Sie zum Abschnitt Erweitert und wählen Sie im Feld Xray JSON-Vorlage die erstellte Vorlage aus.

Stellen Sie sicher, dass der Schalter Host verstecken für den virtuellen Host deaktiviert ist — er muss im Abonnement sichtbar sein.

Vorlage dem virtuellen Host zuweisen

Schritt 5. Ergebnis

Bei der Abonnement-Anfrage verarbeitet das Panel automatisch:

  1. Nimmt die dem virtuellen Host zugewiesene Vorlage.
  2. Entfernt das remnawave-Objekt daraus.
  3. Für jede Gruppe in injectHosts wählt es versteckte Hosts nach selector aus und sammelt deren Outbounds.
  4. Fügt die Outbounds am Anfang des outbounds-Arrays ein.
  5. Setzt remarks aus der Bemerkung des virtuellen Hosts.

Endgültige Konfiguration, die der Client erhält

[
{
"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"
}
]

Was passiert ist:

  • Das remnawave-Objekt wurde aus der endgültigen Konfiguration entfernt.
  • Drei Outbounds (proxy, proxy-2, proxy-3) wurden am Anfang des outbounds-Arrays vor direct und block eingefügt.
  • "selector": ["proxy"] im Load-Balancer hat automatisch alle drei Outbounds erfasst, da ihre Tags mit proxy beginnen (Präfix-Matching).
  • "subjectSelector": ["proxy"] im Observatory hat analog alle drei Outbounds zur Überwachung erfasst.
  • "remarks": "Virtual Host" — übernommen aus der Bemerkung des virtuellen Hosts.
hinweis

Adresse des virtuellen Hosts und echter Inbound

Der virtuelle Host dient in diesem Szenario als «Wrapper» für die Vorlage und Metadaten (Bemerkung, Serverbeschreibung), nicht als echter Verbindungspunkt. In seinen Einstellungen kann jede Adresse angegeben werden (z.B. balancer.host.com) — sie nimmt nicht an der realen Verbindung des Benutzers teil. Der eigentliche Eingangspunkt ist der spezifische Inbound der injizierten Hosts. Wichtig ist, dass der Benutzer, der das Abonnement anfordert, über Squads Zugang zu diesem Inbound hat, sonst erscheint der virtuelle Host in seinem Abonnement gar nicht. Die eigentlichen Verbindungsparameter (Adressen, Ports, Schlüssel usw.) werden von den injizierten Hosts übernommen, deren Outbound-Konfigurationen in die endgültige Client-Konfiguration eingefügt werden.

Wichtige Hinweise

  • Der virtuelle Host muss aktiviert und nicht versteckt sein. Er bestimmt, welche Vorlage verwendet wird, und von ihm werden remarks und description übernommen.
  • Die zu injizierenden Hosts müssen aktiviert sein. Standardmäßig werden nur versteckte Hosts ausgewählt (selectFrom: "HIDDEN"). Dieses Verhalten kann auf "NOT_HIDDEN" oder "ALL" geändert werden. Wenn ein Host deaktiviert ist oder nicht durch den Selektor gefunden wird — wird er übersprungen.
  • Alle beteiligten Hosts müssen für den Endbenutzer zugänglich sein — der Inbound, dem sie zugeordnet sind, muss in der Squad des Benutzers aktiviert sein.
  • Das remnawave-Objekt wird aus der endgültigen Konfiguration entfernt — der Client wird es nicht sehen.
  • Outbounds werden am Anfang des outbounds-Arrays hinzugefügt. Wenn addVirtualHostAsOutbound aktiviert ist, kommt der Outbound des virtuellen Hosts mit dem Tag proxy zuerst, dann die injizierten, dann die statischen Outbounds aus der Vorlage (direct, block).
  • Die Reihenfolge der Hosts bestimmt die Reihenfolge der Outbounds und die ihnen zugewiesenen Tags. Für den uuids-Selektor — die Reihenfolge der UUIDs im values-Array. Anstelle von tagPrefix können useHostRemarkAsTag oder useHostTagAsTag verwendet werden, damit Tags aus Host-Eigenschaften gebildet werden.
  • Vorlagenauswahl und Host-Verstecken befinden sich im Abschnitt Erweitert in der Host-Karte.