Блог Clearway

Настройка VLESS в 3x-ui: поля инбаунда, Reality и XHTTP за CDN

Коротко

Рабочая конфигурация под РФ — два инбаунда VLESS в одной панели. Первый: raw (в старых сборках tcp) + reality на 443 с flow: xtls-rprx-vision — быстрый основной вход, живёт, пока IP ноды не в блоке. Второй: xhttp, security: none, на локальном порту за CDN-фронтом на «белом» домене — резерв на блокировку IP и на whitelist-режим у оператора. Ключи Reality: /usr/local/x-ui/bin/xray-linux-amd64 x25519 (в свежих сборках вывод подписан PrivateKey/Password, где Password — публичный ключ для pbk), shortId — openssl rand -hex 8. Три главных грабли 3x-ui: flow валиден только с raw/tcp; у XHTTP mode обязан быть packet-up, а extra — совпадать на ноде и в клиенте символ в символ; автоссылка из панели всегда ведёт на IP ноды, поэтому для CDN-инбаунда ссылку собирают руками.

Два инбаунда: зачем VLESS Reality и XHTTP одновременно

Транспорт в 3x-ui выбирают не по вкусу, а по тому, что именно у вас ломается. ТСПУ режет по протоколу и SNI — спасает Reality. Нода уже отфильтрована по IP или абонент оказался в whitelist-режиме — Reality бесполезен: пакеты до вашего адреса просто не доходят.

ИнбаундЧто видит фильтрГде ломается
raw (tcp) + reality, 443TLS 1.3 handshake к чужому домену (dest)блокировка IP ноды; блок самого dest
xhttp + security: none за CDNHTTPS к домену CDN-провайдеранесовпадение mode/extra, кастомные заголовки
ws/grpc за CDNWebSocket-upgrade / HTTP-2-стримчасть российских CDN не проксирует апгрейд и капризна к таймаутам

Практика: Reality забирает ~90% трафика, XHTTP-инбаунд стоит вторым плечом и включается, когда первый уже мёртв. Оба живут в одной панели и уезжают абоненту одной подпиской — клиент сам переберёт точки входа. Ради второго плеча и существует whitelist-CDN как сервис (Clearway): нода остаётся вашей, а вход приходит с адреса, который у оператора не под фильтром.

Общую теорию Reality, обфускацию XHTTP и выбор whitelisted-подсетей разбирали отдельно — здесь только то, что нажимается и вводится в 3x-ui.

Перед настройкой: версия Xray, файлы панели, бэкап и откат

Сначала зафиксируйте, с чем работаете: форма инбаунда заметно менялась от ветки к ветке. XHTTP появился в Xray 24.11.x (пришёл на смену splithttp), а в ветке 25.x транспорт tcp переименован в raw — старое имя пока принимается, но в свежих сборках 3x-ui в списке вы увидите именно raw.

x-ui # интерактивное меню панели
x-ui settings # логин, порт панели, webBasePath
systemctl status x-ui
/usr/local/x-ui/bin/xray-linux-amd64 -version
ПутьЧто это
/etc/x-ui/x-ui.dbвся панель: инбаунды, клиенты, подписки, настройки. Единственное, что нужно бэкапить
/usr/local/x-ui/bin/config.jsonсгенерированный конфиг Xray. Руками не править — панель перезапишет при следующем сохранении
/usr/local/x-ui/bin/xray-linux-amd64бинарь ядра, им же генерируются ключи

Бэкап перед любой правкой на проде:

systemctl stop x-ui
cp /etc/x-ui/x-ui.db /root/x-ui.db.$(date +%F-%H%M).bak
systemctl start x-ui

Откат — та же операция в обратную сторону: остановить сервис, вернуть .bak на место /etc/x-ui/x-ui.db, запустить. Этим же способом инбаунды переезжают на другой сервер: ставите там ту же ветку 3x-ui и подкладываете БД. UUID, ключи Reality и Subscription ID переживают переезд, а вот адрес в клиентских ссылках — нет, абонентам придётся обновить подписку.

