ZaStoGram Desktop — форк Telegram Desktop для сетей с DPI: FakeTLS, WSS, приватность, сохранение удалённых сообщений и стабильные обновления. https://t.me/zastogram
  • C++ 95.8%
  • Python 1.9%
  • Objective-C++ 0.7%
  • CMake 0.6%
  • CSS 0.2%
  • Other 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
loop-uh 8015cb4f9d
All checks were successful
Desktop source guards / guards (push) Successful in 6s
Не выпадать из DC1 на проверку мёртвого релея и не замерзать в туннеле
По логу dev-27 (25.09, 18:40–18:45):

- После двух минут подавления релей kws1, к которому TCP не проходит ни
  разу, проверялся заново бюджетами 1+2+4+8 с, и DC1 каждые ~2 минуты
  выпадал на 15 с. Повторное подавление без единого ответа между ними
  удваивается: 2, 4, 8, 16, до 30 минут.
- Основная сессия DC1 через туннель замерзала после 11–15 КБ и ждала
  8 с таймаута приёма каждые 15–50 с. Ротация на границе пакета теперь
  есть и у основных сессий, после 8 КБ; у файловых — по-прежнему 4 КБ.
- Сокет туннеля медиа был готов только через 3,7 с и убивался бюджетом
  4 с; минимальный бюджет подключения через туннель — 6 с.
