Один хост в панели, который у клиента разворачивается в пул нод с автоматическим выбором лучшей.
Пользователь видит одну запись «Авто». Ноды скрыты, вручную выбрать нельзя.
Пользователь видит «Авто» плюс все ноды по отдельности и может выбрать конкретную страну.
Это обычные хосты на твоих нодах. Менять в них почти ничего не нужно.
| Поле | Значение |
|---|---|
| Hide host | включить |
| Hide host | выключить |
| Enabled | включён |
| Xray JSON | не привязывать — шаблон нужен только виртуальному хосту |
UUID берётся в карточке каждого хоста. Выпиши их в том порядке, в каком хочешь видеть теги outbounds: первый в списке станет proxy, второй proxy-2, третий proxy-3.
Порядок ни на что не влияет по существу — leastLoad всё равно сортирует по замерам. Но в логах удобнее, когда он осмысленный.
Список в шаблоне фиксированный, сам он не пополняется. Новая нода попадёт в пул только после правки шаблона, и если подписок несколько — править нужно каждую.
Держи это в чек-листе при заведении новой ноды, иначе она будет стоять и не использоваться.
Создай новый хост. Это та запись, которую увидит пользователь; никуда она не подключается.
| Поле | Значение | Почему |
|---|---|---|
| Hide host | выключить | иначе пользователь не увидит запись с автовыбором |
| Enabled | включён | выключенный не рендерится |
| Remark | Авто | подпись в клиенте |
Address, Port, SNI, pbk | заведомо нерабочие | панель требует заполнения, но в конфиг они не попадут. Копировать сюда параметры живой ноды не надо — см. фазу 03 |
| Inbound | любой доступный пользователю | нужен для проверки доступа по сквадам |
| Xray JSON | конфиг из фазы 03 | без него балансировщика не будет вовсе |
Балансировщик живёт целиком в шаблоне подписки. На нодах для него настраивать нечего — они не знают, что кто-то балансирует между ними.
| Не путать | Где создаётся | К чему привязан | Что описывает |
|---|---|---|---|
| Config Profile инбаунд | настройки нод | нода и хост | конфиг Xray на сервере |
| Xray JSON шаблон | раздел Xray JSON | виртуальный хост | конфиг, который получает клиент |
Дальше речь только про второй. Это два отдельных шага: создать конфиг и привязать его к хосту. Одного создания недостаточно.
Панель → Xray JSON → создать новый. Заменить нужно только UUID_ХОСТА_N на UUID из фазы 01 — строк в списке столько, сколько у тебя нод.
{
"remnawave": {
"injectHosts": [
{
"selector": {
"type": "uuids",
"values": [
"UUID_ХОСТА_1",
"UUID_ХОСТА_2",
"UUID_ХОСТА_3"
]
},
"selectFrom": "HIDDEN",
"selectFrom": "NOT_HIDDEN",
"tagPrefix": "proxy"
}
]
},
"log": { "loglevel": "warning" },
"dns": {
"servers": ["1.1.1.1", "1.0.0.1"],
"queryStrategy": "UseIPv4",
"disableCache": false
},
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 180,
"uplinkOnly": 1,
"downlinkOnly": 1
}
}
},
"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"]
}
}
],
"outbounds": [
{ "tag": "direct", "protocol": "freedom" },
{ "tag": "block", "protocol": "blackhole" }
],
"burstObservatory": {
"subjectSelector": ["proxy"],
"pingConfig": {
"destination": "https://www.gstatic.com/generate_204",
"connectivity": "http://connectivitycheck.gstatic.com/generate_204",
"interval": "30s",
"timeout": "5s",
"sampling": 6
}
},
"routing": {
"domainMatcher": "hybrid",
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "udp",
"port": 443,
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp,udp",
"balancerTag": "auto"
}
],
"balancers": [
{
"tag": "auto",
"selector": ["proxy"],
"fallbackTag": "direct",
"strategy": {
"type": "leastLoad",
"settings": {
"maxRTT": "2s",
"expected": 3,
"baselines": ["150ms", "300ms", "600ms"],
"tolerance": 0.15
}
}
}
]
}
}
| Место | Зачем так |
|---|---|
В outbounds только direct и block | Ноды панель вставляет в начало массива сама. Писать их руками нельзя |
selector: ["proxy"] | Совпадение по префиксу. Теги получаются proxy, proxy-2, proxy-3 — первый без номера |
selectFrom | Указан явно и обязан совпадать со схемой. Дефолт — HIDDEN, и если ноды видимые, пул окажется пустым при полностью правильном селекторе |
| Префикс не должен быть началом другого тега | Возьмёшь d — селектор затянет в пул direct |
network: udp, port: 443 → block | Режет QUIC: поверх TCP-туннеля HTTP/3 работает хуже, чем HTTP/2 |
bittorrent → direct | Торренты идут мимо туннеля. Нужен запрет — меняй на block |
connectivity | Проверка локальной сети. Без неё обрыв Wi-Fi помечает все ноды мёртвыми разом |
Если живых нод не осталось, трафик пойдёт мимо туннеля, с реального IP, и пользователь не заметит.
Альтернатива — block: при пустом пуле не работает ничего, зато утечки нет. Цена — возможная пауза на холодном старте. Проверь это в фазе 05 и реши.
Открой виртуальный хост из фазы 02 и выбери в нём созданный конфиг — в форме есть поле выбора Xray JSON.
Это отдельный обязательный шаг. Виртуальный хост и есть «получатель» инжекта: панель берёт его шаблон, находит по селектору остальные хосты и складывает их внутрь как outbounds.
Шаблон нужен только виртуальному хосту. Привяжешь его и нодам — каждая станет собственным балансировщиком и затянет в себя все остальные.
В схеме со скрытыми хостами участники сами по себе вообще не рендерятся. В схеме с видимыми — рендерятся обычными записями из своих полей, и шаблон им ни к чему.
Открой ссылку подписки — не карточку хоста, она всегда показывает vless://-превью независимо от шаблона.
Должен прийти JSON, и в нём инжектированные ноды в начале outbounds. Если пришёл список vless:// — конфиг не привязан, вернись к шагу 2.
Соблазнительно сделать виртуальный хост копией рабочей ноды — панель требует заполнить Address, SNI, pbk. Но если скопировать оттуда всё, а шаблон при этом окажется не привязан, получится ссылка, которая выглядит настоящей: клиент подключится по TCP, покажет пинг и не будет работать.
Отлаживать такое долго. Поставь виртуальному хосту адрес, который никуда не ведёт, и произвольный pbk — тогда при неприменённом шаблоне соединение честно упадёт сразу, и ошибка будет видна за секунду.
Значения в шаблоне рабочие. Этот раздел нужен, если поведение не устроит.
sampling × interval — сколько времени помнит наблюдатель.
| sampling | interval | Окно | Одна потеря | Поведение |
|---|---|---|---|---|
| 1 | 60s | 1 мин | 100% | Любой потерянный пакет выбивает ноду на минуту |
| 3 | 30s | 1,5 мин | 33% | Реагирует быстро, но нервно |
| 6 | 30s | 3 мин | 17% | В шаблоне. Терпит джиттер, ловит деградацию за минуту |
| 10 | 60s | 10 мин | 10% | Стабильно, но упавшую ноду держит долго |
При окне из одной пробы доля ошибок принимает два значения: 0% или 100%. В связке с низким tolerance любой потерянный пакет выбивает ноду из пула до следующей пробы. На мобильной сети ноды выпадают пачками, и балансировщик проваливается в fallback.
| Параметр | Что делает |
|---|---|
tolerance: 0.15 | Допустимая доля неудачных проб. При sampling 6 одна потеря прощается, две подряд нет |
maxRTT: 2s | Потолок. Ставить 1s рискованно — на плохой сети теряется весь пул |
baselines | Три ступени приоритета. Набирает expected нод из первой, не хватило — добирает из следующей |
expected: 3 | Сколько нод оставить в выборе. Больше одной — меньше переключений |
tolerance до 0.25 или sampling до 10sampling или intervalbaselinesmaxRTT и toleranceОткрой ссылку подписки в браузере. В JSON должно быть:
remnawave нет — панель его вырезаетТолько direct и block — инжект не сработал. Проверь: участники включены → их видимость совпадает со схемой и с selectFrom → UUID скопированы без опечаток → у пользователя есть доступ через сквад.
На один больше — виртуальный хост попал в свой же пул. Смени его тег.
Меньше — часть хостов не прошла по сквадам.
Выключи в панели ту ноду, которую выбрал балансировщик. Соединение должно восстановиться за 30–60 секунд.
Затем перезапусти клиент полностью и проверь, работает ли сеть в первые 30 секунд. Это определяет, можно ли ставить fallbackTag: "block" вместо direct.
| Стратегия | Критерий | Слабое место |
|---|---|---|
leastLoad | стабильность задержки, по отклонению RTT | четыре параметра, которые надо настроить |
leastPing | минимальный средний RTT | игнорирует потери: нода с 20 мс и 10% потерь выглядит лучше стабильной на 60 мс |
roundRobin | по очереди | разные соединения идут через разные IP |
random | случайно | то же плюс непредсказуемая задержка |
Они выбирают ноду на каждое соединение, а не на сессию. Страница грузится через одну ноду, картинки через другую, запрос к API с третьего IP. Результат — вылеты из аккаунтов, капчи, отказы платёжных форм.
Самый частый симптом и самый обманчивый: клиент показывает задержку, значит «работает», но трафик не идёт. Разбирается по порядку, каждый шаг отсекает часть причин.
Это отвечает сразу на три вопроса. Смотри, что там:
vless:// вместо JSON — шаблон не привязан к виртуальному хосту. Клиент подключается к его адресу-заполнителю, а пинг показывает до этого адреса. Возвращайся к фазе 03outbounds только direct и block — инжект дал ноль хостов. Сверь UUID с карточками хостов и проверь selectFromЕсли у тебя несколько виртуальных хостов и часть работает, сравни у них только одну строку — selectFrom. Разница почти всегда там, а не в селекторе.
selectFrom не связан с типом селектора и по умолчанию равен HIDDEN. Конфиг с "selectFrom": "ALL" работает при любой видимости нод; конфиг без этой строки при видимых нодах даёт пустой пул, даже если селектор написан идеально.
Быстрый фикс — поставь "selectFrom": "ALL" в неработающий конфиг. Сработает всегда. Потом заменишь на точное значение под свою схему.
В схеме с видимыми хостами это делается в два тапа. В схеме со скрытыми — временно сними Hide host с одной ноды.
Открой JSON подписки и проверь, что они согласованы между собой:
proxy, proxy-2, proxy-3balancers[0].selector — ["proxy"]burstObservatory.subjectSelector — ["proxy"]Расхождение между subjectSelector и selector даёт ровно этот симптом: наблюдатель замеряет ноды и показывает пинг, а балансировщик пул не находит.
Заодно сверь balancerTag в правиле роутинга с tag балансировщика — оба должны быть auto.
При domainStrategy: "AsIs" он клиенту не нужен: домены уходят на сервер и резолвятся там. А вреда может принести — запросы к 1.1.1.1 попадают под правило-перехватчик и уходят в балансировщик. Получается замкнутый круг: чтобы отрезолвить адрес ноды, нужен туннель, а чтобы поднять туннель, нужен адрес.
Симптом при этом характерный: пинг по IP проходит, а всё, что требует имён, не работает. Удали секцию dns целиком и переподключись.
Временно убери правило блокировки QUIC и правило bittorrent, оставь только правило-перехватчик с balancerTag. Если заработало — возвращай по одному.
Если не помогло, включи в клиенте показ лога Xray. И Happ, и INCY это умеют — там будет видно, на чём именно рвётся соединение.
| Симптом | Что смотреть |
|---|---|
В подписке только direct и block | Опечатка в UUID, selectFrom не совпадает с видимостью нод, либо нет доступа через сквад |
Подписка отдаёт vless://, а не JSON | Шаблон не привязан к виртуальному хосту |
| Outbounds на один больше, чем нод | Виртуальный хост подошёл под свой селектор. Смени его тег |
| Часть нод не попала в пул | Сквады: у пользователя нет доступа к инбаунду этой ноды |
| Ноды инжектятся, клиент не подключается | selector балансировщика не совпадает с tagPrefix |
| Перескакивает между нодами | sampling мал или tolerance строг. Фаза 04 |
| Трафик пошёл с реального IP | Пул опустел, сработал fallbackTag: "direct" |
| Балансировщик не переключается вообще | Проверка connectivity не проходит в твоей сети. Убери эту строку |
| Клиент ругается на конфиг | Часть прослоек ждёт "stats": {} рядом с burstObservatory. Добавить безвредно |
| Клиент | Поддержка |
|---|---|
| Happ | да, даёт выбрать балансировщик в интерфейсе |
| INCY | да, полный конфиг включая burstObservatory |
| v2rayN / v2rayNG | да, в JSON-режиме |
| Streisand | да |
| Hiddify | шаблон не подходит — своя балансировка на sing-box |
Если подписка отдаёт JSON всем без разбора, пользователи Hiddify получат непригодный для них конфиг. Либо отдельная ссылка, либо отдача шаблона по User-Agent.
Механика injectHosts — по документации Remnawave, параметры leastLoad — по документации Xray и практике настройки. Выбор схемы и значения полей хранятся только в этом браузере.