Skip to content
RUEN

VLESS через XHTTP и gRPC: установка и настройка ​

XHTTP и gRPC упаковывают VLESS в обычные HTTP/2-запросы к вашему сайту. Снаружи работает nginx с настоящим сертификатом и настоящей страницей, а Xray получает только запросы на секретный адрес. Такой вход пригодится, когда прямой VLESS по TCP у вашего провайдера подвисает или рвётся.

Ниже настройка с чистого сервера: один nginx на порту 443 и оба транспорта рядом, чтобы переключаться между ними простой заменой ссылки в клиенте.

XHTTP, gRPC и Reality на OBLAKO

Эти транспорты, как и Reality, на OBLAKO разрешены для личного VPN для себя и своего домашнего круга, если сервер настроен по нашим инструкциям, а в SNI стоит ваш собственный домен. Сервер, который показывает сертификат популярного чужого сайта, система выключает автоматически. Полные правила описаны в AUP.

Все конфиги из статьи мы запускали на Ubuntu 24.04 с nginx 1.24 и Xray 26.10.31 в ноябре 2026 года. В каждом варианте через туннель прошло по 20 МБ в обе стороны без искажений, а соединение пережило 130 секунд простоя. Это проверка настройки, а не обхода блокировок: реальное поведение зависит от оператора.

XHTTP или gRPC ​

XHTTPgRPC
Статус в Xrayосновной транспорт, развиваетсяобъявлен устаревшим, может быть удалён
Настройка за nginxсекретный путьсекретное имя сервиса
Выбор режимаpacket-up, stream-up, stream-onegun, multi
Клиентына ядре Xrayна ядре Xray и sing-box

Начинайте с XHTTP. При запуске с gRPC сам Xray пишет в лог прямое предупреждение:

text
The feature gRPC transport (with unnecessary costs, etc.) is deprecated, not recommended
for using and might be removed. Please migrate to XHTTP stream-up H2 as soon as possible.

gRPC пока работает, и добавить его почти ничего не стоит: это ещё один блок в конфигах. Держите его как запасной вход и для клиентов без поддержки XHTTP, но проверяйте описание релиза перед обновлением Xray.

Что известно о работе в России ​

Данных мало, и почти все они взяты из отдельных сообщений пользователей. Гарантий не даёт ни один транспорт.

  • Оба транспорта не бессмертны. На Хабре сообщали, что по состоянию на 5 июня 2026 года XHTTP и gRPC уже попадали под частичные блокировки в Сибири.
  • Иногда спасает смена транспорта. 13 апреля пользователь ntc.party описал, как на сервере в Германии обрывался XHTTP с Reality, а gRPC с Reality на том же адресе заработал.
  • Иногда не спасает. В той же теме другой пользователь рассказал, что его gRPC за nginx не работал примерно сутки, с вечера 10 апреля до вечера 11 апреля.
  • Ограничение по адресу транспортом не лечится. В заметке о транспортах от 4 ноября отмечено, что некоторые подсети попадают под блок на 16 КБ. Как это проверить, показано ниже.
  • Много параллельных соединений заметно. Участники обсуждения на net4people в конце 2025 года связывали срабатывание с числом одновременных TLS-соединений к одному хосту. Выводы там предварительные, но держать доступ личным и не раздавать его десяткам устройств полезно в любом случае.

Если на мобильном интернете включены белые списки, не поможет ни один из этих вариантов. Про этот случай есть отдельная статья: белые списки и каскад.

Что нужно перед началом ​

  • VPS с Ubuntu 22.04, 24.04 или Debian 12 и доступ по SSH.
  • Свой домен, A-запись которого указывает на IP сервера. CDN не включайте. Как выбрать подходящее имя, рассказано в статье Домен для self-steal. Слова vpn, proxy, node в имени использовать нельзя.

В командах и конфигах встречаются четыре значения, которые нужно заменить на свои:

