Блог Clearway

CDN для Remnawave: как настроить ноду за whitelisted-CDN и пережить белые списки

Коротко

CDN для Remnawave нужен не для скорости, а для выживания точки входа: при переходе оператора на белые списки прямой IP ноды в дата-центре отваливается первым. Клиент подключается не к IP ноды, а к домену CDN, edge-IP которого проходит фильтр — трафик доходит. Схема: клиент → CDN (белый IP, TLS на 443) → ваша нода (origin). Для этого нужен HTTP-транспорт, который CDN умеет проксировать (WebSocket, XHTTP, gRPC, HTTPUpgrade — не Reality), inbound без TLS в Config Profile, reverse-proxy с сертификатом на origin и Host в панели, где Address = SNI = Host-заголовок = домен CDN, а path совпадает во всех трёх местах. Начинайте с WebSocket как самого совместимого; XHTTP берите осознанно с явным mode.

Зачем ноде Remnawave вообще CDN перед собой

Механику белых списков разбираем отдельно — здесь только вывод. При блокировке по чёрным спискам режут конкретные домены и IP, и голая нода живёт долго. При переходе оператора на белый список логика инвертируется: проходит только явно разрешённое, всё остальное режется по умолчанию. IP вашей ноды на обычном не-российском VPS (Hetzner, DigitalOcean, любой не-whitelist хостинг) в белый список не входит по определению — падает первым и целиком, вместе с доменом, портом и протоколом.

CDN для Remnawave решает ровно одну задачу — подменяет точку входа. Клиент больше не стучится в IP ноды напрямую, он идёт на домен CDN, а edge-узел имеет IP, который либо уже в whitelist оператора, либо статистически переживает белые списки лучше одиночного VPS. Нода при этом остаётся где угодно — она становится origin'ом за фронтом.

Граница возможностей важна: CDN спасает доступность точки входа, но не делает трафик «легальным» и не прячет сам факт VPN от DPI по содержимому — за это отвечает транспорт. CDN и транспорт работают в паре, не заменяя друг друга.

Как устроена связка клиент → CDN → нода

Цепочка для Remnawave за CDN:

  1. Клиент (Happ, v2rayNG, Streisand) получает из подписки Host, где address — домен CDN, а не IP ноды.
  2. CDN edge принимает TLS на 443, терминирует его (сертификат на домен CDN) и по Host-заголовку и пути проксирует запрос на origin.
  3. Origin (ваша нода) получает уже расшифрованный CDN'ом HTTP-поток, а внутри него — туннель Xray.

Два следствия определяют всю дальнейшую настройку:

  • TLS терминируется на CDN. Значит Reality на фронте невозможен: Reality требует настоящий TLS-handshake напрямую с целевым сайтом, а CDN этот handshake перехватывает. За CDN живут только транспорты поверх HTTP — WebSocket, XHTTP, gRPC, HTTPUpgrade.
  • CDN видит только HTTP-обёртку, а не содержимое VLESS. Поэтому транспорт маскируется под обычный веб-запрос по пути (/path), а origin отвечает только на этот путь и молчит (404/заглушка) на всё остальное — иначе выглядит подозрительно.

Между CDN и origin желательно оставить второй слой TLS (режим origin-over-HTTPS, сертификат на отдельный origin-домен) — чтобы расшифрованный трафик не шёл открытым HTTP. Минимально рабочая схема допускает plain HTTP на origin за локальным reverse-proxy, но по integrity она хуже.

Выбор транспорта: WS, XHTTP, gRPC, HTTPUpgrade

Что реально ставить под CDN:

  • WebSocket (ws) — самый совместимый. Проксируется практически любым CDN, конфиг простой, всё решают path + Host. Минус — WS давно на радаре DPI как «типичный VPN-транспорт», но за whitelisted-CDN это вторично: задача CDN — доступность IP, а не невидимость.
  • XHTTP — современный транспорт Xray, гибче WS. Подводный камень именно на CDN: если CDN не пропускает POST и долгие стримы, оставляя только GET, XHTTP обязан работать в режиме packet-up (не stream-up). Отсюда классический баг «в одном приложении подписка работает, в другом нет» — часть клиентов не согласует режим. Ставите XHTTP за CDN — фиксируйте mode явно и тестируйте на нескольких клиентах. Детали XHTTP-режимов — в отдельной статье.
  • gRPC — работает только за CDN со сквозным HTTP/2. На практике многие CDN ломают gRPC на границе (буферизация, отсутствие end-to-end h2), поэтому капризнее WS.
  • HTTPUpgrade — по сути «WS без апгрейда до фрейминга», лёгкий и CDN-дружелюбный; хорошая альтернатива WS, если ваши клиенты его поддерживают.

