3x-ui и VLESS XHTTP: настройка транспорта XHTTP в панели 3x-ui для обхода блокировок

Полное руководство по настройке VLESS XHTTP в 3x-ui: принципы работы, режимы, комбинация с Reality, работа через CDN, типовые ошибки и рекомендации.

Что такое XHTTP и зачем он нужен в 3x-ui

XHTTP — это транспортный механизм, разработанный для Xray-core, который обычно используется вместе с протоколом VLESS. Вопреки распространённому заблуждению, XHTTP — не самостоятельный протокол, а способ передачи данных, который позволяет маскировать прокси-трафик под обычные HTTP-запросы. В контексте панели 3x-ui XHTTP появляется в списке доступных транспортов при создании входящего подключения (inbound) и даёт возможность гибко настраивать обход блокировок.

Основная задача XHTTP — решить проблемы, характерные для более старых транспортов, таких как WebSocket. WebSocket имеет узнаваемые признаки, по которым система фильтрации может вычислить прокси, и поддерживается не всеми CDN. XHTTP, напротив, работает через механизм множественных HTTP-запросов-ответов, что делает его совместимым с гораздо более широким спектром веб-серверов и CDN, включая те, которые не поддерживают WebSocket или gRPC.

В 3x-ui транспорт XHTTP доступен в свежих версиях Xray-core (начиная с версии 24.11.x). В более старых ветках он назывался splithttp. Важно понимать, что XHTTP активно развивается, поэтому версии Xray на клиенте и сервере должны совпадать, иначе возможны сбои в работе. Панель 3x-ui, будучи удобной обёрткой над Xray, позволяет настраивать XHTTP через графический интерфейс, хотя некоторые продвинутые параметры доступны только в JSON-редакторе.

Как работает XHTTP: режимы packet-up, stream-up и stream-one

XHTTP выделяется среди других транспортов тем, что разделяет входящий и исходящий потоки данных. Это позволяет значительно усложнить анализ трафика и повысить устойчивость к блокировкам. В зависимости от режима работы, XHTTP использует разное количество соединений:

  • packet-up — самый совместимый режим, работающий практически со всеми веб-серверами и CDN. Для передачи данных от клиента к серверу используется множество короткоживущих HTTP-запросов, а для обратного направления — одно долгоживущее соединение. Этот режим медленнее других, но зато надёжен и редко вызывает проблемы.
  • stream-up — более быстрый режим, использующий два отдельных долгоживущих соединения: одно для передачи от клиента к серверу, другое — в обратную сторону. Совместимость ниже, чем у packet-up, и он работает только с определёнными веб-серверами.
  • stream-one — единственный режим, который не разделяет потоки и передаёт данные в обе стороны через одно соединение. По сути, он напоминает старый транспорт с HTTP-заголовком и работает через Nginx с директивой grpc_pass или через Cloudflare с включённой поддержкой gRPC.

Выбор режима зависит от ваших задач. Если вы используете CDN, которые не поддерживают POST-запросы (например, некоторые российские CDN), то вам подойдёт только packet-up. В остальных случаях можно экспериментировать с stream-up для повышения скорости. stream-one применяется реже, так как требует специфической конфигурации сервера.

В 3x-ui при создании инбаунда с транспортом XHTTP поле mode в JSON-редакторе может принимать значения auto, packet-up, stream-up или stream-one. Если оставить auto, клиент сам выберет режим, но это может привести к несовместимости с сервером. Поэтому рекомендуется явно указывать нужный режим.

Преимущества XHTTP перед другими транспортами

XHTTP предлагает несколько ключевых преимуществ, которые делают его привлекательным для обхода блокировок в условиях агрессивной фильтрации трафика:

1. Работа через CDN, не поддерживающие WebSocket. Многие CDN (например, некоторые региональные) не умеют проксировать WebSocket-соединения, но отлично работают с обычными HTTP-запросами. XHTTP использует именно HTTP, поэтому открывается доступ к более широкому пулу CDN.

2. Разделение потоков «туда» и «обратно». В режимах packet-up и stream-up данные передаются по разным соединениям, что затрудняет анализ паттернов трафика. Системы фильтрации, которые ищут TLS-внутри-TLS, теряются, так как видят два независимых потока, которые сложно связать друг с другом.

