---
date: 2026-08-06
tags:
  - mtproto
  - telegram
  - wss
  - websocket
  - диагностика
  - обход-блокировок
  - cloudflare
aliases:
  - Почему не грузятся стикеры через WSS прокси
  - WSS прокси Telegram не работает
  - Не грузит фото и видео в Telegram через прокси
  - Почему звонки не работают через прокси Telegram
  - Ошибка 429 Cloudflare Worker Telegram
  - The proxy you are using is not configured correctly
  - Ограничения WSS транспорта Telegram
---

# 🧯 Ограничения WSS для Telegram: что не работает и почему

> [!info] О чём заметка
> У транспорта, который прячет MTProto в WebSocket и отправляет на веб-релеи Telegram, длинный список оговорок: работают не все датацентры, стикеры и реакции могут не грузиться, звонки не проксируются вовсе, а бесплатные запасные пути упираются в лимиты Cloudflare. Здесь собраны симптомы, их причины и то, чем каждый случай подтверждается. Как транспорт устроен изнутри — в парной заметке [[mtproxy/telegram-wss-transport|WSS для Telegram: MTProto внутри WebSocket]].

> [!warning] Откуда взяты данные
> Заметка собрана из трёх типов источников по состоянию на **6 августа 2026**: комментарии и константы в коде четырёх проектов (`tg-ws-proxy`, модуль `telegram_proxy` в ZapretGUI, форки ZaStoGram для Android и Desktop), их журналы исправлений и обсуждения в трекере `tg-ws-proxy` — включая пользовательский FAQ, который ведёт сообщество в [issue #389](https://github.com/Flowseal/tg-ws-proxy/issues/389), а не разработчики Telegram. Результаты замеров относятся к конкретным сетям и датам и не являются спецификацией: у другого провайдера и в другой месяц поведение релеев может отличаться.

---

## TL;DR

1. **Кадр WebSocket — единица разбора, а не просто нарезка.** Релей обрабатывает только первый MTProto-пакет кадра и молча выбрасывает остальные, поэтому склеивать пакеты нельзя (разрезать один пакет на несколько кадров — можно). Нарушение этого правила оставляет датацентр без ключа: рукопожатие висит на втором шаге, и медиа оттуда не грузится при внешне рабочем соединении.
2. **Веб-релеи работают у всех датацентров DC1–DC5** (проверено живыми соединениями 8 августа 2026). Распространённое «только DC2 и DC4» — следствие ошибки метода: у каждого датацентра свой входной адрес, и обращение к чужому даёт редирект `302` или тишину. Реализации, рассчитанные только на DC2/DC4, ограничены собственным зашитым адресом, а не инфраструктурой Telegram.
3. Самый частый симптом — **«всё работает, но не грузятся фото, видео, стикеры и реакции»**. Причина обычно не в аккаунте, а в том, что нужный контент лежит на датацентре, релей которого закрыт именно в вашей сети. Проверять доступность надо по TCP, а не пингом: ICMP проходит и там, где порт 443 заблокирован — см. [[#Релей закрыт: «фото грузятся, эмодзи нет»]].
4. **Звонки и групповые войс-чаты такой прокси не переносит** — они ходят по UDP, а WebSocket живёт поверх TCP. Это не значит, что они не работают: трафик звонка идёт мимо туннеля напрямую, и закрывает его пакетный обход вроде [[Zapret2/Zapret2|zapret]] (он перехватывает UDP и STUN), а не прокси.
5. Отдельный класс отказов — **«соединение установилось, данных нет»**: рукопожатие прошло, `recv` остаётся нулевым. Реализации ловят это таймерами и уводят маршрут в карантин на 60 секунд, час или полчаса — в зависимости от проекта.
6. Бесплатные запасные пути через **Cloudflare** упираются в лимиты: общие домены отдают 429, неверный режим TLS даёт ошибку 525, а сами подсети Cloudflare в РФ тоже могут блокироваться.
7. WSS **несовместим** с MTProxy и (в Android-форке) с обычным прокси: включение одного гасит другое, и это поведение задумано, а не баг.
8. Клиентские форки долго **не откатывались на обычный TCP**: при недоступном релее попытки повторялись, пока пользователь не выключит транспорт руками. В обоих форках ZaStoGram откат теперь есть — датацентр с закрытым релеем уходит на прямое соединение, остальные продолжают идти через WSS. Причина отказа в интерфейс по-прежнему не выводится.

---

## Почему считалось, что работают только DC2 и DC4

> [!warning] Раздел исправлен 8 августа 2026
> Утверждение «релеи есть только у DC2 и DC4» **опровергнуто живыми соединениями**. Работают все DC1–DC5. Ниже разобрано, откуда взялось заблуждение и почему оно так убедительно выглядело.

У Telegram пять обычных датацентров плюс отдельные идентификаторы для CDN. Веб-релеи по схеме `kwsN.web.telegram.org` строятся для любого номера — и, как выяснилось, принимают соединения тоже все.

Источник заблуждения — **не универсальность ingress-адресов**. У каждого датацентра свой входной адрес: `149.154.174.100` обслуживает DC1/DC3, `149.154.167.220` — DC2/DC4, `149.154.170.100` — DC5. Инструмент, который держит один зашитый адрес на все датацентры, при попытке достучаться до чужого получает либо редирект `302` на `core.telegram.org`, либо — что коварнее — принятое соединение и тишину до таймаута. Отсюда и вывод «релея нет», хотя релей есть, просто вход не тот. Сервер даже подсказывает правильный: в ответе `302` есть заголовок `X-Redirect-Host` с нужным именем.

Проверка 8 августа 2026 (по несколько повторов на каждую пару «адрес + имя», чтобы отсеять обычные для DPI одиночные таймауты) показала: все три адреса принимают апгрейд и проксируют настоящий MTProto, включая медийные `kwsN-1`. Каталог маршрутов ZapretGUI, где `kws1`, `kws3`, `kws5` помечены как «только запасной путь», и комментарий в коде Desktop-форка про «веб-сокеты существуют только для DC2/DC4» отражают ограничение самих этих инструментов, а не инфраструктуры Telegram.

Desktop-форк ZaStoGram зашивает ограничение прямо в код: маршрут строится, только если номер датацентра равен 2 или 4. Android-форк держит таблицу из трёх адресов и покрывает DC1–DC5 — и именно его подход оказался верным. Любопытно, что расширение до пяти датацентров внесли 5 августа 2026 по аналогии, без проверки живым соединением; догадка подтвердилась только три дня спустя.

**Как проверять правильно.** Релей проверяется парой «адрес + имя», а не адресом отдельно: для датацентра N берите обслуживающий его ingress и ставьте `Host` и TLS SNI равными `kwsN.web.telegram.org`. Ещё надёжнее не хардкодить адреса вовсе — DNS отдаёт правильный ingress сам (имена `kwsN` и `kwsN-1` резолвятся в один и тот же адрес; суффикс различает класс трафика на стороне релея). И обязательно делайте 4–5 повторов: одиночный таймаут TCP на 443 к диапазонам Telegram ничего не доказывает.

С CDN-датацентром история отдельная. Домена `kws203.web.telegram.org` не существует: обращение к нему падает на резолве, маршрут отправляется в чёрный список, а прямой запасной путь по адресам вроде `149.154.175.50` в РФ часто заблокирован — соединение остаётся без вариантов. Автор `tg-ws-proxy` в обсуждении убрал переопределение DC203 из настроек по умолчанию, посчитав, что без него работает не хуже.

> [!danger] Не «просто перенаправьте на другой релей»
> Заманчивая идея — пустить трафик несуществующего релея через рабочий `kws2` — не работает и вредит. В ZapretGUI такую попытку зафиксировали замером 14 июня 2026: 276 подключений дали 608 случаев нулевого приёма, 42 обрыва на неполном чтении и 18 таймаутов, после чего Telegram показал «The proxy you are using is not configured correctly and will be disabled» и отключил прокси. С тех пор в режиме MTProxy кросс-датацентровая маршрутизация запрещена явной проверкой: если у датацентра нет своего релея, соединение сразу идёт в запасной путь.

Причина разной строгости — в том, как Telegram относится к двум типам прокси. SOCKS5 для него непрозрачная труба: попросил соединение до адреса, получил байты, содержимое не проверяет. MTProxy — участник протокола: клиент проверяет секрет, форму init-пакета и поведение прокси, и при расхождениях выключает его целиком, а не просто повторяет попытку.

---

## Релей закрыт: «фото грузятся, эмодзи нет»

Самый частый и самый обманчивый случай. Клиент выглядит исправным: переписка идёт, скорость нормальная, ошибок нет — но часть медиа не загружается никогда. Обычно это выглядит как «фотографии открываются, а эмодзи, реакции и стикеры не прогружаются».

Причина в том, что содержимое Telegram разложено по датацентрам, а **доступность релеев в конкретной сети разная**. Замеры 9 августа 2026 у одного российского провайдера, порт 443:

| Куда | Что это | `ping` | TCP 443 |
|---|---|---|---|
| `149.154.167.220` | релей DC2 и DC4 | отвечает | **открыт** |
| `149.154.174.100` | релей DC1 и DC3 | отвечает | закрыт |
| `2001:b28:...:338` | тот же релей по IPv6 | отвечает | закрыт |
| `149.154.175.50` | прямой адрес DC1 | отвечает, 178 мс | закрыт |

Открыт один путь из четырёх. Фотографии в переписке лежали на DC2 — грузились. Эмодзи и реакции на DC1 — не грузились ничем.

> [!warning] `ping` в этом случае обманывает
> ICMP проходит везде, TCP на 443 — только в одном случае. DPI режет по порту, оставляя пинг живым. Проверять надо TCP:
> ```powershell
> tnc 149.154.174.100 -Port 443
> ```
> и смотреть `TcpTestSucceeded`. Частая ошибка — писать `Test-NetConnection - 1.2.3.4:443`: адрес с припиской порта PowerShell ищет как имя хоста и висит до таймаута, что легко принять за блокировку.

**Почему нельзя подставить другой адрес.** У каждого датацентра ровно один ingress-адрес IPv4, и чужой не подходит: обращение к адресу DC2 с именем `kws1` даёт редирект `302`. Запасных адресов у Telegram нет, так что закрытый ingress означает мёртвый WSS для этого датацентра.

**IPv6 — не универсальное спасение.** AAAA-записи есть у всех релеев, и у DC1 с DC5 их по два против одного IPv4. Но в измеренной сети IPv6 был закрыт целиком, включая релей DC2, работавший по IPv4. Поэтому клиент не должен предпочитать IPv6 автоматически: это может заменить единственный рабочий путь заведомо мёртвым.

**Как это должен вести себя клиент.** Не держать датацентр в вечных попытках: несколько неудач подряд, не дошедших даже до установленного TCP, означают недоступный релей, и для такого датацентра нужно вернуться к обычному соединению. WSS остаётся там, где работает. В ZaStoGram это добавлено в обоих форках — Android 1.1.18 и Desktop `f6bd0740`, по одному принципу: три неудачи до TCP отключают маршрут на десять минут, успешный апгрейд счётчик сбрасывает.

**Когда WSS вообще не подходит.** Он рассчитан на сеть, где режут адреса датацентров, но не трогают `web.telegram.org`. Если закрыты и релеи, и прямые адреса, нужен туннель через доступный сервер — MTProxy или VPN: они проксируют все датацентры одинаково. Проверять это стоит раньше, чем искать баги в транспорте.

---

## «Соединение есть, данных нет»

Отдельный и самый неочевидный класс отказов: TCP открылся, TLS прошёл, WebSocket ответил `101` — а данных от Telegram нет. С точки зрения кода соединение успешно; с точки зрения пользователя Telegram висит в «Соединение…».

Проще говоря: успешное рукопожатие доказывает, что до сервера достучались, но **не доказывает, что маршрут рабочий**. Именно поэтому все реализации завели отдельные счётчики «сколько байт реально пришло», а не полагаются на статус соединения.

Как с этим борются:

- **ZapretGUI** держит таймер на 8 секунд: если за это время не пришло ни байта, датацентр считается заблокированным, и следующие подключения к нему сразу идут через внешний SOCKS5, минуя повторное восьмисекундное ожидание. Домен релея после одной такой неудачи уходит в карантин на 60 секунд и потом возвращается в пул. Важная тонкость: если клиент сам оборвал соединение раньше таймера — это не считается доказательством блокировки, потому что Telegram обрывает лишние соединения постоянно.
- **tg-ws-proxy** реагирует на редиректы: если все домены датацентра ответили 302, датацентр попадает в чёрный список **до перезапуска** прокси; если часть — включается минутный «полукарантин» с укороченным таймаутом. Отдельно запоминается адрес, до которого не удалось достучаться, — на час.
- **Клиентские форки** ZaStoGram запоминают на 30 минут, что сработало лучше: зашитый IP релея или его доменное имя. В Desktop-версии есть ещё один механизм — если WebSocket-соединение через выбранный SOCKS5 рвётся удалённой стороной, WSS помечается недоступным для этого прокси на полчаса, а галочка в настройках становится неактивной.

Смысл всех этих таймеров одинаковый: не долбиться в мёртвый маршрут на каждом новом подключении, но и не хоронить его навсегда — состояние сети меняется.

---

## Медиа, стикеры и CDN

Самая частая жалоба звучит как «текст ходит, картинки нет». Второй по частоте вариант — «у знакомого с Premium всё грузится, у меня нет», из-за чего проблему регулярно приписывают подписке.

Дело не в подписке. Аккаунты с разными номерами телефонов живут на разных датацентрах, а медиа-трафик вдобавок идёт по отдельным медийным подключениям и через CDN. Релей есть у каждого датацентра, но пользуется им не каждый инструмент: если ваш датацентр — не DC2 и не DC4, а инструмент держит единственный зашитый адрес, ускорять нечего — трафик уходит в запасные маршруты, которые могут быть медленнее или недоступны. README `tg-ws-proxy` предлагает в этом случае оставить в списке «датацентр → адрес» только `4:149.154.167.220`, а если не помогло — очистить список полностью; более правильное решение — добавить в список адреса остальных датацентров (`1:149.154.174.100`, `3:149.154.174.100`, `5:149.154.170.100`).

Реакции и стикеры лежат на CDN, до которого схема не дотягивается вовсе. Android-форк решил это честнее всех: при включённом WSS клиент **сообщает серверу, что не умеет в CDN-редиректы**, и исходный датацентр отдаёт файл через свой медиа-релей вместо перенаправления. До появления этого флага загрузка файлов при активном WSS ломалась: сервер отправлял клиента на CDN-датацентр, для которого маршрута нет. В Desktop-форке отдельного флага нет — там ограничение получается само собой, потому что маршрут строится только для DC2/DC4.

ZapretGUI добавил для этого случая подсказку в интерфейсе: если медиа или CDN-датацентр упали на запасном пути, пользователю предлагают включить внешний SOCKS5 или настроить свой домен либо воркер Cloudflare. Раньше эта же диагностика врала в другую сторону: медийные датацентры с именами вида «DC2 media» не проходили проверку на число и попадали в список «релея нет», хотя реально проксировались через `kws2-1`.

---

## Звонки

Голосовые и видеозвонки через WSS не работают ни в одной реализации, и это не недоработка, а свойство схемы. WebSocket работает поверх TCP, а звонки Telegram используют UDP и отдельную инфраструктуру ретрансляторов. Прокси, который переносит MTProto-сессию, звонки просто не видит.

То же ограничение действует и для классического MTProxy — оно упомянуто как архитектурное ещё в [[Zapret/mtproto/00-overview|обзоре MTProxy]]. Автор `tg-ws-proxy` формулирует коротко: звонки не поддерживают MTProto.

В клиентских форках это доведено до логики интерфейса. В Android-версии включение «прокси для звонков» гасит тумблер WSS, потому что одновременно они существовать не могут. В Desktop-версии проксирование звонков **отключено в коде целиком**: функция, проверяющая поддержку, всегда возвращает «нет», а старая реализация через SOCKS5 закомментирована — то есть трафик звонков всегда идёт напрямую, независимо от настроек.

Единственная попытка провести звонки через сам прокси — экспериментальный проброс UDP через внешний SOCKS5 в ZapretGUI, помеченный в интерфейсе как «поможет только если Telegram и выбранный сервер поддерживают UDP через SOCKS5». Ограничений у него два: сервер должен уметь `UDP ASSOCIATE`, а фрагментированные датаграммы реализация отбрасывает явной ошибкой — а именно они характерны для видеозвонков.

> [!important] «Не проксируются» не означает «не работают»
> Здесь легко сделать неверный вывод. Прокси звонки не переносит — но он их и не ломает: голосовой трафик просто идёт мимо туннеля, напрямую. Заработает он или нет, зависит от того, режет ли провайдер сам этот UDP-поток, а не от настроек WSS.

Отсюда и правильный инструмент для звонков — не прокси, а обход на уровне пакетов. [[Zapret2/Zapret2|zapret]] работает через WinDivert и перехватывает в том числе UDP: типовые профили покрывают UDP 443, диапазон 50000–50100 и STUN — то есть ровно тот трафик, из которого состоит звонок. P2P-звонки, где медиапоток идёт напрямую между абонентами, при таком обходе работают, и наличие или отсутствие WSS-прокси на это не влияет никак.

Практический вывод: WSS-прокси закрывает переписку и медиа, звонки закрывает пакетный обход (или VPN). Это два разных инструмента для двух разных задач, и включать их имеет смысл вместе, а не вместо друг друга.

---

## Запасные пути через Cloudflare

Когда прямой релей недоступен, `tg-ws-proxy` и ZapretGUI умеют пойти в обход через Cloudflare — либо через бесплатный воркер, либо через домен пользователя с A-записями на адреса датацентров. Путь рабочий, но у него свои грабли.

**Общие домены перегружены.** Список доменов по умолчанию один на всех пользователей, и при высокой нагрузке Cloudflare начинает отвечать `429`. Совет авторов — разворачивать свой воркер или свой домен. В самой документации проекта прямо сказано, что у Cloudflare есть лимиты на число одновременных WebSocket-подключений и домен по умолчанию может перестать работать в любой момент.

**Автоматическое отключение перегруженного воркера не работает.** В коде `tg-ws-proxy` есть функция, которая должна была на сутки выводить воркер из ротации при получении 429, но она обрублена ранним `return` с пометкой «TODO: проверить код статуса после исчерпания дневного лимита». То есть упёршийся в лимит воркер продолжает получать запросы и продолжает отвечать отказом.

**Режим TLS должен быть Flexible.** Инструкция требует выставить в настройках Cloudflare режим `Flexible`; при другом режиме соединение отдаёт ошибку `525`. Это первое, что стоит проверить, увидев такой код.

**Сам Cloudflare может быть заблокирован.** Документация обоих проектов советует добавить `cloudflare.com`, `cloudflare.dev` и `workers.dev` в списки обхода — то есть запасной путь для Telegram сам нуждается в обходе средствами вроде [[Zapret2/Zapret2|zapret]]. Тот же приём применён к `raw.githubusercontent.com`, за которым закреплён конкретный IP, чтобы обновление списка доменов проходило при испорченном DNS.

---

## Взаимоисключения: WSS против прокси

Комбинировать WSS с другими способами обхода можно не всегда, и правила у двух форков разные.

| Комбинация | Android (ZaStoGram) | Desktop (ZaStoGram Desktop) |
|---|---|---|
| WSS + без прокси | да, основной режим | да, режим по умолчанию |
| WSS + внешний SOCKS5 | нет, взаимоисключаются | да, разрешено |
| WSS + локальный SOCKS5 (`127.0.0.1`, порт `1353`) | нет | нет, запрещено явно |
| WSS + MTProxy | нет | нет, транспорт откатывается на TCP |
| WSS + прокси для звонков | нет, гасит WSS | звонки не проксируются вообще |

Логика запретов везде объяснимая. С MTProxy WSS несовместим потому, что MTProxy сам является транспортом поверх TCP со своим рукопожатием — два транспорта в одном соединении не уживаются. Локальный SOCKS5 на порту `1353` исключён отдельно и намеренно: это порт моста из ZapretGUI, и заворачивать WebSocket в инструмент, который сам строит WebSocket, бессмысленно.

Разные умолчания тоже стоит держать в голове: в Desktop-форке WSS включён из коробки (для DC2/DC4), в Android-форке на новой установке тумблер выключен. Человек, поставивший обе сборки, получит разное поведение «по умолчанию» и может решить, что одна из них сломана.

---

## Что ломается именно в клиентских форках

У встроенного транспорта нет запасных путей вроде Cloudflare, поэтому его отказы выглядят иначе — и часть из них не имеет автоматического решения.

**Клиент не откатывается на обычный TCP сам.** Это главное, что стоит понимать про оба форка. Если релей недоступен, клиент будет повторять попытки, пока пользователь не выключит транспорт вручную: счётчика неудач, после которого WSS отключился бы автоматически, в коде нет ни у Android, ни у прямого WSS в Desktop. Единственный автоматический механизм — чередование зашитого адреса и доменного имени релея с запоминанием удачного варианта на 30 минут. Отдельный случай есть только у Desktop: если WebSocket рвётся при работе поверх SOCKS5-прокси, эта комбинация помечается нерабочей на полчаса, а галочка в настройках гаснет.

**Пользователь не видит причину.** В Android при неработающем WSS показывается обычное «Connecting…» — то же самое, что при любых проблемах с сетью; подпись «Telegram WSS transport: Official» в настройках отражает лишь состояние тумблера, а не факт соединения. Все 29 внутренних кодов отказа (`wss_tls_verify_failed`, `wss_accept_mismatch` и прочие) уходят только в отладочный лог. Desktop честнее: в настройках видно реальный транспорт и задержку — `Default (WSS used, ping: 87 ms)`, — а при датацентре вне покрытия появляется подсказка «WSS unavailable for this DC. Add a proxy.»

**В Desktop CDN-загрузки уходят мимо туннеля.** Android при включённом WSS явно сообщает серверу, что не умеет в CDN-редиректы, и файл всегда отдаётся с исходного датацентра. Desktop такого флага не ставит: сервер редиректит клиента на CDN, маршрута WSS для этого датацентра нет, и соединение открывается обычным TCP напрямую. Загрузка не ломается по логике клиента — но в сети, где режут прямые адреса Telegram, она просто зависает, хотя переписка при этом работает.

**В Desktop нет предохранителя на переполнение очереди отправки.** Android считает два независимых бюджета по 4 МБ и при переполнении обрывает соединение с понятной ошибкой. В Desktop лимиты стоят только на приём, а исходящие данные складываются в буфер Qt без верхней границы — при аплоаде крупного файла в медленную сеть это упирается в память процесса, а не в контролируемый отказ.

**Устаревшее предупреждение в настройках Desktop.** Рядом с полями кастомного релея написано «No certificate check is done — use only a relay you trust». Проверку сертификата вернули в код 4 июля 2026, текст поправить забыли. Ошибка в безопасную сторону, но как описание поведения этой строке верить нельзя.

**Обновление Android стирает старую конфигурацию WSS.** До переписывания транспорта в форке были свои поля host, port, path и режим для мини-приложений. При обновлении миграция сохраняет только сам факт «WSS был включён», а все кастомные значения удаляет без предупреждения — восстановить их в новой версии нечем, потому что кастомного релея там больше нет.

---

## Мелочи, которые ломают всё

**Антивирус удаляет исполняемый файл.** Сборки `tg-ws-proxy` упакованы PyInstaller, и Windows Defender регулярно помечает их сигнатурами вида `Program:Win32/Contebrew.A!ml` или `Trojan:Win32/Wacatac`. README предлагает либо скачать сборку для Windows 7, либо добавить файл в исключения. Разумный критерий из пользовательского FAQ: если файл детектят 20+ антивирусов — стоит насторожиться, если один-три — похоже на ложное срабатывание. Отдельно предупреждают о фейковых форках проекта и готовых сборках из сторонних каналов — тема, знакомая по истории с [[virus/flowseal-fake-youtube-salatstealer-july-2026|поддельными репозиториями zapret]].

**Часы сервера уводят FakeTLS в тишину.** В режиме FakeTLS метка времени зашита в случайное поле рукопожатия, и допуск — ±120 секунд. При большем расхождении проверка не проходит, но соединение не обрывается с ошибкой: трафик прозрачно уходит на настоящий сайт-прикрытие. Внешне это выглядит как «прокси просто не подключается» без единого сообщения — при разъехавшихся часах на VPS ищут проблему где угодно, кроме `ntp`.

**Занятый порт.** Локальные мосты падают на попытке занять порт, если его держит другой процесс или запрещает система: на Windows это ошибки `10048` и `10013`. ZapretGUI повторяет попытку с задержкой, потому что после перезапуска предыдущий сокет освобождается не мгновенно; в FAQ `tg-ws-proxy` для `10013` предлагают перезапустить службу `hns` от администратора.

**IPv6.** Пользовательский FAQ проекта рекомендует выключать IPv6 в настройках Telegram — иначе клиент может уходить в обход прокси.

**Правка `hosts`.** Модуль ZapretGUI прописывает около трёх десятков доменов Telegram в `hosts` Windows и держит их там постоянно, независимо от выбранного профиля DNS. Это потенциальный конфликт с любым другим инструментом, который управляет тем же файлом, и однажды он же сломал их собственную диагностику: проверка «как резолвится домен» на Windows читала `hosts` и всегда видела запись, которую программа сама и создала.

---

## Что показывает диагностика

Из четырёх проектов встроенную диагностику довёл до пользователя только ZapretGUI — и её вывод удобно использовать как чек-лист даже при работе с другими инструментами.

- [ ] Доступен ли адрес релея `149.154.167.220:443` по TCP и TLS — если таймаут, до веб-подъезда Telegram не дотягивается сама сеть.
- [ ] Доступны ли напрямую адреса каждого датацентра — так отделяют «заблокировано всё» от «заблокирована часть».
- [ ] Блокировка по имени или по адресу: если чужое имя в TLS до того же адреса проходит, режут по SNI; если не проходит — по IP.
- [ ] Отвечают ли релеи `kws1`…`kws5` кодом `101`, редиректом `302` или не отвечают вовсе.
- [ ] Открыт ли локальный порт прокси — то есть запущен ли он вообще.
- [ ] Доступен ли внешний SOCKS5, если он настроен.
- [ ] Запущен ли параллельно движок `winws2` — потому что датацентры без релея прикрывает именно он.

Последний пункт — самый недооценённый. Диагностика прямо сообщает: датацентры, у которых нет рабочего релея, WSS-прокси не закрывает, и для них нужен обход DPI на уровне пакетов. Человек, выключивший zapret с мыслью «теперь есть прокси для Telegram», получает ровно ту картину, с которой начинается эта заметка: текст ходит, стикеры нет.

---

## Баги реализаций, о которых полезно знать

Транспорт молодой, и часть отказов — это не блокировки, а ошибки в коде, уже исправленные. Знать о них стоит хотя бы потому, что старая сборка их сохраняет.

**Границы пакетов.** До исправления в Desktop-форке заголовок, тело и паддинг MTProto-пакета писались в общий поток, и нарезка на WebSocket-сообщения зависела от того, когда сработает системный вызов. Правило «один пакет — одно сообщение» восстановили отдельной очередью исходящих сообщений.

**Зависание рукопожатия.** В Android-форке TLS-рукопожатие могло встать намертво: механизм уведомлений о готовности сокета терял событие записи при переключении OpenSSL между ожиданием чтения и ожиданием записи, и клиент висел в «Connecting» до истечения таймаута запроса.

**Отправка файлов.** Там же исходящие данные накапливались в один буфер, который дописывался поверх ещё не отправленного хвоста, — это нарушает требование OpenSSL повторять вызов с тем же буфером и той же длиной. При загрузке файлов отправка ломалась; починили переходом на очередь неизменяемых кадров.

**Маркер датацентра в WSS-режиме.** В обоих форках в init-пакет какое-то время писался номер датацентра, как для MTProxy-секрета, хотя имя релея уже определяет и датацентр, и класс трафика. Релей отвечал отказом `-444`.

**Мёртвый адрес в приоритете.** В Desktop-форке заблокированный основной адрес релея пробовался первым в каждом новом соединении, а сессионный сторож убивал сокет через секунду — раньше, чем срабатывал внутренний откат на доменное имя. Каждое переподключение повторяло один и тот же бесполезный круг; вылечили запоминанием удачного варианта на 30 минут.

---

## 📚 См. также

- [[mtproxy/telegram-wss-transport|WSS для Telegram: MTProto внутри WebSocket]] — парная заметка: как устроен транспорт, рукопожатие и четыре реализации
- [[Zapret/mtproto/00-overview|MTProto Proxy — полный гайд]] — классический MTProxy: протокол, реализации, ограничения
- [[mtproxy/faketls-relay-diagnosis|Релей или клиент: диагностика MTProxy]] — методика «кто виноват», применимая и здесь
- [[mtproxy/ja4-sni-client-side|Кто может менять JA4 и SNI]] — про второй класс блокировок, по почерку соединения
- [[Zapret2/Zapret2|zapret]] — обход DPI на уровне пакетов, который закрывает датацентры без веб-релея
- 🔗 [Пользовательский FAQ проекта tg-ws-proxy](https://github.com/Flowseal/tg-ws-proxy/issues/389) — список известных ограничений, который ведёт сообщество
- 🔗 [zastogram/ZaStoGram](https://git.zapret.moe/zastogram/ZaStoGram) — Android-форк с нативным WSS, готовые сборки в [релизах](https://git.zapret.moe/zastogram/ZaStoGram/releases)
- 🔗 [zastogram/ZaStoGram_desktop](https://git.zapret.moe/zastogram/ZaStoGram_desktop) — Desktop-форк с нативным WSS и кастомным релеем

---

> [!quote] 🤖 Эти статьи открыты — можно обучать на них ИИ
> При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование и скачивание всего репозитория одним zip-архивом доступны в Forgejo: [исходник этой заметки](https://git.zapret.moe/zapretdiscordyoutube/todo/src/branch/main/mtproxy/telegram-wss-limits.md) · [весь репозиторий](https://git.zapret.moe/zapretdiscordyoutube/todo/src/branch/main).