Два момента, которые экономят час отладки. Первый: порт панели и порт инбаунда не должны пересекаться — на занятом порту 3x-ui не всегда внятно ругается, инбаунд просто молча не поднимается. Второй: у формы инбаунда есть переключатель в JSON (иконка </>) — часть полей XHTTP (extra, размещение uplink и служебных ключей) в GUI отсутствует в принципе, и задаются они только там.

Настройка 3x-ui VLESS Reality: поля формы и ключи x25519

Inbounds → Add Inbound. Разбор полей схемы 3x-ui VLESS Reality в том порядке, как они идут в форме.

ПолеЗначениеКомментарий
Remarkreality-443попадает в имя конфига у абонента
Protocolvless
Listening IPпустопусто = 0.0.0.0
Port443почти всегда 443: на нестандартном порту маскировка под обычный сайт теряет смысл
Client → IDUUID (кнопка генерации)«ключ» абонента
Client → Emailуникальная меткауникальна в пределах всей панели, а не инбаунда; дубль ломает учёт трафика
Client → Flowxtls-rprx-visionтолько для raw/tcp. У XHTTP/WS/gRPC поле обязано быть пустым
Decryptionnoneв свежих ветках Xray у VLESS появилось собственное шифрование (encryption/decryption). Включать только когда все клиенты на такой же свежей версии
Transmissionraw (старые сборки — tcp)
Securityreality
uTLS (fingerprint)chromeдолжен совпасть с fp в ссылке
Dest / SNIчужой домен:443см. ниже
Private / Public keyкнопка Get New Cert или вручнуюприватный остаётся на ноде, публичный уходит в ссылку как pbk
Short IDs8–16 hex, чётное число символовможно несколько, клиент присылает один
SpiderX/в ссылке — spx=%2F

Если кнопка генерации не отработала (бывает на кастомных сборках) — считаем руками:

/usr/local/x-ui/bin/xray-linux-amd64 x25519
openssl rand -hex 8 # 16 hex-символов, годится как shortId

Нюанс свежих Xray: в части сборок вывод x25519 подписан не Private key / Public key, а PrivateKey / Password. Password здесь — это публичный ключ, тот самый pbk для клиента. Перепутать местами — классическая причина «подключается, но трафика нет».

Про dest: критерии выбора (TLS 1.3, HTTP/2, валидный сертификат, домен не под фильтром в РФ и не с вашего же хостера) разбирали в статье про Reality. От себя добавим честную оговорку: www.cloudflare.com как дефолт из мануалов — плохой выбор именно из-за тиражности, берите менее очевидный крупный домен.

После сохранения проверьте снаружи, что нода отдаёт чужой сертификат, а не ваш:

openssl s_client -connect NODE_IP:443 -servername www.samsung.com \
 </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject

Если в ответе ваш Let's Encrypt — Reality не активен, и вы только что показали фильтру свой домен.

Второй инбаунд: VLESS XHTTP за CDN, mode packet-up и extra

TLS терминируется на edge, до ноды идёт уже расшифрованный HTTP — значит на инбаунде TLS не нужен: Transmission: xhttp, Security: none, Listening IP 127.0.0.1 (если фронт на том же хосте) либо 0.0.0.0 с фаерволом, пускающим только адреса вашего gateway.

ПолеЗначение
Portлокальный, например 25454
Transmissionxhttp
Securitynone
Path/api/v1/sync/ — длинный, неугадываемый, ровно тот же на CDN
Hostдомен CDN-edge, который увидит абонент
Modepacket-up
Client → Flowпусто

Про mode — техфакт, на котором ломается большинство операторов. У Yandex CDN нет POST, поэтому XHTTP-аплинк уходит GET-запросами, а GET допустим только при mode: packet-up. Оставите auto — клиент сам выберет режим с POST, получит от edge отказ и повиснет на пустом соединении. Симптом узнаваемый: «в Happ работает, в v2rayN нет» — или наоборот, в зависимости от того, что клиент выбрал за вас.

Второе правило: extra на ноде и extra в клиенте совпадают полем в поле, не «примерно». Служебные данные раскладывайте по тем каналам, которые edge реально доносит до origin — тело запроса, query, cookie; произвольные кастомные заголовки CDN режет, и туннель рвётся с unexpected EOF (это разбиралось в отдельной статье про 3x-ui за CDN). И чем экзотичнее поля обфускации, тем выше шанс, что клиент на другой версии Xray их не поймёт: совместимость между ветками тут никем не гарантирована. Начинайте с минимума, добавляйте по факту подтверждённой проблемы.