ЗначениеОткуда взять
ВАШ_ДОМЕНваш домен или поддомен
ВАШ_UUIDкоманда xray uuid на шаге 3
ПУТЬ_XHTTPкоманда openssl rand -hex 8
ИМЯ_GRPCещё один запуск openssl rand -hex 8

Путь и имя сервиса работают как второй пароль: кто их не знает, увидит только ваш сайт. Не используйте /xhttp, /grpc или примеры из чужих инструкций.

Шаг 1. Получите сертификат ​

bash
apt update && apt upgrade -y
apt install -y nginx certbot
certbot certonly --webroot -w /var/www/html -d ВАШ_ДОМЕН --deploy-hook "systemctl reload nginx"

На этом этапе отвечает стандартная страница nginx, через неё certbot и подтверждает домен.

Сразу создайте страницу, которую увидит случайный посетитель. Лучше написать пару осмысленных строк о себе или проекте, чем оставлять заглушку:

bash
mkdir -p /var/www/site
nano /var/www/site/index.html

Шаг 2. Настройте nginx ​

В этой схеме TLS целиком держит nginx. Xray не работает с сертификатами и слушает только локальные порты, поэтому ему не нужен доступ к ключам Let's Encrypt.

Удалите стандартный сайт и создайте /etc/nginx/sites-available/site:

bash
rm /etc/nginx/sites-enabled/default
nano /etc/nginx/sites-available/site
nginx
server {
    listen 80;
    server_name ВАШ_ДОМЕН;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    server_name ВАШ_ДОМЕН;

    ssl_certificate /etc/letsencrypt/live/ВАШ_ДОМЕН/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ВАШ_ДОМЕН/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    root /var/www/site;
    index index.html;

    client_header_timeout 5m;
    keepalive_timeout 5m;

    location /ПУТЬ_XHTTP/ {
        client_max_body_size 0;
        client_body_timeout 1h;
        grpc_read_timeout 1h;
        grpc_send_timeout 1h;
        grpc_pass grpc://127.0.0.1:10080;
    }

    location /ИМЯ_GRPC/ {
        if ($content_type !~ "^application/grpc") {
            return 404;
        }

        client_max_body_size 0;
        client_body_timeout 1h;
        grpc_read_timeout 1h;
        grpc_send_timeout 1h;
        grpc_pass grpc://127.0.0.1:10081;
    }
}

Что здесь важно:

  • grpc_pass стоит в обоих блоках, в том числе для XHTTP. Так nginx говорит с Xray по HTTP/2, этот вариант рекомендует автор XHTTP.
  • client_max_body_size 0 снимает ограничение на размер запроса. Со стандартным лимитом в 1 МБ отправка больших файлов обрывается в stream-up и gRPC.
  • Без увеличенных таймаутов nginx закрывает простаивающий туннель уже через минуту.
  • Проверка $content_type прячет имя сервиса gRPC от обычных запросов: браузер получит 404.
  • Запись listen ... http2 на новых версиях nginx вызывает предупреждение. Это не ошибка, зато такой конфиг понимает nginx из репозиториев всех перечисленных систем.

Включите сайт:

bash
ln -s /etc/nginx/sites-available/site /etc/nginx/sites-enabled/site
nginx -t && systemctl reload nginx

Шаг 3. Установите Xray ​

bash
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
xray version
xray uuid

Версия должна быть не ниже 26.10.31: в ней закрыта серьёзная уязвимость, подробности в статье Xray в 2026.

Шаг 4. Настройте Xray ​

Откройте /usr/local/etc/xray/config.json и вставьте конфиг целиком. Если на сервере уже работает Xray, ничего не перезаписывайте: добавьте два объекта из inbounds к своим.

json
{
  "log": { "loglevel": "warning" },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 10080,
      "protocol": "vless",
      "settings": {
        "clients": [{ "id": "ВАШ_UUID" }],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "xhttp",
        "xhttpSettings": { "path": "/ПУТЬ_XHTTP/" }
      }
    },
    {
      "listen": "127.0.0.1",
      "port": 10081,
      "protocol": "vless",
      "settings": {
        "clients": [{ "id": "ВАШ_UUID" }],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "grpc",
        "grpcSettings": { "serviceName": "ИМЯ_GRPC" }
      }
    }
  ],
  "outbounds": [
    { "protocol": "freedom", "tag": "direct" }
  ]
}

