# 🧯 Ограничения 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. **Из релеев Telegram надёжно отвечают апгрейдом до WebSocket только DC2 и DC4.** Остальные в проверках отдавали редирект 302 либо принимали соединение и молчали, поэтому все реализации по умолчанию рассчитаны на эти два датацентра. 2. Самый частый симптом — **«всё работает, но не грузятся фото, видео, стикеры и реакции»**. Причина обычно не в аккаунте, а в том, что нужный контент лежит на датацентре или CDN, у которого рабочего релея нет. 3. **Звонки и групповые войс-чаты такой прокси не переносит** — они ходят по UDP, а WebSocket живёт поверх TCP. Это не значит, что они не работают: трафик звонка идёт мимо туннеля напрямую, и закрывает его пакетный обход вроде [[Zapret2/Zapret2|zapret]] (он перехватывает UDP и STUN), а не прокси. 4. Отдельный класс отказов — **«соединение установилось, данных нет»**: рукопожатие прошло, `recv` остаётся нулевым. Реализации ловят это таймерами и уводят маршрут в карантин на 60 секунд, час или полчаса — в зависимости от проекта. 5. Бесплатные запасные пути через **Cloudflare** упираются в лимиты: общие домены отдают 429, неверный режим TLS даёт ошибку 525, а сами подсети Cloudflare в РФ тоже могут блокироваться. 6. WSS **несовместим** с MTProxy и (в Android-форке) с обычным прокси: включение одного гасит другое, и это поведение задумано, а не баг. 7. Клиентские форки **не откатываются на обычный TCP автоматически**: при недоступном релее попытки повторяются, пока пользователь не выключит транспорт руками, а причина отказа в интерфейс не выводится. --- ## Почему работают только DC2 и DC4 У Telegram пять обычных датацентров плюс отдельные идентификаторы для CDN. Веб-релеи по схеме `kwsN.web.telegram.org` формально строятся для любого номера — но принимают соединение не все. Формулировка в коде ZapretGUI не оставляет двусмысленности: только релеи DC2 и DC4 принимают подключения, DC1, DC3 и DC5 отвечают редиректом `302`. Проект ведёт каталог маршрутов, где `kws2`/`kws4` помечены как стабильные с датой подтверждения (14 июня 2026, повторный апгрейд возвращал `101`), а `kws1`, `kws3`, `kws5` и `kws203` — как «только запасной путь», с пояснением, что стабильного `101` они не показали. Desktop-форк ZaStoGram зашивает это ограничение прямо в код: маршрут строится, только если номер датацентра равен 2 или 4, иначе WSS не рассматривается вовсе. Android-форк смелее — он объявляет DC1–DC5 и держит для них три зашитых адреса релеев (`149.154.174.100` для DC1/DC3, `149.154.167.220` для DC2/DC4, `149.154.170.100` для DC5), — но это заявка на покрытие, а не гарантия, что конкретный релей ответит именно вам. Стоит знать, откуда взялась эта разница. Первая версия Android-транспорта поддерживала те же DC2/DC4, что и Desktop; расширение до пяти датацентров внесли в тот же день, 5 августа 2026, вместе с исправлением загрузки медиа. Проверки живым соединением в репозитории нет — тест, который к этому прилагается, статически сверяет текст кода, а не факт успешного апгрейда к `kws1`, `kws3` или `kws5`. Если ваш датацентр — один из этих трёх, поведение стоит проверять на своём подключении, а не полагаться на список в коде. С 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-пакета и поведение прокси, и при расхождениях выключает его целиком, а не просто повторяет попытку. --- ## «Соединение есть, данных нет» Отдельный и самый неочевидный класс отказов: 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`, а если не помогло — очистить список полностью. Реакции и стикеры лежат на 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+ антивирусов — стоит насторожиться, если один-три — похоже на ложное срабатывание. Отдельно предупреждают о фейковых форках проекта и готовых сборках из сторонних каналов — тема, знакомая по истории с [[Zapret/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) — список известных ограничений, который ведёт сообщество - 🔗 [youtubediscord/ZaStoGram](https://github.com/youtubediscord/ZaStoGram) — Android-форк с нативным WSS, готовые сборки в [релизах](https://github.com/youtubediscord/ZaStoGram/releases) - 🔗 [youtubediscord/ZaStoGram_desktop](https://github.com/youtubediscord/ZaStoGram_desktop) — Desktop-форк с нативным WSS и кастомным релеем --- > [!quote] 🤖 Эти статьи открыты — можно обучать на них ИИ > При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование и скачивание всего репозитория одним zip-архивом доступны на GitHub: [исходник этой заметки](https://github.com/youtubediscord/todo/blob/main/mtproxy/telegram-wss-limits.md) · [весь репозиторий](https://github.com/youtubediscord/todo/tree/main).