Эти поля живут в JSON-редакторе инбаунда, в GUI их нет. Итог смотрите в сгенерированном конфиге:

{
 "network": "xhttp",
 "security": "none",
 "xhttpSettings": {
 "path": "/api/v1/sync/",
 "host": "edge.example.com",
 "mode": "packet-up",
 "extra": { "xPaddingBytes": "100-1000" }
 }
}

Проверка цепочки:

curl -s -o /dev/null -w '%{http_code}\n' https://edge.example.com/api/v1/sync/ # через фронт
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:25454/api/v1/sync/ # мимо CDN

Важно различать «404 от edge» (путь не проброшен на CDN) и «висит без ответа» (путь дошёл, но не совпал mode или extra). И закрывайте origin — фаерволом по адресам gateway или секрет-заголовком от edge: открытый резервный инбаунд находят сканом за сутки.

Отдельно запомните: 3x-ui не разделяет «инбаунд на сервере» и «адрес, который получает клиент». Автоссылка и QR из панели для этого инбаунда ведут на IP ноды напрямую, мимо CDN, и работать не будут.

Клиентская ссылка, подписка и Subscription ID

Ссылку полезно уметь читать глазами — большинство «не подключается» видно прямо в параметрах.

Reality (панель отдаёт корректно, кнопкой QR/копирования):

vless://[email protected]:443?type=tcp&security=reality&fp=chrome
&sni=www.samsung.com&pbk=PUBLIC_KEY&sid=1a2b3c4d&spx=%2F
&flow=xtls-rprx-vision#node1-reality

XHTTP за CDN (собирается вручную, один раз на инбаунд — дальше меняется только UUID):

vless://[email protected]:443?type=xhttp&security=tls
&sni=edge.example.com&host=edge.example.com&path=%2Fapi%2Fv1%2Fsync%2F
&mode=packet-up&extra=%7B%22xPaddingBytes%22%3A%22100-1000%22%7D#node1-cdn

Чек-лист сверки: pbk — публичный ключ с ноды, sid — один из shortId, sni/fp — как в форме, flow присутствует только у Reality-ссылки, mode и extra у XHTTP — байт в байт как на ноде. extra едет URL-энкоднутым JSON; если клиент при импорте молча его теряет — это ограничение клиента, а не ваша ошибка: заводите конфиг вручную или отдавайте JSON-подписку.

Подписка: Panel Settings → Subscription, порт по умолчанию 2096, путь /sub/, JSON-путь /json/. У каждого клиента должен быть заполнен Subscription ID — по нему 3x-ui группирует конфиги, и абонент получает Reality и XHTTP одной ссылкой. Домен подписки держите отдельным именем от нод: подписка отваливается первой, когда фильтр начинает работать по доменам. Там же в клиенте живут totalGB и срок действия — штатные лимиты панели, они считаются по Email-метке, поэтому дубли метки ломают и учёт, и автоотключение.

Про кэш — по наблюдениям: часть мобильных клиентов (особенно iOS) держит старую версию подписки десятками минут и не подхватывает правку инбаунда. Сменили mode, path или ключи — просите абонента обновить подписку вручную или переподписаться; на стороне фронта помогает отдача подписки с Cache-Control: no-store.

Диагностика: типовые ошибки vless 3x ui

Логи в первую очередь — с консоли быстрее, чем со страницы панели:

journalctl -u x-ui -f --no-pager
ss -tlnp | grep xray

Уровень лога Xray переключается в Xray Configuration → Log: на время отладки info, после — обратно, иначе диск съедается на живом трафике.