2026-09-25 18:46:04 +03:00
.agents Merge upstream dev through 64ca5475f2 2026-09-25 14:38:13 +03:00
.claude/commands Merge upstream dev through 64ca5475f2 2026-09-25 14:38:13 +03:00
.forgejo Перевести проверки и обновления desktop в Forgejo 2026-08-07 06:57:18 +03:00
.grok [ai] Trying less verbose Codex performers. 2026-09-24 22:54:02 +04:00
cmake@5e21e7ac35 Move rlottie -> tlottie. 2026-09-07 19:14:54 +04:00
docs Merge upstream dev through a1ea1ddd8c (7.2.9) 2026-09-23 16:21:17 +03:00
lib/xdg Перевести проверки и обновления desktop в Forgejo 2026-08-07 06:57:18 +03:00
snap Update patches revision. 2026-09-24 22:01:56 +04:00
tasks/2026/08 Remove stale Info teardown implementation note 2026-09-24 22:22:16 +04:00
Telegram Не выпадать из DC1 на проверку мёртвого релея и не замерзать в туннеле 2026-09-25 18:46:04 +03:00
tools Added tests of house rules hook. 2026-09-14 18:03:15 +03:00
.clang-tidy Added clang-tidy ban of qRound. 2026-09-14 18:41:40 +03:00
.devcontainer.json Ensure clangd cache is out of build directory 2025-05-13 10:41:42 +04:00
.gitattributes Keep qtbase patches LF so they apply on Windows 2026-07-28 16:20:08 +03:00
.gitignore Ignore tester log archives 2026-09-24 20:36:59 +03:00
.gitmodules Merge upstream dev through a1ea1ddd8c (7.2.9) 2026-09-23 16:21:17 +03:00
changelog.txt Merge upstream dev through a1ea1ddd8c (7.2.9) 2026-09-23 16:21:17 +03:00
CMakeLists.txt Enable protected group tests in CTest 2026-08-01 18:11:34 +03:00
GROK.md [ai] Test workflow in Grok Build. 2026-08-12 22:28:05 +04:00
LEGAL Update copyright year to 2026. (#30159) 2026-01-05 12:21:48 +04:00
LICENSE Moved OpenSSL exception below GPL terms in LICENSE. 2026-08-26 14:18:16 +03:00
README.md Перевести проверки и обновления desktop в Forgejo 2026-08-07 06:57:18 +03:00

ZaStoGram Desktop

Обзор ZaStoGram Desktop

ZaStoGram — форк Telegram Desktop, заточенный под работу в сетях с DPI‑цензурой и под приватность. Цель проекта: чтобы клиент уверенно подключался там, где обычный Telegram режут, маскировал трафик под обычный браузерный HTTPS и не терял переписку (удалённые сообщения, истории, правки).

Это неофициальная сборка. Она основана на исходниках официального клиента и сохраняет весь его функционал, добавляя сверху сетевой стелс, WSS‑транспорт и набор приватных функций.

⚠️ Используйте на свой риск. Проект не связан с Telegram FZ‑LLC. Базовый код — под GPLv3 с OpenSSL‑исключением (см. раздел «Лицензия»).


Чем отличается от обычного Telegram Desktop

Область Что добавлено
Обход DPI FakeTLS‑стелс: профили ClientHello, правдоподобные повторные TLS‑подключения через поддельные билеты возобновления, маскировка старта, фрагментация ClientHello, варьирование размера TLS‑записей, пейсинг трафика, разнос попыток подключения
Надёжность Классифицированный loop‑backoff переподключения (cap 8 c), деприоритизация «залипших» endpoint'ов (cooldown)
Транспорт Встроенный WSS (MTProto поверх WebSocket к web‑релею Telegram)
Прокси Обязательный прокси (force‑proxy) + дефолтный локальный SOCKS5 127.0.0.1:1353
Приватность Сохранение удалённых сообщений и историй (stories), скачивание любых (даже защищённых) историй, история правок сообщений
Скорость подключения Убраны две клиентские задержки, найденные измерением: очередь дозвонов (было до 8 с ожидания на поздних сокетах) и невыключенный алгоритм Нейгла
Производительность Ограничение числа потоков софт‑декодера видео, троттлинг под нагрузкой
UX Список прокси больше не устраивает «шквал» проверок при открытии
Бренд Имя и иконка ZaStoGram

🛡️ Обход DPI — стелс MTProxy

Когда задан MTProxy (FakeTLS), клиент маскирует подключение под настоящий браузерный TLS‑хэндшейк. Всё настраивается тумблерами в окне прокси (Настройки → Продвинутые → Тип соединения → список прокси).

  • Профиль ClientHello — ClientHello воспроизводит форму реального браузера/приложения: Auto (Yandex), Auto‑rotate, Firefox, Firefox Android, Yandex, Android OkHttp. Профили Chrome Modern и Android Chrome остались в таблице, но больше не отправляются: измерением найдено, что фильтрующая сеть отвергает именно их — 3 попытки из 12 против 12 из 12 у остальных, на одном релее в одни минуты. Выбранный вручную отключённый профиль автоматически заменяется на рабочий.
  • Маскировка старта (startup‑cover) — первые записи разбиваются и подаются так, чтобы начало сессии не выделялось характерным паттерном.
  • Фрагментация ClientHello — ClientHello дробится при отправке, чтобы DPI было сложнее собрать и распознать его целиком.
  • Варьирование размера TLS‑записей — размеры записей не фиксированы, что ломает сигнатуры по длине.
  • Пейсинг трафика — межзаписевые задержки на старте сглаживают «взрывной» профиль (без удушения уже установленного потока).
  • Разнос попыток подключения — попытки к нескольким endpoint'ам стартуют со сдвигом, а не пачкой. Сдвиг намеренно небольшой (50 мс): измерение показало, что релеи спокойно принимают два десятка одновременных рукопожатий, а большой разнос стоил секунд на старте — подробности в разделе про задержку.
  • Правдоподобные повторные TLS‑подключения — первый ClientHello к узлу и имени назначения идёт без PSK, как обычный «холодный» заход браузера. После успешного fakeTLS‑хэндшейка клиент держит небольшой локальный пул поддельных билетов возобновления с ограниченным временем жизни и при повторных подключениях отправляет один из них с нормальным возрастом. Это убирает подозрительный паттерн «каждый параллельный сокет приносит новый случайный PSK» и делает повторные подключения похожими на обычный браузерный HTTPS. Эти билеты нужны только для маскировки, не используются для шифрования MTProto и не сохраняются на диск.

Надёжность подключения

  • Loop‑backoff — классифицированные таймауты переповтора, привязанные к прокси, с верхней границей, чтобы не зацикливаться на мёртвом узле и не спамить коннектами.
  • Endpoint cooldown — endpoint, который только что отвалился, временно понижается в приоритете (а не выбрасывается), чтобы клиент пробовал живые маршруты, не теряя резервные.

🌐 WSS‑транспорт

Встроенный MTProto‑over‑WebSocket (чистая реализация на QSslSocket + RFC 6455): настоящий TLS → HTTP‑upgrade (GET /apiws) → бинарные WS‑фреймы, внутри которых идёт обфусцированный MTProto‑поток. Подключается к официальным web‑релеям Telegram (kws2/kws4.web.telegram.org) для DC2/DC4.

Включается тумблером «Route via WSS (web, DC2/DC4 only)». Полезен там, где прямой TCP к DC блокируется, но веб‑Telegram работает. Может ходить как напрямую, так и через заданный SOCKS‑прокси.

Альтернатива встроенному WSS — внешний локальный прокси (telegram_proxy из zapret‑набора) на 127.0.0.1:1353, к которому клиент подключается по SOCKS5 (см. ниже).


🔌 Прокси: обязательный + дефолтный

  • Force‑proxy — без выбранного прокси клиент не выходит в сеть; «щит» соединения виден всегда. Исключение — включённый режим WSS (он сам является методом обхода). Это страховка от случайного прямого подключения в опасной сети.
  • Дефолтный SOCKS5 127.0.0.1:1353 — добавляется в список один раз (если такого ещё нет; существующие прокси не перетираются). Это endpoint внешнего сервиса telegram_proxy: схема tdesktop → SOCKS5 1353 → telegram_proxy → WSS/FakeTLS → Telegram.

🔒 Приватность

Клиент‑сайд функции, которые сохраняют данные локально (по умолчанию включены):

  • Сохранение удалённых сообщений — когда сервер присылает «удалить», сообщение не уничтожается локально, а остаётся (помечается как удалённое отправителем). Переписка не пропадает.
  • Сохранение историй (stories) — локальный снэпшот историй с восстановлением при старте; истории не исчезают по истечении срока.
  • Скачивание любых историй — медиа истории сохраняется на диск даже для защищённых от пересылки (noforwards) и чужих историй, без Premium (снят клиентский гейт canDownload).
  • История правок — при редактировании сообщения предыдущие версии (текст + время) сохраняются, чтобы видеть, что было изменено.

Это локальные функции: они не влияют на сервер и не нарушают шифрование. Хранение части данных может быть только в памяти до перезапуска (персистентность отдельных частей — в развитии).


⚡ Производительность

  • Decoder policy — централизованное ограничение числа потоков софтверного видео‑декодера и троттлинг запуска декодеров под нагрузкой, чтобы тяжёлые медиа не «съедали» CPU и не плодили лишние декодеры.

Задержка подключения: что было измерено и убрано

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

слой что это типичные значения
TCP до релея 11–70 мс
FakeTLS релей отвечает сам 9–71 мс
resPQ релей → Telegram → релей 55–94 мс суммарно

Оказалось, что фильтрация к задержке не добавляет ничего: на одном и том же релее сеть с блокировками и сеть без них дали 17/55 мс против 11/56 мс. Секунды создавал сам клиент, и нашлось два источника.

  • Очередь дозвонов. Попытки к одному релею разносились на 250 мс, а холодный старт открывает десятки сокетов — поздние ждали своей очереди секундами (в логе tcp_ms доходил до 8666 мс при сетевом round trip 17 мс). Разнос вводился ради маскировки, но измерение показало, что цена ему не соответствует: 24 дозвона вообще без разноса дошли до Telegram все 24, вся пачка за 170 мс, тогда как через очередь те же 24 стоили около шести секунд. Разнос снижен до 50 мс — этого хватает, чтобы соединения приходили различимо, а не одним мгновением. Рост разноса при неудачах не тронут: именно он защищает релей, который действительно не тянет пачку.
  • Алгоритм Нейгла. TCP_NODELAY не выставлялся ни на одном сокете. Нейгл придерживает короткую запись, пока не подтверждена предыдущая, а MTProto устроен ровно так: короткий запрос, затем ожидание. Тонкость, из‑за которой это легко сделать вхолостую: Qt применяет опции сокета через движок, который появляется только после установления соединения, поэтому выставлять их надо в обработчике connected, а не в конструкторе.

Обе правки закрыты тестами, которые держат числа рядом с константой — чтобы следующий, кто захочет вернуть разнос, спорил с измерением, а не с догадкой.

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

🧰 Спокойная архитектура прокси

  • Список прокси не запускает проверку всех строк при открытии окна — это убирает «шквал» одновременных тестовых коннектов. Строки по умолчанию в состоянии Unknown; проверка запускается вручную по пункту Check Status.

🗺️ Roadmap (запланировано, ещё не реализовано)

  • Глобальный лимитер MTProxy‑handshakes — в текущем Desktop каждый аккаунт держит свой MTP::Instance со своей DC‑сессией (разные auth keys, msg_id/seqno, salt), поэтому «один общий поток» для всех аккаунтов сделать нельзя без серверной поддержки. Вместо этого планируется безопасный лимитер: общий cap на число одновременных MTProxy‑handshakes между аккаунтами + jitter/backoff + очередь; снижение числа активных проверок ротации (10 → 1–2); кэширование статусов прокси; единый gate для всех StartProxyCheck и рабочих handshakes. Это сгладит всплеск подключений, не душа уже установленный трафик.
  • UI приватности — видимая метка «удалено» на сохранённых сообщениях и просмотрщик истории правок (контекст‑меню).

🏗️ Сборка и проверки

  • Forgejo Actions выполняет быстрые проверки исходников из .forgejo/workflows/source-guards.yml на изолированном Linux Runner.
  • Тяжёлая Windows-сборка выполняется локальным публикатором на выделенной Windows-машине, после чего проверенные .exe, ZIP и файлы автообновления загружаются в Forgejo Releases.
  • Единый список обязательных исходных проверок хранится в Telegram/SourceFiles/tests/release_guards.txt; его используют и Forgejo Actions, и локальный Windows-публикатор.
  • Инструкции по ручной сборке официального клиента (применимы и здесь) — в docs/.

Базовый клиент собирается стандартным тулчейном Telegram Desktop. Артефакты пре‑релиза переименовываются в ZaStoGram-<arch>.exe.


📥 Установка

Скачайте ZaStoGram-x64.exe (или x64_x86 для 32‑бит) из раздела Releases (пре‑релиз dev-N). Это сборка из исходников этого репозитория. Для работы дефолтного прокси 127.0.0.1:1353 нужен запущенный внешний сервис telegram_proxy, либо включите встроенный WSS‑транспорт.


📄 Лицензия

Проект основан на Telegram Desktop и распространяется под GPLv3 с OpenSSL‑исключением — тот же текст лицензии, что и у апстрима, см. LICENSE и LEGAL.

ZaStoGram — независимый форк; товарные знаки Telegram принадлежат их владельцам.