todo/DPI/tspu-http2-tls12-fix.md
loop-uh 0ad0bcc8dd
Some checks failed
Published content check / validate (push) Failing after 5s
seo+зеркало: [!mirror]-плашка со ссылкой на вики и description во frontmatter всех заметок
Каждая публикуемая заметка получила callout-шапку со ссылкой на свою страницу
wiki.zapret.moe (на самой вики она вырезается транформером RemoveMirrorCallout,
видна только на зеркале Obsidian Publish и в Forgejo) и SEO-поле description —
1–2 предложения для meta description обоих сайтов.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-26 22:05:57 +03:00

144 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
date: 2026-06-11
tags:
- dpi
- tspu
- rkn
- http2
- tls
- caddy
- hosting
- howto
aliases:
- HTTP/2 Only + TLS 1.2 против ТСПУ
- Как спасти сайт от ложных блокировок ТСПУ
- Caddy reverse-proxy против Июньской блокировки
- Почему TLS 1.2 проходит ТСПУ лучше TLS 1.3
link: https://ebyebots.ru/blog/kak-spasti-svoj-sajt-ot-lozhnyh-blokirovok-tspu-rkn-2026-god/
description: "Как вернуть сайт из-под ложной блокировки ТСПУ: reverse-proxy на Caddy с HTTP/2 Only и TLS 1.2 — почему это работает и когда не поможет."
---
> [!mirror] Резервное зеркало
> Актуальная версия этой страницы — на основной вики: [wiki.zapret.moe/DPI/tspu-http2-tls12-fix](https://wiki.zapret.moe/DPI/tspu-http2-tls12-fix)
# 🛠️ Как починить сайт под ложной блокировкой ТСПУ: HTTP/2 Only + TLS 1.2
> [!info] О чём заметка
> Практический гайд для **владельца сайта или сисадмина**, чей легальный ресурс на российском хостинге (Beget, TimeWeb, Selectel, SpaceWeb, FirstVDS) «прилёг» для части пользователей в начале июня 2026 из-за обновления **ТСПУ (Технические Средства Противодействия Угрозам)** — оборудования **DPI (Deep Packet Inspection, глубокий анализ пакетов)** Роскомнадзора. Решение: перевести отдачу сайта на **HTTP/2 Only в связке с TLS 1.2** (**TLS — Transport Layer Security, протокол шифрования, на котором стоит HTTPS**), обычно через reverse-proxy на веб-сервере Caddy. Здесь — *почему* это работает (включая контринтуитивный момент: TLS 1.2 проходит фильтр **лучше**, чем более новый TLS 1.3) и *как* настроить. Что это за блокировка в целом и по каким признакам она срабатывает — в обзорной заметке [[DPI/tspu-false-blocks-june-2026|про «Июньскую блокировку 2026»]].
> [!warning] Статус данных
> Механизм триггера — **результат реверс-инжиниринга** DPI (наблюдения eByeBots и исследователя Петра Осетрова @hyperion_cs, июнь 2026). Числа (порог «~3 соединения за 60 секунд», заморозка «120 секунд») и сам факт, что помогает именно HTTP/2 + TLS 1.2, — **наблюдения на июнь 2026**; параметры фильтра **различаются по операторам и регионам и со временем меняются**. Это решение лечит **одно** из условий блокировки (всплеск TLS-соединений); если сайт режется по другому признаку — оно может не помочь (см. оговорки в конце).
## TL;DR
- **Симптом:** сайт на российском хостинге грузится через раз, не подгружается **CDN (Content Delivery Network — сеть доставки статики: картинок, стилей, скриптов)**, виснет `Connection timed out`, сервер не пингуется — но **только у части пользователей** (зависит от их оператора и региона).
- **Причина:** ТСПУ считает **всплеск TLS-соединений** от одного клиента к одному адресу признаком **VPN (Virtual Private Network — шифрованный туннель)** и временно блокирует. Браузер по **HTTP/1.1** открывает 630 параллельных TLS-соединений на загрузку страницы — и невольно превышает порог (наблюдался лимит ~**3 новых сессии за 60 секунд** к одному имени хоста), ловя **заморозку соединений на 120 секунд**.
- **Фикс:** заставить сайт отдаваться по **HTTP/2 Only** — мультиплексирование сворачивает все запросы к домену в **одно** TLS-соединение, и порог не пробивается. Плюс **принудительно ограничить TLS версией 1.2**.
- **Парадокс TLS:** откатить с TLS 1.3 на **TLS 1.2** помогает не потому, что 1.2 «лучше», а потому, что он для ТСПУ **привычнее**: в TLS 1.2 в открытом виде видны и **SNI (Server Name Indication — имя домена)**, и **сертификат сервера** — структура опознаётся как «старый добрый HTTPS». В TLS 1.3 сертификат сервера зашифрован, и сам факт «нового» протокола ТСПУ давит превентивно, когда трафик идёт большими объёмами на популярные хостинги.
- **Как:** поставить reverse-proxy на **Caddy** (HTTP/2 + TLS 1.2), направить **A-записи (DNS-записи, привязывающие домен к IP-адресу)** домена на прокси, проксировать на реальный IP бэкенда. На бэкенде — отключить редирект HTTP→HTTPS (иначе петля и ошибка 502).
- **Это легально.** Сайт не в реестре запрещённых — чинится настройкой сервера, без обходных средств.
## На пальцах
> [!example] Аналогия
> Представь охранника на входе (ТСПУ), которому сказали не пускать тех, кто «суетливо забегает по 10 раз подряд» (так ведут себя VPN-туннели). Обычный сайт по HTTP/1.1 ведёт себя именно так: чтобы быстро показать страницу, браузер «забегает» за картинками, стилями и скриптами **десятком отдельных заходов** — и охранник принимает его за нарушителя.
>
> HTTP/2 — это когда вместо десяти суетливых забеганий курьер заходит **один раз** и приносит всё сразу в одной сумке (мультиплексирование). Охранник видит спокойного одиночного посетителя и пропускает. А TLS 1.2 вместо TLS 1.3 — это как прийти в **знакомой форме**, которую охранник видел годами, вместо новой наглухо закрытой экипировки, которая его настораживает.
## Что произошло (45 июня 2026)
Крупные российские хостеры — **Beget, TimeWeb, Selectel, SpaceWeb, FirstVDS** — массово зафиксировали частичную недоступность ресурсов. Техподдержка отвечала: «с нашей стороны проблем нет, это плавающие обновления ТСПУ со стороны РКН, зависящие от региона и оператора связи». Симптомы — полный таймаут по **SSH (Secure Shell, удалённая консоль)** и **RDP (Remote Desktop Protocol, удалённый рабочий стол Windows)**, недоступность HTTP/HTTPS, пропажа даже **ICMP (служебный протокол сети — на нём работает `ping`)**.
> [!note] Кто не пострадал
> Провайдер **REG.RU** (REGRU) почти не затронуло — большинство его IP-адресов **изначально в «белых списках»** систем фильтрации. Это прямое следствие механизма: блок идёт по подсети, а «белая» подсеть под него не попадает.
Эмпирическое подтверждение причины (из разбора eByeBots): пока у непокрытых хостеров сайты лежали (у самого Beget не грузился CDN, профильные чаты кипели), сайты пострадавших, которых **подключили к фильтрующему прокси с HTTP/2 + TLS 1.2, мгновенно оживали** — при том что их реальные IP оставались прежними. Контраст «у клиентов прокси тихо — у непокрытых лежит» и показывает: дело не в самом IP, а в *том, как* клиент устанавливает шифрованные соединения.
## Почему спасает HTTP/2
DPI на ТСПУ ищет аномалии. Одна из главных для него — **множественные быстрые TLS-рукопожатия** (TLS Handshake) с одного IP на другой за короткое время: для фильтра это похоже на VPN-протокол, прокси-туннель или **DDoS-атаку (распределённую атаку на отказ в обслуживании)**. Реакция — автоматическая заморозка соединений на **120 секунд**.
| Протокол | Как браузер грузит страницу | Что видит ТСПУ |
|---|---|---|
| **HTTP/1.1** | от **6 до ~30** параллельных TCP-соединений, в каждом — свой TLS-хендшейк | «всплеск» рукопожатий → превышение лимита (~3 за 60 с) → заморозка на 120 с |
| **HTTP/2** | **мультиплексирование**: одно TCP-соединение, **ровно один** TLS-хендшейк, внутри — сотни запросов одновременно | один невинный запрос → лимит не превышен → трафик легитимен |
«Only» в названии важно: цель — чтобы браузер вёл всю загрузку через одно HTTP/2-соединение, а не откатывался на HTTP/1.1 с лавиной рукопожатий. Версия HTTP согласуется при подключении через **ALPN (Application-Layer Protocol Negotiation — расширение TLS, в котором клиент и сервер договариваются о протоколе)**.
> [!warning] Тонкость: «HTTP/2 Only» требует модифицированного Caddy
> **Стоковый Caddy не умеет полностью отключить HTTP/1.1** — это ограничение стандартной библиотеки Go (включение HTTP/2 неизбежно оставляет включённым и HTTP/1.1; открытый issue [caddy#7221](https://github.com/caddyserver/caddy/issues/7221)). Сервер всё равно анонсирует HTTP/1.1 в ALPN рядом с HTTP/2, и браузер технически может откатиться. Именно поэтому eByeBots использует **модифицированный (пропатченный) Caddy** — отсюда и название «HTTP/2 Only». На практике, впрочем, современные браузеры предпочитают HTTP/2, когда он предложен, так что даже приоритет h2 без жёсткого отключения h1 заметно снижает число рукопожатий; для гарантированного результата нужен пропатченный Caddy или другой сервер, умеющий не анонсировать h1.
> [!note] Связь с полной моделью триггера
> Вторая статья eByeBots подаёт причину упрощённо — «всплеск TLS-соединений → бан IP». Полная модель (по реверс-инжинирингу @hyperion_cs) точнее: блок — это **И-цепочка из трёх условий**, и HTTP/2 ломает именно **третье** из них (частоту новых TLS-сессий), чего достаточно, чтобы вся цепочка не сработала. Разбор всех трёх условий и точных порогов — в [[DPI/tspu-false-blocks-june-2026|обзорной заметке]].
## Почему именно TLS 1.2, а не более новый TLS 1.3
Это контринтуитивный момент: TLS 1.3 современнее и безопаснее, но через ТСПУ хуже проходит **именно из-за этого**.
- **TLS 1.3 — для ТСПУ «слишком новое».** Важная оговорка: вопреки расхожей формулировке eByeBots про «чёрную коробку», в стандартном TLS 1.3 (без расширения ECH) `ClientHello` и **SNI** всё ещё передаются **открыто** — отпечаток **JA3/JA4 (стандартные хэши параметров TLS-рукопожатия, по которым опознают браузер)** из них по-прежнему вычислим. Что 1.3 реально прячет — это **сертификат сервера** и часть ответных расширений (они шифруются сразу после обмена ключами). Но для ТСПУ важнее другое: сам факт TLS 1.3 плюс структура его рукопожатия — маркер «современного, непривычного» трафика, который фильтр **давит превентивно**, когда он идёт огромными объёмами (терабайтами) на популярные хостинги.
- **TLS 1.2 — «свой, привычный».** В TLS 1.2 в открытом виде передаётся не только SNI, но и **сертификат сервера**, и всё соединение выглядит как «старый добрый HTTPS». ТСПУ распознаёт привычные маркеры и пропускает пакеты.
> [!warning] Это осознанный компромисс
> Откат на TLS 1.2 — шаг **назад** по приватности рукопожатия: в открытом виде оказывается сертификат сервера (в TLS 1.3 он зашифрован), и теряются прочие улучшения 1.3. Для публичного сайта это обычно приемлемо (контент и так открыт), но понимать цену стоит: вы делаете трафик **намеренно более прозрачным** для цензора, чтобы он счёл его «легитимным». Это противоположность стратегии обходных средств, которые, наоборот, прячут почерк.
## Как настроить reverse-proxy (каркас)
Идея: между пользователем и вашим бэкендом ставится прокси на **Caddy**, который принимает соединения **по HTTP/2 + TLS 1.2**, а внутрь проксирует на реальный IP сайта. ТСПУ видит спокойное одиночное соединение к прокси.
- [ ] **На бэкенде — отключить принудительный редирект HTTP→HTTPS.** Иначе между прокси и бэкендом возникает петля редиректов и ошибка **502**. Связь прокси ↔ бэкенд идёт по самоподписанному сертификату.
- [ ] **Сгенерировать самоподписанный сертификат** на прокси-сервере, например:
```bash
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout /etc/caddy/my_private.key \
-out /etc/caddy/my_selfsigned.crt
```
- [ ] **Зажать протоколы в `Caddyfile`.** Важно: список версий HTTP в Caddy задаётся **глобально** (в блоке `servers`), а не внутри блока сайта; ограничение версии TLS — директивой `tls` внутри блока сайта. Иллюстративный каркас (псевдоконфиг — точный синтаксис и подводные камни сверяйте с актуальной документацией Caddy и первоисточником):
```caddyfile
{
servers {
protocols h2 # оставить только HTTP/2; внимание: стоковый Caddy всё равно не убирает h1 из ALPN (ограничение Go, caddy#7221) — полный HTTP/2 Only требует пропатченного Caddy. h2c (HTTP/2 без TLS) для TLS-сайта не нужен.
}
}
your-domain.ru {
tls /etc/caddy/my_selfsigned.crt /etc/caddy/my_private.key {
protocols tls1.2 tls1.2 # порядок аргументов: минимум, затем максимум — оба зажаты на TLS 1.2
}
reverse_proxy https://РЕАЛЬНЫЙ_IP_БЭКЕНДА {
transport http {
tls_insecure_skip_verify # бэкенд по самоподписанному серту
}
}
}
```
- [ ] **Перенаправить A-записи домена** на IP прокси-сервера (желательно в локации/подсети, не попавшей под фильтр).
- [ ] **Проверить результат:** `curl -Iv https://your-domain.ru` — в выводе должно быть `HTTP/2` и `TLS 1.2`.
## Альтернативы без своего прокси
- **Официальный «белый список» (для юрлиц и ИП — индивидуальных предпринимателей).** Подать заявку хостеру (например, Selectel) на внесение ваших подсетей в официальные белые списки РКН. Надёжно, но требует времени и обоснований.
- **Миграция на «чистый» хостинг.** Переехать туда, чьи IP ТСПУ пока не трогает (например, у REG.RU большинство IP в белых списках).
- **Клиентский фикс (для пользователя, не владельца).** Сменить TLS-отпечаток в браузере — открыть сайт в Firefox или включить флаг Chrome, см. [[DPI/chrome-cnsa-flag-bypass|приём с флагом cryptography-compliance-cnsa]]. Это лечит другое условие триггера (отпечаток), а не частоту. Среди трёх вариантов eByeBots #2 этого пункта нет — он из общей трёхфакторной модели.
## Оговорки: когда HTTP/2 + TLS 1.2 не спасёт
> [!warning] Границы применимости
> - Решение ломает условие **«всплеск TLS-соединений»**. Если ваш сайт режется по **другому** признаку — например, по TLS-отпечатку (часть сайтов не открывается только в Chrome/Edge) — HTTP/2 не поможет, нужен фикс отпечатка.
> - Параметры фильтра **меняются**. То, что проходит сегодня, может попасть под правило завтра; «лимит ~3 соединения» и «120 секунд» — наблюдения, а не гарантированные константы.
> - `HTTP/2 Only` без анонса HTTP/1.1 в ALPN может отрезать совсем старые клиенты, не умеющие HTTP/2 (на практике их почти нет).
> - Это **возврат доступности**, а не «обход блокировки»: приём работает именно потому, что сайт легальный и его не нужно прятать — наоборот, его делают максимально «обычным» для DPI.
## Источники
| Источник | Дата | Что отсюда взято |
|---|---|---|
| [eByeBots — «Как спасти свой сайт… HTTP/2 Only и TLS 1.2»](https://ebyebots.ru/blog/kak-spasti-svoj-sajt-ot-lozhnyh-blokirovok-tspu-rkn-2026-god/) | 10 июня 2026 | Связка HTTP/2 Only + TLS 1.2, почему TLS 1.2 «читаем» для ТСПУ, список пострадавших хостеров и REG.RU как исключение, эмпирика с прокси, алгоритм настройки (отключить HTTP→HTTPS-редирект, самоподписанный серт через `openssl req -x509`, Caddyfile с h2+tls1.2, A-записи). |
| [Хабр articles/1045684 — починка блокировки сайта ТСПУ, реальный кейс](https://habr.com/ru/articles/1045684/) | июнь 2026 | Готовый минимальный конфиг Caddy и проверка `curl -Iv`. |
| [eByeBots — технический разбор «Июньской блокировки 2026»](https://ebyebots.ru/blog/kak-tspu-roskomnadzora-lomaet-legitimnye-sajty-i-servery-v-iyune-2026-goda-tehnicheskij-razbor/) | 7 июня 2026 | Полная трёхфакторная модель триггера, в которую HTTP/2-фикс встроен как слом условия «частота». |
## 📚 См. также
- [[DPI/tspu-false-blocks-june-2026|Как ТСПУ ломает легитимные сайты: «Июньская блокировка 2026»]] — обзор: что это за блокировка, И-триггер из трёх условий, диагностика и полный список фиксов. **Эта заметка — детализация одного из них.**
- [[VLESS/dpi-tls-june-2026|Как DPI «замораживает» VLESS+REALITY: схема июня 2026]] — тот же триггер со стороны обходных средств; почему там, наоборот, прячут TLS-отпечаток.
- [[DPI/chrome-cnsa-flag-bypass|Обход блокировки флагом Chrome cryptography-compliance-cnsa]] — клиентский фикс через смену TLS-отпечатка (другое условие триггера).
- [[DPI/browser-ja4-fingerprint-block|Блокировка сайта по JA4-отпечатку браузера]] — случай, когда сайт режется именно по отпечатку, а не по частоте.