VPN·HUB·CRACK Yandex CDN (рекомендую): рабочий РФ-фронт · VPN HUB CRACK
Все статьи
CDN и др. обходы PRO

Yandex CDN (рекомендую): рабочий РФ-фронт

Обновлено 11 августа 2026 Проверено

Yandex CDN (рекомендую): рабочий РФ-фронт

Главное с 28.07.2026: ориджин должен быть в России. Яндекс начал резать доступ к CDN-ресурсам, у которых источник (origin) это зарубежный сервер. По нашим наблюдениям уже забанены подсети play2go и aeza, и похоже, что дальше под раздачу попадёт остальной зарубеж. Симптом: всё настроено по шагам, а ресурс не встаёт или отдаёт ошибки на пустом месте. Рабочая схема: ориджин на РФ-сервере, а за границу трафик уходит уже каскадом с него (см. Каскад: вход в РФ, чистый выход). Если CDN «не заводится», первым делом переносите ориджин на российский сервер, это чинит в большинстве случаев.

Это разбор одного провайдера. Что такое CDN-фронтинг, режимы «через GET / через POST» и общая база (XHTTP-инбаунд) разобраны в обзорной статье «CDN-фронтинг: спрятать ноду за CDN».

Из всех российских CDN это самый предсказуемый фронт, и именно его я рекомендую как основной CDN-резерв для РФ. Сеть Яндекса «своя» для ТСПУ (российской фильтрации трафика у операторов), трафик к ней не режут, домен стабилен и не «протухает». Материал взят из реального внедрения (заменили нестабильный Beget CDN на Yandex). Стек: Remnawave + Xray-core 26.x + nginx + Yandex Cloud CDN (ourcdn) + Certificate Manager.

📖 Незнакомые слова? Все термины простыми словами смотрите в Словаре терминов.

✅ Плюсы: «своя» для ТСПУ сеть (не режется), стабильный домен и серты, предсказуемость, бесплатный/дешёвый трафик в рамках Yandex Cloud. ❌ Минусы: режет POST на эдже (отдаёт 405) → нужен GET-only xHTTP (транспорт за CDN; аплинк в заголовке); настройка только через yc CLI; +0.4–0.5 с латентности (общая беда CDN-фронта).

Главная засада, которая экономит день: Yandex CDN (провайдер ourcdn) режет метод POST на эдже. Стандартный xHTTP шлёт аплинк через POST → через Yandex он не заработает. Лечится переводом транспорта в GET-only (uplinkHTTPMethod: GET, данные аплинка передаются в HTTP-заголовке). Провайдер gcore у Яндекса deprecated, активируется только ourcdn.

Архитектура

                         TLS (SNI = CDN-домен), ALPN h2
 [ Xray-клиент ] ──VLESS/xHTTP──► [ Yandex CDN edge ] ──HTTPS──► [ origin nginx :443 ]
                                                                  ⚠️ РФ-сервер (иначе Яндекс режет)
                                                                          │
                                                                   каскад ▼
                                                                [ загран-выход ]
   (Happ и т.п.)                    (терминирует TLS,             (LE-серт на origin-FQDN)
                                     GET проходит, POST=405)               │ proxy_pass
                                                                           ▼
                                                              [ Xray xHTTP inbound :10086 ]
                                                                (listen 127.0.0.1, GET-only)
                                                                           │
                                                                           ▼  outbound → интернет

Два домена: - публичный CDN-домен (cdn.your.domain): к нему коннектится клиент; CNAME → эдж Яндекса. - ориджин-домен (origin.your.domain): откуда CDN тянет контент; A-запись → IP сервера с валидным LE-сертом; DNS «серый» (DNS only).

Предусловия

  • Аккаунт Yandex Cloud + установленный/авторизованный yc CLI (yc config list показывает cloud-id/folder-id).
  • Управляемый DNS (например, Cloudflare), записи в режиме DNS only (серое облако).
  • Origin-сервер: nginx + Xray, валидный Let's Encrypt-серт на ориджин-домен, порт 443 открыт.
  • Xray-ядро с поддержкой xHTTP extra (xray-core ≥ 1.8.x / 26.x, поля SplitHTTPConfig).

