Блог Clearway

XHTTP через CDN: полное руководство для VPN-операторов

Коротко

Чтобы VPN-нода не отваливалась в момент, когда мобильный оператор переводит сеть в режим белого списка, вход прячут за whitelisted CDN-edge: клиент обращается к «белому» CDN-поддомену, а тот проксирует трафик на origin-ноду. Рабочий транспорт под троттлингом — VLESS XHTTP в режиме packet-up; Reality и Hysteria2 напрямую edge обычно не пропускает. Ключевой нюанс: uplink-данные должны идти в теле запроса (uplinkDataPlacement: "body"), а не в кастомном заголовке — иначе CDN не донесёт их до origin и туннель порвётся с ошибкой «unexpected EOF».

Почему прямой VPN отваливается под троттлингом

Когда мобильный оператор в РФ сталкивается с требованием ограничить доступ или проходит через локальный шатдаун, сеть часто переводится не в полный офф, а в режим «белого списка». В этом режиме мобильный интернет пропускает трафик только к whitelisted-ресурсам: части CDN, государственным и инфраструктурным сайтам. Всё остальное — включая прямое TCP/UDP-соединение с вашей VPN-нодой — просто не устанавливается.

Для оператора это выглядит так: сервис работает в обычном режиме, но в момент ограничения все клиенты в затронутом регионе одновременно теряют коннект к ноде. Пинги до IP ноды не проходят, handshake не начинается. Проблема не в конфиге и не в блокировке протокола по DPI — сам маршрут до датацентрового IP закрыт на уровне оператора.

Отсюда вывод, который меняет архитектуру: под троттлингом нельзя ходить напрямую к своему серверу. Клиент должен обращаться к адресу, который оператор считает «белым». Единственный практичный способ получить такой адрес — спрятать вход за whitelisted CDN-edge.

Как whitelist-CDN закрывает вход: архитектура

Идея проста: между клиентом и нодой ставится CDN-edge, чей диапазон адресов попадает в белые списки операторов. Клиент подключается не к IP ноды, а к CDN-поддомену. Для оператора это выглядит как обычное обращение к «белому» CDN; CDN, в свою очередь, проксирует запрос на ваш origin — ноду с VPN-инбаундом.

ЗвеноЧто видит операторЧто происходит на самом деле
Клиент → CDN-edgeЗапрос к whitelisted CDNTLS-сессия к «белому» поддомену
CDN-edge → origin(трафик уже вне моб. сети)Проксирование на ноду по HTTP(S)
origin (нода)XHTTP-инбаунд принимает туннель

Ключевое свойство схемы: адрес, к которому идёт клиент, и адрес вашей ноды — разные. Нода может стоять на «сером» хостере, который сам по себе не whitelisted, потому что клиент до него напрямую не ходит. Белым должен быть только edge.

Именно этот «белый вход перед нодой» и продаёт Clearway (clear-way.pro) как сервис: оператор получает whitelisted CDN-поддомен (*.whitechannel-x1-cdn.ru) перед своей инфраструктурой, не покупая и не арендуя серверы под CDN.

Транспорт: почему XHTTP (packet-up), а не Reality или Hysteria2

Не любой транспорт переживёт прохождение через CDN. Reality и Hysteria2 напрямую под троттлингом обычно не проходят: Hysteria2 работает поверх QUIC/UDP, который edge либо не проксирует, либо режет, а Reality рассчитан на прямое TLS-соединение с нодой и теряет смысл, когда перед нодой стоит чужой CDN, терминирующий TLS.

XHTTP (наследник SplitHTTP) устроен иначе: он оформляет туннель как последовательность обычных HTTP-запросов. Для CDN это неотличимо от нормального веб-трафика, поэтому edge его прозрачно проксирует. Режим mode: packet-up дополнительно оптимизирует восходящий поток, что важно именно за CDN.

ТранспортЧерез whitelist-CDNПричина
VLESS XHTTP (packet-up)РаботаетВыглядит как HTTP-запросы, edge проксирует
RealityНе подходитНужен прямой TLS к ноде; CDN терминирует TLS
Hysteria2Обычно не проходитQUIC/UDP edge не пропускает

Поэтому базовая связка для устойчивости под ограничениями — VLESS XHTTP через CDN. Дальше — про настройку и главный подводный камень.