Блока security здесь нет намеренно: снаружи шифрование обеспечивает nginx, а эти порты доступны только с самого сервера. Строка flow тоже не нужна, Vision на этих транспортах без VLESS Encryption не работает.

Запустите Xray и откройте порты, если включён UFW:

bash
xray run -test -c /usr/local/etc/xray/config.json
systemctl restart xray
ufw allow 80/tcp
ufw allow 443/tcp

Шаг 5. Проверьте сервер ​

Запросы должны вернуть три разных кода:

bash
curl -s -o /dev/null -w "%{http_code}\n" https://ВАШ_ДОМЕН/
curl -s -o /dev/null -w "%{http_code}\n" https://ВАШ_ДОМЕН/ПУТЬ_XHTTP/
curl -s -o /dev/null -w "%{http_code}\n" https://ВАШ_ДОМЕН/ИМЯ_GRPC/Tun
АдресОжидаемый кодЧто значит
сайт200nginx и сертификат работают
путь XHTTP400запрос дошёл до Xray и отклонён как неполный
путь gRPC404сработала проверка $content_type

Код 502 на пути XHTTP означает, что nginx не достучался до Xray: проверьте systemctl status xray.

Шаг 6. Подключите клиента ​

Импортируйте ссылку в клиент на ядре Xray, например v2rayN или v2rayNG. Косая черта в пути записывается как %2F.

XHTTP:

text
vless://ВАШ_UUID@ВАШ_ДОМЕН:443?encryption=none&security=tls&sni=ВАШ_ДОМЕН&fp=chrome&alpn=h2&type=xhttp&path=%2FПУТЬ_XHTTP%2F&mode=stream-up#site-xhttp

gRPC:

text
vless://ВАШ_UUID@ВАШ_ДОМЕН:443?encryption=none&security=tls&sni=ВАШ_ДОМЕН&fp=chrome&alpn=h2&type=grpc&serviceName=ИМЯ_GRPC&mode=gun#site-grpc

В приложении с ручным вводом значения те же: транспорт xhttp или grpc, TLS, ALPN h2, SNI с вашим доменом. Клиенты на чистом sing-box, в частности Hiddify, могут не принять XHTTP. Для них подойдёт ссылка gRPC.

Какой режим выбрать ​

Сервер принимает любой режим XHTTP, поэтому менять его можно только в ссылке клиента, параметром mode:

РежимКак передаёт данныеКогда брать
stream-upотправка и получение двумя долгими запросамиосновной вариант, его советует само предупреждение Xray
packet-upотправка множеством коротких запросовесли посредник буферизует долгие запросы и туннель зависает
stream-oneвсё в одном запросезапасной вариант, если не проходят первые два

В нашем тесте packet-up отправлял данные примерно на треть медленнее остальных режимов: 11,8 МБ/с против 19 МБ/с. Абсолютные цифры сняты на одной машине, важно только соотношение.

Значение auto лучше не оставлять без причины. В обсуждении автора указано, что с TLS и HTTP/2 оно выбирает stream-up, но Xray 26.10.31 в нашей проверке выбирал packet-up.

Для gRPC оставьте gun. Режим multi документация Xray считает экспериментальным, а прибавки к скорости в нашем тесте он не дал.

Вариант с Reality ​

Если вы настроили self-steal, XHTTP и gRPC можно включить прямо внутри Reality, без grpc_pass. Такой вход занимает порт целиком, так что на 443 поместится только один из них. Остальные настройки self-steal не меняются, nginx по-прежнему отвечает на 127.0.0.1:8443.

В существующем подключении уберите flow у пользователя и замените streamSettings. Ключи и shortIds оставьте свои.