3. Возможность комбинировать разные протоколы и адреса. XRay позволяет настраивать соединения для приёма и передачи независимо. Например, можно отправлять данные через QUIC, а получать по HTTPS, или использовать разные IPv4/IPv6-адреса. Это даёт огромную гибкость и усложняет жизнь цензорам.

4. Маскировка под реальный веб-сервер. При использовании XHTTP за Nginx или Caddy, фингерпринт сервера будет аутентичным, так как на 443 порту слушает настоящий веб-сервер, а Xray находится позади него. Это особенно важно в условиях, когда блокируется TLS v1.3 (используемый XTLS-Reality), но TLS v1.2 остаётся доступным.

5. Поддержка browser dialer. Эта функция позволяет клиенту подключаться к прокси через браузер, что делает фингерпринт клиента максимально похожим на настоящий браузер. Однако эта возможность требует дополнительной настройки и используется реже.

Настройка VLESS Reality на 443: первый инбаунд в 3x-ui

Для создания надёжной конфигурации под российские условия рекомендуется использовать два инбаунда в одной панели 3x-ui. Первый — VLESS Reality на 443 порту, который будет основным рабочим каналом. Второй — VLESS XHTTP за CDN, который станет резервным на случай блокировки IP-адреса.

Настройка первого инбаунда в 3x-ui выглядит следующим образом. Зайдите в веб-панель администратора, перейдите в раздел «Входящие» (Inbounds) и нажмите «Добавить входящее». В открывшейся форме укажите:

  • Remark — любое имя, например, reality-443.
  • Protocol — выберите vless.
  • Port — 443 (или другой, если он свободен).
  • Transmission — raw (в старых версиях tcp).
  • Security — reality.

Затем перейдите на вкладку безопасности и настройте параметры Reality:

  • Dest / SNI — укажите чужой домен, который поддерживает TLS 1.3 и HTTP/2, например, www.samsung.com. Важно, чтобы этот домен не был заблокирован в РФ и не принадлежал вашему хостинг-провайдеру. Избегайте слишком популярных доменов вроде www.cloudflare.com, так как их массовое использование привлекает внимание.
  • Private / Public key — сгенерируйте ключи с помощью кнопки Get New Cert или вручную командой /usr/local/x-ui/bin/xray-linux-amd64 x25519. Приватный ключ остаётся на сервере, публичный (в новых версиях он называется Password) попадает в клиентскую ссылку.
  • Short IDs — сгенерируйте идентификатор командой openssl rand -hex 8. Можно указать несколько.
  • uTLS (fingerprint) — выберите chrome, чтобы имитировать отпечаток браузера.

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

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: второй инбаунд

Второй инбаунд — VLESS XHTTP — создаётся как резервный канал, который работает через CDN. Это особенно полезно, когда ваш IP-адрес уже заблокирован или оператор использует whitelist-режим. В отличие от Reality, здесь TLS терминируется на стороне CDN, поэтому до вашего сервера доходит уже расшифрованный HTTP-трафик.

В 3x-ui создайте новый инбаунд со следующими параметрами:

  • Transmission — выберите xhttp.
  • Security — none, так как шифрование обеспечивает CDN.
  • Listening IP — если CDN-фронт находится на том же сервере, укажите 127.0.0.1. В противном случае можно оставить пустым (0.0.0.0) и настроить фаервол, разрешающий подключения только с IP-адресов CDN.
  • Port — выберите нестандартный локальный порт, например, 25454.
  • Path — задайте длинный и неугадываемый путь, например, /api/v1/sync/. Этот путь должен совпадать с настройками на CDN.
  • Host — укажите домен CDN-edge, который будет видеть клиент.
  • Mode — обязательно packet-up, если ваш CDN не поддерживает POST-запросы (как Yandex CDN).

Важный момент: режим packet-up использует GET-запросы для передачи данных от клиента, поэтому он совместим с CDN, которые не поддерживают POST. Если оставить auto, клиент может выбрать режим с POST, что приведёт к ошибкам. Также убедитесь, что параметры extra на сервере и клиенте совпадают полностью. Эти параметры задаются только в JSON-редакторе инбаунда (иконка </>). Пример JSON:

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

После создания инбаунда обязательно проверьте доступность через CDN: curl -s -o /dev/null -w '%{http_code}' https://edge.example.com/api/v1/sync/. Если получаете 404 — путь не проброшен на CDN, если соединение висит — проверьте mode и extra.