Шаг 1. Активировать CDN-провайдер

yc cdn provider activate --type ourcdn       # gcore — DEPRECATED, не активируется
yc cdn provider list-activated               # должно показать: ourcdn

Шаг 2. Выпустить TLS-серт (Certificate Manager, Let's Encrypt, DNS-01)

yc certificate-manager certificate request \
  --name cdn-cert --domains cdn.your.domain --challenge dns

# забрать запись валидации (challenge виден только с --full):
yc certificate-manager certificate get --name cdn-cert --full --format json

В выводе будет CNAME вида _acme-challenge.cdn.your.domain CNAME <id>.cm.yandexcloud.net. Добавляем её в DNS (DNS only). Берём именно CNAME, а не TXT: при автопродлении значение за CNAME меняет сам Яндекс, запись трогать не нужно. Ждём status: ISSUED (1–10 минут):

yc certificate-manager certificate get --name cdn-cert --format json | jq -r .status

Шаг 3. Создать ориджин-группу

yc cdn origin-group create --name my-origin \
  --origin source=origin.your.domain,enabled=true
# запоминаем выданный origin-group-id

Шаг 4. Создать CDN-ресурс (+ выключить кэш)

yc cdn resource create \
  --cname cdn.your.domain \
  --origin-group-id <ORIGIN_GROUP_ID> \
  --origin-protocol https \
  --host-header origin.your.domain \
  --cert-manager-ssl-cert-id <CERT_ID> \
  --active=true

Грабли ourcdn при создании: - булевы флаги требуют явного =true (--active=true); - POST задать нельзя ни при создании (method POST is not allowed during creation), ни позже (POST management is unavailable), поэтому и нужен GET-only.

Выключить кэш обязательно (иначе эдж закэширует ответы xHTTP и сломает сессии):

yc cdn resource update --id <RESOURCE_ID> --cache-expiration-time 0

⚠️ У ourcdn флаг --disable-cache это no-op (в опциях остаётся edge_cache_settings: 86400). Реально выключает только --cache-expiration-time 0 (после него edge_cache_settings.value = 0).

Забрать CNAME-таргет эджа:

yc cdn resource get --id <RESOURCE_ID> --format json | jq -r .provider_cname
# например: d01529f5e12f015a.topology.gslb.yccdn.ru

Шаг 5. Направить публичный домен на эдж

В DNS: cdn.your.domain CNAME <provider_cname> (DNS only / серое).

Эдж ourcdn прогревается 15–30 минут: серт и fetch-конфиг разъезжаются по эджам постепенно, GSLB первое время «флапает» (часть эджей ещё отдаёт дефолтный *.yccdn.cloud.yandex.net). Это нормально, нужно подождать.

Шаг 6. Xray: GET-only xHTTP-инбаунд (на ориджине)

Сердце обхода POST-блокировки. Инбаунд слушает localhost, наружу его публикует nginx. Ключ: uplinkHTTPMethod: GET + аплинк в заголовке (uplinkDataPlacement: header), путь «правдоподобный» (под вид API-поллинга). Клиентский extra должен 1-в-1 совпадать с этим блоком.

{
  "log": { "loglevel": "warning" },
  "inbounds": [
    {
      "tag": "VLESS_XHTTP_CDN_GET",
      "port": 10086,
      "listen": "127.0.0.1",
      "protocol": "vless",
      "settings": { "clients": [], "decryption": "none" },
      "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] },
      "streamSettings": {
        "network": "xhttp",
        "security": "none",
        "xhttpSettings": {
          "mode": "packet-up",
          "path": "/api/v4/media/session/poll",
          "extra": {
            "xmux": {
              "maxConcurrency": "8-16", "cMaxReuseTimes": "128-256",
              "hKeepAlivePeriod": 30, "hMaxRequestTimes": "600-1000",
              "hMaxReusableSecs": "1800-3600"
            },
            "headers": {
              "Accept": "application/vnd.api+json, application/json, text/plain, */*",
              "Cache-Control": "no-cache", "Pragma": "no-cache",
              "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7"
            },
            "uplinkHTTPMethod": "GET",
            "uplinkDataPlacement": "header",
            "uplinkDataKey": "X-Playback-Token",
            "serverMaxHeaderBytes": 32768,
            "sessionKey": "media_sid", "sessionPlacement": "path",
            "seqKey": "offset", "seqPlacement": "query",
            "xPaddingKey": "q", "xPaddingPlacement": "query",
            "xPaddingMethod": "tokenish", "xPaddingBytes": "48-320", "xPaddingObfsMode": true,
            "scMaxBufferedPosts": 64, "scMaxEachPostBytes": "1536-6144",
            "scMinPostsIntervalMs": "10-30"
          }
        }
      }
    }
  ],
  "outbounds": [
    { "tag": "DIRECT", "protocol": "freedom" },
    { "tag": "BLOCK",  "protocol": "blackhole" }
  ],
  "routing": {
    "rules": [
      { "type": "field", "protocol": ["bittorrent"], "outboundTag": "BLOCK" },
      { "type": "field", "ip": ["geoip:private"], "outboundTag": "BLOCK" }
    ]
  }
}

⚠️ Вставляйте профиль целиком, вместе с inbounds/outbounds/routing. Если скопировать только сам инбаунд (то, что внутри inbounds[]), свежая панель Remnawave отклонит его с ошибкой Config doesn't have inbounds — она ждёт полный config profile, а не фрагмент. Добавляете инбаунд к уже существующему профилю — кладите его в массив config.inbounds[], не заменяя чужие теги. Почему mode: packet-up, а не stream-up: GET-аплинк валиден только в packet-up. stream-up через CDN к тому же часто регрессирует (CDN буферит длинный POST-стрим). Outbound: обычный freedom + роутинг (блок geoip:private, bittorrent, udp/443 чтобы QUIC ушёл на TCP).

Шаг 7. nginx на ориджине (роут пути в Xray)

Critically: выключить буферизацию и кэш, длинные таймауты, без лимита тела.

location /api/v4/media/session/poll {
    proxy_pass              http://127.0.0.1:10086;
    proxy_http_version      1.1;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto https;
    proxy_buffering         off;
    proxy_request_buffering off;
    proxy_cache             off;
    proxy_read_timeout      3600s;
    proxy_send_timeout      3600s;
    client_max_body_size    0;
}

nginx -t && systemctl reload nginx. (Несколько фронтов на одном ориджине разводятся по разным location-путям на разные локальные порты Xray.)

Шаг 8. Клиентский хост (Remnawave)

  • address / sni / host = публичный CDN-домен (cdn.your.domain), port 443;
  • security TLS, network xhttp, path = тот же, что у инбаунда;
  • alpn h2,http/1.1, fingerprint firefox;
  • xHttpExtraParams = тот же блок extra, что и на сервере (GET-only), иначе клиент ловит 400.

🔴 ЗАПАСНОЙ ВАРИАНТ: «сервер ок (форк-тест выходит), а у клиента 400 / нет интернета»: sessionPlacement: "path" (НЕ cookie/query). Это самая коварная засада GET-only: клиенты вроде Happ честно исполняют sessionPlacement и кладут session-id в cookie/query: GET /…/poll/?media_sid=<id>&offset=0. А Xray-сервер (26.x) sessionPlacement фактически игнорирует и ждёт session-id в пути: GET /…/poll/<id>?offset=0. Не совпало → сервер отбивает 400 на КАЖДЫЙ запрос → у юзера «подключилось, но нет интернета». Почему ловится не сразу: форк-тест на голом Xray-клиенте тоже шлёт session в путь (он sessionPlacement игнорит) → e2e через CDN проходит → создаётся ложное ощущение «сервер рабочий, виноват клиент». Не верьте только форк-тесту, проверяйте реальным клиентом. Диагностика (решает за минуту): origin-nginx access-лог (docker logs remnawave-nginx | grep poll, либо access.log): сравнить GET-строки: рабочая /…/poll/<sid>?offset=0200, сломанная /…/poll/?media_sid=<sid>&offset=0400. Реальный IP юзера смотрите в конце строки (X-Forwarded-For). Фикс: sessionPlacement: "path" в блоке extra и на сервере, и в клиентской ссылке (seqPlacement: "query" оставить: offset в query Xray принимает нормально). ⚠️ Happ кэширует конфиг: сменил ссылку → в клиенте удали старый профиль и импортни заново, иначе возьмёт старое.

Проверка

С нейтральной точки (с любого сервера, НЕ с машины за своим VPN, иначе локальный прокси перехватит curl и отдаст мусор edge_ip=127.0.0.1):

# downlink GET — ждём 404/400 (= Xray достигнут сквозь CDN), TLS должен верифаться
curl -s -o /dev/null -w "GET  %{http_code} tls=%{ssl_verify_result} %{time_total}s\n" \
  https://cdn.your.domain/api/v4/media/session/poll
# → HTTP 404, tls=0

# проверка, что POST режется эджем (это диагностика, не ошибка):
curl -s -o /dev/null -w "POST %{http_code}\n" -X POST --data x \
  https://cdn.your.domain/api/v4/media/session/poll
# → 405  (именно поэтому GET-only)

Финальная проверка: реальный конект VLESS-клиентом (Happ/v2rayN/sing-box): curl'ом полноценную xHTTP-сессию не воспроизвести. Если TLS не верифается, а серт *.yccdn.cloud.yandex.net, значит эдж ещё не прокатил кастомный серт, ждём прогрев.

Грабли (чек-лист)

Симптом Причина / фикс
gcore provider is deprecated использовать --type ourcdn
POST через эдж = 405, конект не встаёт ourcdn режет POST → перевести xHTTP в GET-only
--disable-cache не выключает кэш у ourcdn это no-op → --cache-expiration-time 0
method POST is not allowed during creation / POST management is unavailable POST на CDN-ресурсе недоступен в принципе, не пытайтесь
TLS-серт не тот (*.yccdn.cloud.yandex.net), HTTP=000 эдж прогревается (15–30 мин), GSLB флапает, надо просто ждать
Ресурс не встаёт / ошибки на ровном месте, ориджин за границей ⛔ Яндекс режет зарубежные ориджины (28.07.2026: play2go, aeza). Перенесите ориджин на РФ-сервер, а за границу уходите каскадом
502 сквозь эдж, ориджин жив проверить origin-protocol/host-header; кэш; путь nginx → Xray
curl с рабочей машины врёт (edge_ip=127.0.0.1) локальный VPN или прокси перехватывает, тестируйте с чистого сервера
Клиент 400 при коннекте client xHttpExtraParams ≠ серверный extra
Клиент 400 / «нет инета», а форк-тест выходит session-id не там: Happ кладёт в cookie/query, Xray ждёт в путиsessionPlacement:"path" в extra (сервер+ссылка), Happ удалить+переимпорт. См. «Запасной вариант» выше

Границы применимости

CDN-фронтинг = +0.4–0.5 с латентности на запрос (природа edge-проксирования), а GET-only ещё ограничивает аплинк (данные в заголовках). Итог: мессенджеры/браузинг: ок; YouTube/большой upload/спидтест: структурно тяжело. Применять как узел обхода/выживания, а не как скоростной. Для скорости нужны прямые ноды.

Связано: обзорная статья «CDN-фронтинг» (общая база, GET/POST), «Каскад RU-вход → загран-выход» (чтобы выход был заграничным), «Заблокировали IP?».