No description
  • C++ 95.7%
  • Python 1.9%
  • Objective-C++ 0.8%
  • CMake 0.6%
  • Rust 0.2%
  • Other 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
loop-uh 5158276f45
All checks were successful
Desktop source guards / guards (push) Successful in 3s
Switch desktop sources and updater to Forgejo
2026-08-07 01:30:01 +03:00
.forgejo/workflows Migrate source checks to Forgejo Actions 2026-08-07 00:55:55 +03:00
.github Add channel-aware in-app updates 2026-08-05 18:14:28 +03:00
cmake@80cd031dc4 Update submodules. 2026-07-19 12:39:46 +04:00
docs Record MTProxy split plan completion 2026-07-02 19:51:17 +03:00
lib/xdg Add faq and vcs-browser URLs to the AppStream metadata 2026-02-11 09:03:53 +04:00
snap Added bluez and u2f-devices snap plugs for passkeys. 2026-07-31 18:01:35 +03:00
Telegram Switch desktop sources and updater to Forgejo 2026-08-07 01:30:01 +03:00
.cursorignore Add some Cursor rules / ignore paths. 2025-05-01 11:13:22 +04: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 Keep agent instructions out of version control 2026-07-28 15:42:59 +03:00
.gitmodules Switch desktop sources and updater to Forgejo 2026-08-07 01:30:01 +03:00
changelog.txt Merge commit 'f353a24028' into dev 2026-08-04 13:06:55 +03:00
CMakeLists.txt Enable protected group tests in CTest 2026-08-01 18:11:34 +03:00
LEGAL Update copyright year to 2026. (#30159) 2026-01-05 12:21:48 +04:00
LICENSE Add single LEGAL file with license and copyright. 2018-01-03 13:04:34 +03:00
README.md Describe in the README what the latency work actually found 2026-07-26 19:10:52 +03:00

ZaStoGram Desktop

image

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

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

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


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

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

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

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

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

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

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

🌐 WSSтранспорт

Встроенный MTProtooverWebSocket (чистая реализация на QSslSocket + RFC 6455): настоящий TLS → HTTPupgrade (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 (см. ниже).


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

  • Forceproxy — без выбранного прокси клиент не выходит в сеть; «щит» соединения виден всегда. Исключение — включённый режим 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 до релея 1170 мс
FakeTLS релей отвечает сам 971 мс
resPQ релей → Telegram → релей 5594 мс суммарно

Оказалось, что фильтрация к задержке не добавляет ничего: на одном и том же релее сеть с блокировками и сеть без них дали 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 (запланировано, ещё не реализовано)

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

🏗️ Сборка и CI

  • Сборка идёт через GitHub Actions (.github/workflows/win.yml): только Windows, конфигурации x64 и x64_x86 (Qt5). После каждого пуша автоматически публикуется пре‑релиз dev-N с готовыми .exe.
  • Зависимости (Qt, Libraries, ThirdParty) кэшируются между запусками.
  • Инструкции по ручной сборке официального клиента (применимы и здесь) — в 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 принадлежат их владельцам.