Как собрать клиентскую ссылку для XHTTP-инбаунда

Одна из особенностей 3x-ui заключается в том, что автоссылка из панели всегда генерируется с IP-адресом ноды, что не работает для инбаунда за CDN. Поэтому клиентскую ссылку для XHTTP нужно собирать вручную. Это делается один раз на инбаунд, а дальше меняется только UUID.

Формат ссылки VLESS XHTTP выглядит следующим образом:

vless://UUID@ADDRESS: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#имя-узла

Где:

  • UUID — идентификатор клиента, который вы создали в панели.
  • ADDRESS — домен CDN, через который идёт подключение (не IP ноды).
  • security=tls — указывает, что используется TLS, хотя на самом деле он терминируется на CDN.
  • sni и host — должны совпадать с доменом CDN-edge.
  • path — URL-кодированный путь, который вы указали в инбаунде.
  • mode — режим XHTTP (packet-up).
  • extra — URL-кодированный JSON с дополнительными параметрами (если они есть).

Важно, чтобы параметры mode и extra в ссылке точно совпадали с теми, что на сервере. Если клиент при импорте теряет extra (некоторые приложения это делают), лучше создавать конфигурацию вручную или использовать JSON-подписку. Также обратите внимание, что поле flow для XHTTP должно быть пустым, так как flow xtls-rprx-vision работает только с raw/tcp.

Настройка подписки и управление клиентами в 3x-ui

Для удобства раздачи конфигураций нескольким абонентам в 3x-ui предусмотрена система подписок. Она позволяет сгруппировать несколько инбаундов (например, Reality и XHTTP) в одну ссылку, по которой клиент автоматически получает все доступные узлы.

Настройка подписки находится в разделе Panel Settings → Subscription. По умолчанию подписка работает на порту 2096, путь /sub/, JSON-версия — /json/. У каждого клиента в его настройках должен быть заполнен Subscription ID — по нему панель группирует конфиги. Когда клиент переходит по ссылке подписки, он получает список всех инбаундов, привязанных к его Subscription ID.

Для каждого клиента также можно задать лимиты трафика (totalGB) и срок действия. Эти параметры рассчитываются на основе Email-метки клиента, поэтому важно, чтобы метки были уникальными в пределах всей панели. Дубликаты меток приводят к сбоям в учёте трафика и автоотключении.

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

Типовые ошибки и их диагностика

При настройке VLESS XHTTP и Reality пользователи часто сталкиваются с типичными проблемами. Рассмотрим их и способы решения.

Ошибка «failed to find user / invalid user» — означает, что UUID в клиентской ссылке не совпадает с UUID, созданным в панели. Решение: пересоздайте ссылку из панели, не редактируйте UUID вручную.

Клиент показывает «connected», но трафик не идёт — для Reality это часто связано с перепутанными приватным и публичным ключами. Помните, что в выводе команды x25519 поле Password — это публичный ключ (pbk). Также проверьте, совпадают ли sid, sni и fp.

XHTTP за CDN: edge отдаёт 404 — означает, что путь не проброшен на CDN или не совпадает с path в инбаунде. Выровняйте настройки пути на фронте и в инбаунде.

XHTTP: соединение висит, данные не передаются — скорее всего, режим mode разъехался (auto против packet-up). Установите packet-up с обеих сторон.

Ошибка unexpected EOF — служебные данные ушли в кастомный заголовок, который CDN срезал. Переложите uplink и служебные ключи в тело запроса, query или cookie.

Работает в одном приложении, но не работает в другом — клиент не понял extra или подставил свой mode. Уберите редкие поля обфускации и оставьте минимум.

Инбаунд «есть», но порт не слушается — порт занят панелью или другим инбаундом. Проверьте с помощью ss -tlnp | grep xray и смените порт.

Для диагностики полезно смотреть логи Xray. На время отладки установите уровень лога info в Xray Configuration → Log, после — верните обратно на warning, чтобы логи не забивали диск.

Практические рекомендации и ограничения XHTTP

