Зачем прятать вход x-ui за CDN
В РФ при блокировках и локальных шатдаунах мобильные операторы нередко переводят интернет в режим белого списка: доступны только whitelisted-ресурсы — часть CDN, госсайты, платёжные шлюзы. VPN-нода, к которой клиент ходит напрямую по её IP, в этот момент просто перестаёт отвечать — её подсети нет в белом списке.
Решение на уровне инфраструктуры: вход VPN прячут за whitelisted CDN-edge (например, на базе Yandex CDN). Для оператора связи трафик выглядит как обычное обращение к «белому» CDN-домену, а edge уже проксирует соединение на вашу origin-ноду с x-ui. Сама нода при этом может стоять на любом хостинге — наружу, в сторону абонента, торчит только CDN.
Важно не путать две разные задачи. Пробить троттлинг (заставить туннель работать в режиме белого списка) whitelist-CDN решает. А разблокировать российский стриминг вроде Kinopoisk — нет: такие сервисы банят датацентр-IP по репутации, и для них нужен резидентный адрес. Это отдельная история, и CDN её не закрывает.
Whitelist привязан к подсети /24
Белый список — это не «весь хостер целиком», а конкретные подсети /24. У одного провайдера подсеть может быть в списке, у соседней /24 того же провайдера — уже нет. Статус меняется со временем, поэтому проверять нужно каждую /24 отдельно и актуально на момент запуска, без расчёта на «навсегда».
Проверяется не origin-нода (она может стоять где угодно), а точка входа — IP, который видит оператор связи. При управляемом Yandex CDN это уже whitelisted-диапазоны edge. Если вы строите собственный шлюз перед нодой — выбирайте хостера, чья /24 в белом списке.
| Точка входа | Наблюдаемый статус | Комментарий |
|---|---|---|
| Управляемый CDN-edge (Yandex CDN) | Обычно whitelisted | Edge в «белых» диапазонах CDN |
| Selectel (свой шлюз) | Часто whitelisted | Проверять конкретную /24 |
| cloud.ru / SberCloud | Часто НЕ whitelisted | Под задачу входа обычно не годится |
Цифры в таблице — это наблюдаемая практика, а не гарантия. Перед продом всегда перепроверяйте /24 под своим оператором и регионом.
Почему XHTTP, а не Reality или Hysteria2
Через CDN-edge проходит только то, что выглядит как валидный HTTP. Поэтому рабочий транспорт за CDN — XHTTP в режиме packet-up (x-ui xhttp): он укладывается в HTTP-семантику, которую edge понимает и проксирует на origin.
Reality и Hysteria2 напрямую под троттлингом в режиме белого списка обычно не проходят: edge не пропускает их протоколы к origin, а прямого маршрута к ноде у абонента в этот момент нет. Отсюда простое правило: за whitelisted CDN держат XHTTP-инбаунд, а Reality/Hysteria2 при желании оставляют как отдельный прямой профиль для ситуаций без ограничений.
Минус XHTTP — он плодит много мелких HTTP-запросов, что влияет и на стабильность, и на стоимость (об этом ниже). Частично это лечится тем, что uplink уходит крупными POST-ами в теле.
Ключевой момент: uplink в теле, а не в заголовке
Это самая неочевидная и самая частая причина, по которой «всё настроил, а туннель не поднимается».
По умолчанию некоторые сборки кладут uplink-данные в кастомный заголовок (например, X-Payload). Напрямую это работает, но через CDN — нет: edge не обязан доносить произвольные кастомные заголовки до origin, он их режет. В результате origin не получает тело сессии, и туннель рвётся с характерным unexpected EOF.
Правильная раскладка данных для XHTTP за CDN:
- uplink → тело запроса:
uplinkDataPlacement: "body"— данные едут в body POST-запроса, который CDN обязан передать на origin; - session id / seq → cookie: cookie CDN прокидывает надёжнее кастомных заголовков;
- padding → query-строка: вспомогательные параметры уносим в URL.
Бонус: крупные POST-ы в body ещё и снижают число мелких запросов, что напрямую бьёт по стоимости трафика.
Настройка XHTTP-инбаунда в x-ui и клиентский конфиг
На стороне ноды в x-ui (3x-ui) поднимается XHTTP-инбаунд на локальном порту, куда edge будет проксировать соединения — например, 25454. Наружу этот порт не публикуется, он доступен только со стороны gateway.
Главное требование к паре «клиент ↔ нода» — точное совпадение. Разъедется хоть один символ в path или в блоке extra — туннель не поднимется, часто без внятной ошибки. Сверяйте побайтово.
В клиентском конфиге:
- Address / SNI / Host — указывают на CDN-поддомен (не на IP ноды);
- path — тот же, что на инбаунде ноды, символ в символ;
- extra (mode, uplinkDataPlacement, cookie/query-раскладка) — идентичен серверному.
Подход одинаково применим к x-ui, Remnawave, Marzban и Hiddify — меняется только UI панели, логика «CDN-поддомен снаружи, XHTTP-инбаунд на origin, совпадающие path/extra» остаётся той же.
Защита origin, учёт трафика и экономика
Защита origin. Раз весь легитимный трафик приходит только от edge, origin надо закрыть от прямых обращений мимо CDN:
- файрвол на вход — разрешить только IP gateway/edge;
- секрет-заголовок
X-Cdn-Auth— edge добавляет его к каждому запросу, origin отклоняет всё без валидного значения. Это отсекает сканеры и попытки достучаться до ноды напрямую.
Учёт трафика. В панелях вроде Remnawave есть множитель потребления ноды и per-user лимиты. Множитель 0 на CDN-ноде означает, что её трафик не списывается против лимита пользователя (нода при этом работает штатно) — удобно, если CDN-канал вы тарифицируете отдельно от общего лимита.
Прайс за гигабайт — только половина счёта. Вторая половина у части провайдеров это запросы, а XHTTP в режиме packet-up дробит аплинк на множество мелких обращений. Крупные POST-ы в body уменьшают число запросов и тянут кост вниз, поэтому раскладка uplink в тело важна не только для работоспособности, но и для денег.
Если поднимать и держать актуальным собственный whitelisted-вход не хочется, эту часть можно взять как сервис: Clearway (clear-way.pro) даёт операторам whitelisted CDN-вход перед их нодами (edge-домен *.whitechannel-x1-cdn.ru), без продажи серверов — вы оставляете свою x-ui-ноду как origin, а «белую» точку входа и её актуальность по /24 берёт на себя провайдер.