Главный подводный камень: uplink в теле запроса, а не в заголовке

Это самый неочевидный момент, на котором ломается большинство первых попыток. XHTTP умеет размещать восходящие (uplink) данные по-разному. Если оставить вариант, где полезная нагрузка едет в кастомном заголовке (например, X-Payload), туннель через CDN не поднимется: CDN-edge не обязан доносить произвольные кастомные заголовки до origin и, как правило, их отбрасывает. Клиент шлёт данные, до ноды они не доходят, соединение рвётся с характерной ошибкой unexpected EOF.

Лечится переносом uplink в тело запроса:

  • uplinkDataPlacement: "body" — полезная нагрузка едет в body POST-запроса, который CDN проксирует к origin как есть;
  • session / seq — в cookie (cookie CDN передаёт надёжнее кастомных заголовков);
  • padding — в query-параметрах URL.
Что кладёмКуда НЕ надоКуда надо
uplink-данныекастомный заголовок (X-Payload)тело запроса (body)
session / seqзаголовокcookie
paddingзаголовокquery

Правило простое: всё, что критично для туннеля, должно ехать по каналам, которые CDN гарантированно проксирует до origin — это body, cookie и URL. Нестандартные кастомные заголовки считайте ненадёжными.

Пошаговая настройка ноды и клиента

На стороне ноды поднимается XHTTP-инбаунд — например, на порту 25454, слушающий там, куда ходит только CDN. На стороне клиента в качестве Address / SNI / Host указывается CDN-поддомен, а не IP ноды.

Критично: path и весь блок extra (включая mode, uplinkDataPlacement, размещение session и padding) на клиенте и на ноде должны совпадать точь-в-точь. Любое расхождение в path или в одном из полей extra — и туннель не поднимется, даже если CDN и firewall настроены верно. Это частая причина «настроил по гайду, а не работает»: рассинхрон одного параметра.

Проверку удобно вести послойно, отсекая слои по одному:

  1. origin отвечает локально (нода поднята, инбаунд слушает);
  2. origin отвечает через CDN по HTTP (edge проксирует до ноды);
  3. поднимается полный туннель с клиента.

Если шаг 1 и 2 проходят, а туннель не встаёт — почти наверняка виноват рассинхрон path/extra или uplink в заголовке (см. предыдущую секцию).

Whitelist живёт на уровне /24: выбор хостера и подсети

Белые списки операторов привязаны не к домену CDN и не к ASN, а к подсетям — как правило, к блокам /24. Значит, «whitelisted» — свойство конкретного диапазона IP edge, а не бренда CDN целиком. У одного провайдера часть /24 в белых списках, часть — нет; статус со временем меняется.

Из практики распределение примерно такое (но проверять нужно всегда актуально и по каждой /24 отдельно):

Хостер / провайдерЧасто whitelisted
SelectelДа, встречается часто
cloud.ru / SberCloudЧасто нет

Гарантий здесь нет и быть не может: сегодня /24 проходит, завтра выпадает. Поэтому выбор edge — не разовое решение, а постоянный мониторинг статуса подсетей. Оператору, который не хочет держать это на себе, проще брать whitelisted-вход как сервис: Clearway как раз закрывает подбор и поддержание «белых» edge-подсетей, отдавая оператору стабильный поддомен перед его нодами.

Безопасность origin: закрыть ноду от прямых обращений

Как только вход спрятан за CDN, origin нужно защитить от обращений мимо CDN — иначе ноду легко найти сканером, и смысл «спрятанного» входа теряется.

Два уровня защиты:

  • Firewall на вход. Разрешить входящие только с IP gateway/CDN-edge, всё остальное — drop. Прямой коннект к порту 25454 с любого другого адреса не должен проходить.
  • Секрет-заголовок X-Cdn-Auth. CDN добавляет к проксируемым запросам секретный заголовок, а нода отвергает запросы без него. Это отсекает того, кто узнал IP ноды, но не знает секрета.

Вместе firewall и X-Cdn-Auth дают нужный результат: ноду видит только ваш CDN, а для всех остальных её как будто нет.

Экономика: сколько реально стоит трафик через CDN

CDN-трафик тарифицируется не только за гигабайты, но и за запросы — и для XHTTP это принципиально. Прайс за гигабайт — только половина счёта. Вторая половина у части провайдеров это запросы, а XHTTP в режиме packet-up дробит аплинк на множество мелких обращений.