СимптомПричинаЧто делать
failed to find user / invalid userUUID в ссылке не совпал с клиентом инбаундапересоздать ссылку из панели, не править UUID руками
Клиент «connected», трафика ноль (Reality)перепутаны private/public, либо разъехались sid/sni/fpсверить с формой; помнить, что Password в выводе x25519 — публичный ключ
REALITY: processed invalid connection изредкачужие сканеры и пробынормально, реагировать не нужно
Рвётся на handshake, dest недоступен с нодыdest не отвечает TLS 1.3 или сам заблокировансменить dest, проверить openssl s_client с ноды
Клиент с flow не подключается к XHTTP/WSxtls-rprx-vision живёт только с raw/tcpочистить поле Flow у клиента этого инбаунда
XHTTP: edge отдаёт 404путь не проброшен на CDN или не совпал с pathвыровнять path на фронте и в инбаунде
XHTTP: соединение висит, данных нетmode разъехался (auto против packet-up)поставить packet-up с обеих сторон
XHTTP: unexpected EOFслужебные данные ушли в кастомный заголовок, edge его срезалпереложить uplink и служебные ключи в тело/query/cookie
Работает в одном приложении, не работает в другомклиент не понял extra или подставил свой modeубрать редкие поля обфускации, оставить минимум
Инбаунд «есть», порт не слушаетсяпорт занят панелью или другим инбаундом`ss -tlnp \grep -E ':443\:25454'`, сменить порт
Правка не примениласьядро не перезапустилосьx-ui restart, затем сверить /usr/local/x-ui/bin/config.json

Последнее правило универсальное: в споре формы и config.json прав config.json — в нём лежит то, что работает прямо сейчас, а не то, что вы видите на экране.

Частые вопросы

Reality или XHTTP — что настраивать первым в 3x-ui?

Первым — VLESS Reality на 443: он проще, не требует внешнего фронта и даёт лучшую скорость за счёт flow xtls-rprx-vision. XHTTP-инбаунд заводите вторым, как резерв на блокировку IP ноды или whitelist-режим у абонента. Держать оба нормально: они не конфликтуют, а подписка по общему Subscription ID отдаёт клиенту обе точки входа.

Почему не работает flow xtls-rprx-vision?

Этот flow валиден только для транспорта raw/tcp с TLS или Reality. С xhttp, ws, grpc, httpupgrade поле Flow у клиента должно быть пустым — иначе соединение не поднимется или отвалится сразу после handshake. Если инбаунд был Reality, а вы переключили транспорт, 3x-ui не всегда чистит flow автоматически: проверьте руками у каждого клиента инбаунда.

Где взять privateKey и publicKey, если кнопка в панели не сработала?

Сгенерируйте бинарём ядра: /usr/local/x-ui/bin/xray-linux-amd64 x25519. Приватный вставляете в инбаунд, публичный уходит в ссылку как pbk. В свежих сборках вывод подписан PrivateKey/Password — Password здесь и есть публичный ключ. ShortId: openssl rand -hex 8 (16 hex-символов).

Почему конфиг работает в одном клиенте и не работает в другом?

Почти всегда расхождение по XHTTP. Либо клиент выбрал mode auto и попытался слать POST туда, где фронт его не пропускает — у Yandex CDN POST нет, аплинк идёт GET, а GET допустим только при packet-up. Либо клиент не понял поле extra: его версия Xray не знает часть полей обфускации. Лечится приведением mode и extra к одинаковому виду на ноде и в ссылке и отказом от редких полей.

Почему ссылка из панели не работает для XHTTP-инбаунда за CDN?

3x-ui не разделяет серверный инбаунд и клиентский адрес: панель считает, что клиент идёт туда же, где стоит сервер, — по его IP. Автоссылка и QR ведут напрямую на ноду, мимо CDN. Для CDN-инбаунда ссылку собирают вручную: Address, SNI и Host — домен edge, security tls, type xhttp, mode packet-up. Шаблон делается один раз, дальше меняется только UUID.

Как перенести инбаунды 3x-ui на другой сервер?

Остановить панель, скопировать /etc/x-ui/x-ui.db на новый сервер с той же веткой 3x-ui, положить по тому же пути, запустить. UUID, ключи Reality, лимиты и Subscription ID сохранятся. Адрес в клиентских ссылках не сохранится: после переезда абонентам нужно обновить подписку, иначе они продолжат стучаться на старый IP.

Whitelisted-вход для вашего VPN-сервиса

Clearway даёт «белый» CDN-вход перед вашей нодой — устойчивый к троттлингу операторов. Первые 10 ГБ бесплатно, без карты.

Попробовать →