Симптом: всё зелёное, а страницы не грузятся
Клиент подключается, панель показывает online/connected, пинг до ноды живой, Reality-хендшейк проходит — openssl s_client отдаёт сертификат маскировочной цели. Но наружу трафик не выходит: страницы не грузятся, спидтест показывает «n/a», всё висит. Железо ноды при этом исправно: curl https://… с самой ноды возвращает 200, ip_forward = 1, MASQUERADE на месте.
Это классический симптом пустого outbounds в config-профиле.
Механизм
В профиле Xray-конфигурация имеет "outbounds": [] или пустой routing. Reality-инбаунд принимает и расшифровывает соединение — поэтому панель видит online. Но Xray некуда деть расшифрованный трафик: нет outbound freedom. Пакеты входят и умирают на ноде.
Рабочий профиль обязан иметь оба выхода:
"outbounds": [
{ "tag": "DIRECT", "protocol": "freedom" },
{ "tag": "BLOCK", "protocol": "blackhole" }
]
Как это заносят: автоматический проход добавлял один инбаунд и передал PATCH с полным config, в котором не было блока outbounds. Профиль перезаписался целиком — выход затёрся для всех нод этого профиля разом.
Диагностика (только чтение)
Прогнать все профили и найти те, где инбаунды есть, а outbounds пуст:
для каждого профиля: inb = инбаунды кроме 'api', ob = outbounds
если inb непуст, а ob пуст → ПУСТО, чинить
Два обманчивых момента. Реальная конфигурация на ноде в файле не лежит — панель держит её в памяти, поэтому проверять надо через API профиля, а не cat на ноде. И «всё живо» с самой ноды ничего не доказывает: curl с ноды идёт мимо xray-инбаунда, его 200 не говорит о туннеле ничего.
Фикс
GET свежего профиля → снапшот → добавить оба outbounds → PATCH → пересинк ноды. Пересинк надёжнее делать полным рестартом контейнера ноды (docker restart): панельный restart отдаёт eventSent: true, но xray на ноде не всегда реально перезапускается — PID не меняется, порт не поднимается. Проверка: ss -tlnp | grep <порт> показывает инбаунд.
Подводные камни
- Никогда не переписывайте config профиля целиком. Добавляя инбаунд, берите свежий config через GET и делайте append, сохраняя
outbounds,routing,dns. Сборка config с нуля — прямой путь к этому багу. - Не путать с «работает через раз». Если прямые хосты работают всегда, а «Авто» скачет между странами — это штатный leastLoad, а не пустой outbounds.
- После любого PATCH профиля — проверить, что
outboundsна месте.
Вывод. «Online, но трафик не идёт» при живом Reality-хендшейке — это пустой outbounds в профиле: расшифрованному трафику некуда выйти. Причина почти всегда — перезапись профиля целиком при добавлении инбаунда. Правило: только append к свежему config через GET, снапшот до PATCH, пересинк через полный рестарт контейнера ноды.