Отсюда прямой инженерный рычаг: чем крупнее POST-запросы (больше данных в одном body), тем меньше суммарное число запросов и ниже стоимость. Настройки XHTTP, укрупняющие посты, снижают request-косты. Это ещё одна причина держать uplink в body — не только ради совместимости с CDN, но и ради экономики.

СоставляющаяПорядок величины
Сырой CDN-трафикзависит от провайдера
С учётом платы за запросы (на масштабе)зависит от провайдера

Учёт трафика в панели и чего CDN не решает

Панели (Remnawave, 3x-ui, Marzban, Hiddify) держат за CDN обычный XHTTP-инбаунд, поэтому учёт трафика остаётся штатным. В Remnawave полезны два механизма:

  • множитель потребления ноды: множитель 0 означает, что трафик через эту ноду не засчитывается против лимита пользователя — нода при этом работает;
  • per-user лимиты: как обычно, ограничивают потребление на аккаунт.

И важное разграничение, чтобы не обещать клиентам лишнего. Whitelist-CDN решает ровно одну задачу — пробить троттлинг/белый список оператора, чтобы туннель вообще поднялся. Он не разблокирует российский стриминг: сервисы вроде Kinopoisk банят датацентровые IP по репутации, и для их контента нужен резидентный IP. Это отдельная задача, которую whitelist-CDN не закрывает. «Пробить троттлинг» и «разблокировать стриминг» — разные вещи, и путать их не стоит.

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

Чем XHTTP через CDN отличается от старой связки VLESS + WebSocket + CDN?

WebSocket держит одно долгое соединение, которое некоторые edge и промежуточные прокси рвут по таймауту или не апгрейдят. XHTTP оформляет туннель как серию обычных HTTP-запросов, что для CDN выглядит естественнее и лучше переживает проксирование. Плюс режим packet-up и размещение uplink в body заточены именно под прохождение через edge.

Почему туннель рвётся с ошибкой «unexpected EOF»?

Почти всегда причина в том, что uplink-данные едут в кастомном заголовке, который CDN-edge отбрасывает и не доносит до origin. Переключите uplinkDataPlacement на body, session/seq положите в cookie, а padding — в query. После этого EOF, как правило, уходит.

Можно ли пустить Reality или Hysteria2 за whitelist-CDN?

Практически нет. Reality рассчитан на прямое TLS-соединение с нодой и ломается, когда TLS терминирует чужой CDN; Hysteria2 работает поверх QUIC/UDP, который edge обычно не проксирует. Под троттлингом рабочий вариант через CDN — VLESS XHTTP в режиме packet-up.

Как понять, что подсеть моего edge в белом списке?

Whitelist привязан к /24, поэтому проверять нужно конкретный диапазон edge, а не бренд CDN или ASN. Статус меняется во времени, гарантий нет — нужен регулярный мониторинг. Подсети Selectel встречаются в белых списках чаще, cloud.ru/SberCloud — реже, но это ориентир, а не правило.

Whitelist-CDN разблокирует Kinopoisk и другой российский стриминг?

Нет, это разные задачи. Whitelist-CDN пробивает троттлинг оператора, чтобы туннель вообще поднялся. Стриминг вроде Kinopoisk банит датацентровые IP по репутации, и для его контента нужен резидентный IP — whitelist-CDN этого не даёт.

Сколько реально стоит гигабайт трафика через CDN?

Считать по прайсу за гигабайт нельзя: CDN тарифицирует ещё и количество запросов, а XHTTP плодит много мелких обращений — итоговый счёт расходится с номиналом ₽/ГБ тем сильнее, чем интерактивнее трафик абонентов. Снизить стоимость помогает укрупнение POST-запросов: больше данных в одном body — меньше запросов и меньше request-костов.

Какие панели поддерживают XHTTP за CDN?

Remnawave, 3x-ui, Marzban и Hiddify — все они умеют держать XHTTP-инбаунд, за которым стоит CDN. Главное условие одинаково для всех: path и блок extra на ноде и на клиенте должны совпадать точь-в-точь. В Remnawave дополнительно удобны множитель потребления ноды и per-user лимиты для учёта трафика.

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

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

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