Что такое 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 на клиенте и сервере совпадают.