Для XHTTP:

json
"streamSettings": {
  "network": "xhttp",
  "xhttpSettings": { "path": "/ПУТЬ_XHTTP/" },
  "security": "reality",
  "realitySettings": {
    "target": "127.0.0.1:8443",
    "serverNames": ["ВАШ_ДОМЕН"],
    "privateKey": "ВАШ_PRIVATE_KEY",
    "shortIds": ["ВАШ_SHORT_ID"]
  }
}

Для gRPC замените первые две строки:

json
"network": "grpc",
"grpcSettings": { "serviceName": "ИМЯ_GRPC" },

Ссылки для клиента:

text
vless://ВАШ_UUID@ВАШ_ДОМЕН:443?encryption=none&security=reality&sni=ВАШ_ДОМЕН&fp=chrome&pbk=ВАШ_PUBLIC_KEY&sid=ВАШ_SHORT_ID&type=xhttp&path=%2FПУТЬ_XHTTP%2F&mode=stream-one#site-reality-xhttp
vless://ВАШ_UUID@ВАШ_ДОМЕН:443?encryption=none&security=reality&sni=ВАШ_ДОМЕН&fp=chrome&pbk=ВАШ_PUBLIC_KEY&sid=ВАШ_SHORT_ID&type=grpc&serviceName=ИМЯ_GRPC&mode=gun#site-reality-grpc

В обоих случаях в SNI и serverNames стоит только ваш домен. С чужим доменом сервер будет выключен автоматически, какой бы транспорт ни использовался.

Если провайдер мешает ​

Прежде чем перебирать настройки, выясните, что именно ограничено. Положите на сервер файл размером 1 МБ:

bash
head -c 1M /dev/urandom > /var/www/site/test.bin

С проблемного интернета, с выключенным VPN, выполните:

bash
curl -o /dev/null -w "%{http_code} %{size_download}\n" --max-time 30 https://ВАШ_ДОМЕН/test.bin
РезультатВероятная причинаЧто делать
200 1048576адрес доступен, мешают протокол или поведениесменить транспорт или режим, попробовать fp=firefox
Обрыв примерно на 16 КБограничение на адрес или подсетьперейти к статье про проверку блокировки IP
Таймаут сразуадрес не отвечает с этой сетипроверить другие сети по той же статье
Не открываются никакие зарубежные сайтына мобильной сети включены белые спискисмотреть статью про каскад

Закончив проверку, удалите файл: rm /var/www/site/test.bin.

Обратите внимание, что обычная страница сайта помещается в 16 КБ и откроется даже при таком ограничении. Поэтому открывшийся сайт ещё не доказывает, что с адресом всё в порядке.

Частые ошибки ​

СимптомПричина и решение
Сайт открывается, а клиент не подключается ни по одной ссылкеНет HTTP/2 в listen. Строка должна быть listen 443 ssl http2;
Сайт открывается, VPN подключается, но трафика нетПуть или имя сервиса различаются в nginx, Xray и ссылке. В serviceName не ставьте косую черту
Туннель обрывается примерно через минуту простояВ location нет grpc_read_timeout и client_body_timeout
Большие файлы не отправляютсяВ location нет client_max_body_size 0
Через VPN не открываются адреса вида 127.0.0.1 или 192.168.x.xXray по умолчанию не пускает трафик клиентов на частные адреса. В логе видно blocked target. Так и задумано, разрешать это без необходимости не стоит
Клиент пишет про неизвестный транспорт xhttpКлиент на старом ядре или на sing-box. Обновите его или используйте ссылку gRPC
Xray с Reality и mode=auto даёт unexpected response versionТакое встречалось на старых версиях. Обновите Xray и укажите mode=stream-one
В journalctl -u xray предупреждение про gRPCЭто не ошибка, gRPC работает. Текст разобран выше

Если вход работает у одного оператора и не работает у другого, сравните со статьёй VLESS Reality перестал работать: порядок диагностики там тот же, хотя транспорт другой.