Рекомендация: начните с WebSocket, а XHTTP берите осознанно, когда контролируете режим и готовы тестировать. Reality за CDN не протащить — не тратьте на это время.

Config Profile, inbound и reverse-proxy на ноде

В Remnawave транспорт задаётся в Config Profile (это Xray-конфиг с inbound'ами), нода использует выбранный inbound, а Host в подписке ссылается на него. Пример inbound VLESS+WebSocket, слушающего локально (TLS снимает reverse-proxy или сам CDN):

{
 "tag": "vless-ws-cdn",
 "listen": "127.0.0.1",
 "port": 8080,
 "protocol": "vless",
 "settings": { "clients": [], "decryption": "none" },
 "streamSettings": {
 "network": "ws",
 "security": "none",
 "wsSettings": { "path": "/braid", "host": "cdn.example.com" }
 }
}

security: none — TLS снимает фронт. Массив clients заполняет сам Remnawave по пользователям, вручную не трогаем.

Вариант XHTTP под GET-only CDN — с явным режимом:

{
 "tag": "vless-xhttp-cdn",
 "listen": "127.0.0.1",
 "port": 8080,
 "protocol": "vless",
 "settings": { "clients": [], "decryption": "none" },
 "streamSettings": {
 "network": "xhttp",
 "security": "none",
 "xhttpSettings": { "path": "/braid", "mode": "packet-up" }
 }
}

Перед нодой на 443 держите reverse-proxy с валидным сертификатом на origin-домен — именно на этот origin ходит CDN. Для WS критичны заголовки Upgrade/Connection, иначе соединение молча рвётся:

location /braid {
 proxy_pass http://127.0.0.1:8080;
 proxy_http_version 1.1;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection "upgrade";
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_read_timeout 300s;
}

Путь на proxy и path в inbound должны совпадать; всё остальное отдавайте 404 или заглушку. Для gRPC/XHTTP набор proxy_set_header иной (без Upgrade, с HTTP/2 на listener) — сверяйтесь с требованиями транспорта.

Настройка Hosts в Remnawave — самое важное

Host в Remnawave — это то, что реально уезжает клиенту в подписке. Здесь нода «переезжает» за CDN, при этом сам origin не меняется. Это ядро настройки Remnawave за CDN. Ключевые поля:

  • Address — домен CDN, а не IP и не origin-домен ноды. Это адрес, куда пойдёт клиент.
  • Port443.
  • Securitytls (TLS до CDN настоящий).
  • SNI — домен CDN (тот же, что Address); должен совпадать с сертификатом, которым отвечает CDN.
  • Host (header) — домен CDN. Для WS/XHTTP это HTTP-заголовок маршрутизации; расхождение SNI и Host — частая причина «не коннектится».
  • Path — тот же /braid, что в inbound и на reverse-proxy.
  • ALPNhttp/1.1 для WS; для gRPC/XHTTP — h2. Неверный ALPN ломает соединение на CDN молча.
  • Fingerprintchrome (маскировка TLS ClientHello под браузер).
  • Allow Insecureoff. Если пришлось включать — сертификат/SNI настроены неверно; чините причину, а не симптом.

Смысл: inbound на ноде остаётся один, а через несколько Hosts вы отдаёте один узел под разными фронтами (прямой домен и домен CDN) и переключаете аудиторию, не трогая ноду. Когда прямой IP ложится под белым списком — активным остаётся Host с CDN-адресом. Удобно держать оба Host'а заранее и включать резервный по факту блокировки.

Проверка, типичные ошибки и слой устойчивости

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

  1. С origin-сервера — curl -vk https://127.0.0.1/braid --resolve... или проще проверьте локально curl -v http://127.0.0.1:8080/braid: reverse-proxy и inbound живы, если нет ошибки соединения.
  2. Снаружи через CDN — curl -v https://cdn.example.com/braid. CDN должен принять TLS и дотянуться до origin; ответ 400/404 от вашего proxy — норма (путь живёт, просто не VLESS-рукопожатие), а вот 5xx с edge означает, что origin недоступен или путь не совпал.
  3. Подключение реальным клиентом из подписки — проверяйте на двух-трёх разных клиентах, особенно для XHTTP (история с packet-up).
  4. Отключите CDN-Host и убедитесь, что прямой доступ тоже работает — так отделяете проблемы CDN от проблем ноды.

Частые грабли:

  • SNI ≠ Host — рвётся молча; держите оба равными домену CDN.
  • Path не совпал в inbound / reverse-proxy / Host — CDN отдаёт 404, клиент «не подключается».
  • Reality под CDN — не работает в принципе, TLS терминирует CDN.
  • XHTTP на GET-only CDN без packet-up — работает выборочно по клиентам.
  • WS без Upgrade-заголовков на nginx — 502/400 на apgrade'е.
  • iOS-клиенты кэшируют подписку — после смены Host обновление «залипает»; лечится no-cache на выдаче подписки или переустановкой подписки на устройстве.

Стратегический итог: обычный публичный CDN даёт доступность, но его edge-IP тоже могут не входить в белый список конкретного оператора. Максимальную устойчивость даёт фронт через whitelisted-CDN — сеть, edge-IP которой заведомо в белых списках российских операторов (по этому принципу построен наш Clearway). Тогда падение IP ноды в дата-центре перестаёт означать падение сервиса: клиент входит через белый фронт, а нода прячется за ним как origin.

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

CDN ускоряет Remnawave?

Нет, это не про скорость. Дополнительный хоп через edge CDN обычно добавляет задержку — по наблюдениям десятки миллисекунд. CDN для Remnawave ставят ради устойчивости IP: чтобы точка входа пережила белые списки и блокировку прямого IP ноды, когда сам дата-центр становится недоступен.

Можно ли использовать Reality за CDN?

Нет. Reality требует настоящий TLS-handshake напрямую с целевым сайтом, а CDN этот handshake терминирует на себе. За CDN работают только транспорты поверх HTTP: WebSocket, XHTTP, gRPC, HTTPUpgrade с обычным TLS. Reality оставляйте для прямого подключения к ноде без CDN.

Что писать в поле Address у Host — IP ноды или домен CDN?

Домен CDN. Address, SNI и Host-заголовок должны указывать на домен CDN, чтобы клиент шёл на edge, а не на origin. IP и origin-домен ноды в Host для CDN-схемы не фигурируют вообще — нода прячется за фронтом, а path во всех трёх местах (inbound, reverse-proxy, Host) должен совпадать.

Почему за CDN подписка работает в одном приложении и не работает в другом?

Классический симптом XHTTP на CDN, который пропускает только GET-запросы. Тогда XHTTP обязан работать в режиме packet-up, иначе часть клиентов не согласует транспорт. Зафиксируйте mode явно в xhttpSettings и протестируйте на нескольких клиентах, либо возьмите WebSocket как более совместимый вариант.

Нужен ли TLS между CDN и нодой, если CDN уже терминирует TLS?

Желательно. Без него расшифрованный CDN'ом трафик идёт до origin открытым HTTP. Настройте на ноде reverse-proxy с сертификатом на отдельный origin-домен и переведите CDN в режим origin-over-HTTPS. Минимально рабочая схема без второго TLS возможна, но по integrity она хуже.

Обычного CDN достаточно, чтобы пережить белые списки?

Не всегда. Публичный CDN даёт подмену точки входа, но его edge-IP могут не входить в белый список конкретного оператора и тоже отвалиться. Наибольшую устойчивость даёт whitelisted-CDN, edge-IP которого заведомо в белых списках; тогда падение IP ноды не роняет сервис, потому что клиент входит через белый фронт.

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

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

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