При использовании XHTTP важно учитывать несколько ограничений и следовать рекомендациям, чтобы избежать проблем:

  • Совместимость версий. XHTTP активно развивается, поэтому убедитесь, что версии Xray на клиенте и сервере одинаковы. В противном случае возможны странные глюки или полная неработоспособность.
  • Клиенты. Не все клиенты поддерживают XHTTP. Клиенты на базе Sing-box не умеют работать с XHTTP, в то время как v2rayN и v2rayNG работают без проблем. Для iOS можно использовать Shadowrocket или Karing, для Windows — v2rayN или Hiddify, для macOS — Karing.
  • XTLS-Vision несовместим. XHTTP нельзя использовать вместе с XTLS-Vision, так как защита от детектирования обеспечивается через мультиплексирование (XMUX) и разделение потоков.
  • XTLS-Reality совместим. XHTTP можно комбинировать с XTLS-Reality, в этом случае по умолчанию выбирается режим stream-one.
  • Не злоупотребляйте обфускацией. Чем экзотичнее поля обфускации, тем выше шанс, что клиент на другой версии Xray их не поймёт. Начинайте с минимальной конфигурации и добавляйте параметры только по мере необходимости.
  • Закрывайте origin. Если ваш XHTTP-инбаунд не за CDN, обязательно ограничьте доступ по IP с помощью фаервола, иначе открытый порт будет найден сканерами в течение суток.
  • Используйте оба инбаунда. На практике Reality забирает около 90% трафика, а XHTTP служит резервным каналом, который включается, когда основной недоступен. Оба инбаунда можно отдавать одной подпиской, и клиент сам переберёт точки входа.

Часто задаваемые вопросы

Ниже собраны ответы на распространённые вопросы о настройке 3x-ui с VLESS XHTTP.

Вопросы и ответы

Что такое XHTTP и чем он отличается от XTLS-Reality?

XHTTP — это транспортный механизм, который маскирует прокси-трафик под HTTP-запросы и может работать через CDN. XTLS-Reality — это технология, которая имитирует handshake реального TLS-сервера, чтобы скрыть факт использования прокси. Reality работает только с TLS v1.3 и не использует CDN, тогда как XHTTP поддерживает TLS v1.2 и может работать за CDN. Их можно комбинировать: в 3x-ui часто создают два инбаунда — VLESS Reality для прямого подключения и VLESS XHTTP за CDN как резерв.

Какой режим XHTTP выбрать для работы через Yandex CDN?

Для Yandex CDN, который не поддерживает POST-запросы, необходимо выбирать режим packet-up. В этом режиме данные от клиента к серверу передаются через GET-запросы, что совместимо с этим CDN. Если оставить auto, клиент может выбрать режим с POST, что приведёт к ошибкам и зависанию соединения. Поэтому в настройках инбаунда и в клиентской ссылке явно указывайте mode=packet-up.

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

3x-ui генерирует автоссылки с IP-адресом ноды напрямую, игнорируя CDN. Для инбаунда XHTTP за CDN клиент должен подключаться к домену CDN, а не к IP сервера. Поэтому ссылку нужно собирать вручную, указав в поле address домен CDN-edge, а также параметры type=xhttp, security=tls, host, path, mode и extra, которые совпадают с настройками на сервере.

Можно ли использовать XHTTP вместе с XTLS-Vision?

Нет, XHTTP несовместим с XTLS-Vision. XTLS-Vision использует механизм прямого прохождения трафика, который конфликтует с мультиплексированием XMUX и разделением потоков, применяемыми в XHTTP. Для XHTTP оставляйте поле flow пустым. Если вам нужен flow xtls-rprx-vision, используйте транспорт raw (tcp) с Security reality.

Как проверить, что Reality-инбаунд правильно настроен?

Выполните на сервере команду: openssl s_client -connect NODE_IP:443 -servername www.samsung.com </dev/null 2>/dev/null | openssl x509 -noout -issuer -subject. Если в выводе указан сертификат домена www.samsung.com (или того домена, который вы указали в Dest), значит, Reality работает. Если указан ваш собственный сертификат (например, Let's Encrypt), то Reality не активирован.

Почему клиент на Sing-box не подключается к XHTTP-узлу?

Клиенты на базе Sing-box (например, некоторые версии Hiddify) не поддерживают транспорт XHTTP, так как он реализован только в Xray-core. Используйте клиенты на базе Xray: v2rayN (Windows), v2rayNG (Android), Shadowrocket (iOS) или Karing (iOS/macOS). Убедитесь также, что версии Xray на клиенте и сервере совпадают.