ZaStoGram — форк Telegram для Android с MTProxy FakeTLS, нативным WSS-транспортом, защитой приватности и обновлениями из Forgejo. https://t.me/zastogram
  • Java 60.9%
  • C++ 24.3%
  • C 10.5%
  • Kotlin 2.5%
  • Python 1.3%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
loop-uh 96c4549a4d
Some checks failed
Build three ZaStoGram APKs / build (arm64-v8a, ZaStoGram-standalone-arm64-v8a, Arm64, arm64) (push) Has been cancelled
Build three ZaStoGram APKs / build (armeabi-v7a, ZaStoGram-standalone-armeabi-v7a, Armv7, armv7) (push) Has been cancelled
Build three ZaStoGram APKs / build (x86, ZaStoGram-standalone-x86, X86, x86) (push) Has been cancelled
ZaStoGram source guards / guards (push) Has been cancelled
Не держать датацентр без медиа, если релей недоступен
У части провайдеров порт 443 к релею отдельного датацентра закрыт целиком:
у пользователя kws2-1 и kws4-1 отвечают, а kws1-1 не отвечает ни по IPv4,
ни по IPv6 — 15 таймаутов подряд на стадии установки TCP, ни одного
успешного подключения. Эмодзи и реакции лежат как раз на этом датацентре,
и WSS оставлял их без загрузки навсегда, работая по принципу «всё или
ничего».

Теперь неудачи, не дошедшие даже до установленного TCP, считаются по
датацентру отдельно от выбора адреса. После трёх подряд маршрут WSS для
него отключается на десять минут, и соединение идёт напрямую; успешный
апгрейд счётчик сбрасывает. Остальные датацентры продолжают работать через
WSS как раньше.

Заодно откачено предпочтение IPv6, введённое в 1.1.17: наличие у
устройства глобального IPv6-адреса не означает, что маршрут до релея
работает, и попытки тратились на заведомо недостижимый путь. Теперь IPv4
идёт первым как известно рабочий, а IPv6 — дополнительным кандидатом при
отказе. Запрос AAAA сохранён: он даёт второй адрес там, где у IPv4 он
единственный.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 15:48:19 +03:00
.codex Add hide all chats option and refresh project docs 2026-08-05 21:02:19 +03:00
.forgejo/workflows Не подписывать стабильные сборки запасным ключом 2026-08-09 00:09:19 +03:00
buildSrc Merge upstream Telegram 12.9.0 2026-07-16 20:59:14 +03:00
docs Убрать совместимость workflow с GitHub 2026-08-07 06:57:28 +03:00
gradle/wrapper update to 12.0.0 (6163) 2025-09-01 19:12:49 +04:00
TMessagesProj Не держать датацентр без медиа, если релей недоступен 2026-08-09 15:48:19 +03:00
TMessagesProj_App Add ZaStoGram plugin engine with Chaquopy/Pine 2026-06-28 00:06:34 +03:00
TMessagesProj_AppHockeyApp Add ZaStoGram plugin engine with Chaquopy/Pine 2026-06-28 00:06:34 +03:00
TMessagesProj_AppHuawei Add ZaStoGram plugin engine with Chaquopy/Pine 2026-06-28 00:06:34 +03:00
TMessagesProj_AppStandalone Не подписывать стабильные сборки запасным ключом 2026-08-09 00:09:19 +03:00
TMessagesProj_AppTests update to 12.9.0 (6966) 2026-07-16 16:46:05 +04:00
Tools Резать WSS-кадры по границам MTProto-пакетов 2026-08-09 14:22:17 +03:00
.gitignore Merge upstream Telegram 12.9.2 2026-08-05 17:41:35 +03:00
.gitmodules add third_party libs as submodules 2026-08-03 00:25:52 +04:00
apkdiff.py update apkdiff.py apkfrombundle.py 2023-01-26 17:06:12 +04:00
apkfrombundle.py update apkdiff.py apkfrombundle.py 2023-01-26 17:06:12 +04:00
build.gradle Выводить versionCode из тега релиза 2026-08-08 23:50:12 +03:00
Dockerfile update to 12.0.0 (6163) 2025-09-01 19:12:49 +04:00
gradle.properties Ускорить повторные Android-сборки 2026-08-07 20:06:54 +03:00
gradlew first commit 2013-10-25 19:19:00 +04:00
LICENSE first commit 2013-10-25 19:19:00 +04:00
README.md Исправить вход и обновление приложения 2026-08-08 17:15:06 +03:00
settings.gradle update to 11.14.0 (6102) 2025-08-11 13:36:23 +04:00

ZaStoGram — Telegram для Android с MTProxy FakeTLS и нативным WSS

ZaStoGram

ZaStoGram — экспериментальный форк официального Telegram для Android. Он сохраняет протокол и серверную инфраструктуру Telegram, но добавляет:

  • более строгий и диагностируемый MTProxy FakeTLS для ee-секретов;
  • управляемые JA4/TLS-профили с рабочим автопрофилем Telegram Desktop;
  • отдельный нативный WSS-транспорт через официальные WebSocket-релеи Telegram;
  • клиентские функции приватности, локальную историю правок и UX-настройки;
  • Python-плагины, совместимые с реализованной частью API exteraGram;
  • встроенные stable/dev-обновления из Forgejo Releases.

Это не новый мессенджер, не VPN и не отдельный протокол. Текущая база — Telegram Android 12.9.2, минимальная версия Android — 7.0 (minSdk 24). Stable и dev используют разные package id, поэтому устанавливаются параллельно: org.zastogram.messenger и org.zastogram.messenger.dev соответственно.

Скачать

Выбирайте APK по архитектуре устройства:

APK Для чего
arm64-v8a Почти все современные Android-смартфоны и планшеты
armeabi-v7a Старые 32-битные ARM-устройства
x86 Старые 32-битные эмуляторы

Актуальный стабильный релиз публикуется для этих трёх ABI, подписывается релизным ключом ZaStoGram и использует канал обновлений stable. Сборка x86_64 поддерживается исходниками, но не публикуется без отдельного запроса.

Транспортная архитектура

Клиент не смешивает WSS, MTProxy и SOCKS5 в один комбинированный прокси. ConnectionSocket выбирает один маршрут для конкретного соединения:

flowchart TD
    A["tgnet / ConnectionSocket"] --> B{"Выбранный маршрут"}
    B -->|"WSS включён, прокси выключен, DC поддержан"| C["wss::Socket"]
    B -->|"Выбран SOCKS5 или MTProxy"| D["Обычный proxy path"]
    B -->|"WSS выключен или route недоступен"| E["Прямой Telegram transport"]
    C --> F["TLS + WebSocket /apiws"]
    F --> G["Официальные relay DC1–DC5"]
    D --> H["SOCKS5 или MTProxy dd/ee"]
    H --> I["FakeTLS policy только для ee"]

Главные границы конструкции:

  • прямой транспорт не зависит от MTProxy lifecycle и его retry-политик;
  • MTProxy policy вынесена в TMessagesProj/jni/mtproxy/ и работает через фазовые состояния, evidence и один retry authority;
  • WSS реализован отдельным transport::Socket в TMessagesProj/jni/tgnet/wss/WssSocket.* и сам владеет TCP-дескриптором, TLS, WebSocket upgrade и очередями кадров;
  • legacy-прокси и WSS взаимоисключаемы: включение WSS выключает активный SOCKS5/MTProxy, а выбор обычного прокси выключает WSS;
  • WSS не наслаивается поверх SOCKS5 или MTProxy.

MTProxy FakeTLS

Relay-контракт ClientHello

FakeTLS применяется только к MTProxy с ee-секретом. Перед отправкой ClientHello проверяется по правилам reference relay:

  • SNI должен байт-в-байт совпадать с доменом из ee-секрета;
  • TLS record и handshake должны иметь согласованные длины;
  • session id должен занимать 32 байта;
  • первый набор шифров после relay-compatible GREASE должен быть TLS 1.3 (0x1301–0x1303);
  • размер ClientHello должен быть от канонических 517 до максимальных 4096 байт;
  • некорректный профиль блокируется до отправки в сеть.

Lowercase, trim, punycode и вариант без SNI могут рассчитываться для диагностики, но не подменяют wire-SNI. Relay сравнивает его с исходным доменом из секрета.

ClientHello и последующие TLS-записи имеют собственные pending-буферы. Неблокирующий send() может принять часть записи: остаток досылается на следующем EPOLLOUT, а MTProto payload удаляется из очереди только после полной отправки TLS frame.

JA4 / TLS-профили

Автоматический профиль синхронизирован с проверенной формой Telegram Desktop:

  • Auto отправляет рабочий Yandex-shaped профиль с намеренно сохранённой tdesktop-совместимой формой последнего GREASE extension;
  • Auto rotate выбирает из проверенного пула Yandex, Firefox Android, Firefox и Android OkHttp и меняет профиль только после релевантного post-ClientHello сбоя;
  • DNS-ошибки и tcp_not_connected не вращают JA4: ClientHello в этих фазах ещё не участвовал;
  • Chrome Modern и Android Chrome удерживаются от отправки и переводятся на безопасный автопрофиль: в контрольной сети они отвечали заметно хуже рабочего пула;
  • каждый собранный профиль повторно проходит relay-контракт перед отправкой.

Это не попытка сделать байт-в-байт копию установленного браузера. Приоритет — сначала совместимость с MTProxy relay, затем форма JA4 и дополнительные эксперименты.

Управляемые слои

Настройки MTProxy находятся в обычном экране прокси и передаются Java → JNI → native без пересборки APK:

Настройка Что меняет
JA4 / TLS-профиль Выбор ClientHello-рецепта
Мягкая фрагментация ClientHello Две неблокирующие отправки одного валидного hello
Размер TLS-записей Размер завершённых FakeTLS ApplicationData frames
Тайминги трафика Короткие паузы только между полностью отправленными frames
Стартовая маскировка MTProxy Форму первых реальных MTProto ApplicationData-записей
Меньше параллельных каналов Fanout download/upload при активном MTProxy
Паттерн подключений Допуск и приоритет новых FakeTLS handshakes

Размеры, тайминги и startup cover не перепаковывают MTProto в HTTP. Они меняют только TLS-подобное обрамление уже установленного FakeTLS-соединения.

Фазы и восстановление

MTProxy не лечит все сбои сменой JA4. Основные классы evidence разделены:

  • host_resolve_failed — DNS и кэш endpoint;
  • tcp_not_connected — путь до TCP и endpoint circuit breaker;
  • client_hello_sent_no_server_hello — ClientHello/relay recipe;
  • server_hello_hmac_mismatch — ответ пришёл, но не прошёл MTProxy HMAC;
  • post_handshake_no_appdata — handshake завершён, data-path не начался;
  • dropped_early_after_appdata — data-path успел заработать и быстро оборвался;
  • mtproxy_packet_sent_no_response — отдельный lifecycle обычных dd/legacy секретов, где JA4 вообще не участвует.

Модули MtProxyEndpointPolicy, MtProxyHandshakeScheduler, MtProxyProbeCoordinator, MtProxyAdaptivePolicy, MtProxyRecoveryPolicy и MtProxyRetryAuthority разделяют запись фактов, выбор рецепта, координацию проб и фактический reconnect. GUI и runtime-логи используют ту же карту фаз.

DRS пока не первым: до расширения динамических размеров записей должны быть стабильны DNS, TCP, handshake и data-aware отправка завершённых TLS frames. Иначе host_resolve_failed или mtproxy_packet_sent_no_response ошибочно выглядят как проблема record sizing, хотя соответствующий слой ещё не участвовал.

Архитектура проверки прокси

ProxyCheckScheduler владеет Java-очередью проверок, native socket публикует фазовые события, а finishProxyCheck завершает ровно активное поколение проверки. Java backoff использует ту же фазовую идею ключей: network-сбои группируются по адресу, а проверки склеиваются только по полному exact key host:port:username:password:secret.

Наблюдение generic Connected не стирает свежую terminal phase конкретного endpoint. Явный новый старт подключения может начать новое поколение, но не должен стирать ещё актуальный usable success. Итог проверяется через Tools/analyze_mtproxy_markers.py; verdict connected_without_socket_connected_marker означает, что Java увидела connected-state без подтверждённого native socket marker.

Нативный Telegram WSS

WSS — настоящий TLS + WebSocket transport, а не FakeTLS и не локальный proxy bridge. Он включается одним глобальным флажком:

Настройки → Данные и память → Прокси → Использовать WSS транспорт

Новая установка начинает с выключенным WSS. При миграции старый выбранный WSS режим превращается в этот флажок, а устаревшие host, port, path, SOCKS и MiniApp-поля удаляются схемой proxy config V4.

Как строится route

  • production DC1–DC5 используют kwsN.web.telegram.org;
  • media/download/upload соединения используют соответствующий kwsN-1.web.telegram.org;
  • путь WebSocket — /apiws, subprotocol — binary;
  • route, DNS, TLS SNI и hostname verification используют один официальный hostname; ручной таблицы relay IP нет;
  • WSS не наследует адрес или secret от выбранного TCP/MTProxy dcOption;
  • obfuscated init и каждый готовый abridged MTProto packet отправляются отдельными binary WebSocket messages;
  • test backend, неизвестные и CDN DC остаются на обычном транспорте;
  • пока WSS не умеет маршрутизировать CDN DC ids, клиент не объявляет поддержку CDN redirects для загрузок в этом режиме.

Что проверяет WSS socket

  • TLS не ниже 1.2;
  • цепочку сертификата через Android и встроенные root certificates;
  • hostname через SNI и SSL_set1_host;
  • HTTP status 101 и точный Sec-WebSocket-Accept;
  • размеры входных/выходных буферов и WebSocket frames;
  • masked client frames, binary/continuation frames и ping/pong.

В новой конструкции отсутствуют custom WSS gateway, SOCKS upstream, режим «SOCKS внутри WSS», MiniApp bridge и локальный relay на 127.0.0.1. Это намеренно: WSS — простой официальный транспорт клиента, а список Telegram proxy остаётся отдельным.

Пользовательские функции

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

Отдельный экран управляет клиентскими override-функциями:

  • сохранять удалённые сообщения;
  • сохранять view-once и самоуничтожающиеся материалы;
  • хранить локальную историю редактирования сообщений;
  • разрешать сохранение и пересылку защищённого контента и историй;
  • разрешать скриншоты и не отправлять screenshot ping в секретном чате;
  • отключать рекламные и промо-поверхности Telegram.

Это локальное поведение клиента, а не изменение серверной политики Telegram и не полноценная система архивирования.

Остальные изменения

  • скрытие stories row и кнопки создания истории на главном экране;
  • опция скрытия вкладки «Все чаты», когда создана хотя бы одна пользовательская папка, с переключением на первую доступную папку;
  • опция «Всегда держать сеть в фоне» без вызова клиентского native_pauseNetwork();
  • online presence отправляет только выбранный аккаунт;
  • кнопка прокси доступна в обычном login-flow до настройки прокси;
  • контакты не вызывают автоматический prompt доступа при открытии;
  • домашний DC показывается в профиле, если его можно надёжно определить;
  • Android 12+ splash использует логотип ZaStoGram;
  • файловые логи очищаются при старте нового процесса;
  • ссылки на канал, VPN, поддержку и управляемая sponsor-строка Zapret VPNs.

Плагины exteraGram

ZaStoGram запускает .plugin-файлы внутри приложения через CPython 3.11 и Chaquopy. Установка:

Настройки → Плагины → + → выбрать .plugin файл

Реализованы:

  • lifecycle on_plugin_load() / on_plugin_unload();
  • нативные экраны create_settings();
  • client_utils, android_utils, hook_utils, file_utils, ui.alert и ui.bulletin;
  • send_request() и RequestCallback;
  • requests, Pillow/PIL и pyfiglet внутри APK;
  • Java hooks через Pine и Xposed-compatible API;
  • post-response hook для пропуска, замены или отмены ответа.

Совместимость покрывает только реализованную поверхность exteraGram. Плагин с другими API нужно адаптировать. Устанавливайте только доверенные плагины: они выполняются внутри процесса Telegram и могут менять UI, сеть и данные аккаунта.

Обновления и релизы

В APK встраиваются канал, тег Forgejo и номер сборки. Обновлятор выбирает файл по Build.SUPPORTED_ABIS и не предлагает уже установленный тег.

Канал Package ID / имя Forgejo Release Логи Назначение
stable org.zastogram.messenger / ZaStoGram Обычный release с semver-тегом, например 1.1.1 Выключены по умолчанию Повседневная установка
dev org.zastogram.messenger.dev / ZaStoGram Dev Prerelease zastogram-apk-<run>-<attempt> MTProxy network logs включены Диагностика и тестирование

Android versionName следует версии upstream Telegram, а версия ZaStoGram задаётся встроенным release tag. versionCode включает upstream code, номер сборки Forgejo Actions и ABI-цифру, поэтому новые сборки устанавливаются поверх старых в правильном порядке.

Push в master запускает фоновую проверочную сборку трёх релизных ABI в Forgejo Actions. Публикация stable/dev-релиза остаётся локальным процессом: он собирает и проверяет все три APK, подписанные восстановленным production-ключом, и загружает именно эти файлы в Forgejo Releases.

Forgejo Actions требует отдельные Telegram API credentials из repository secrets TELEGRAM_API_ID и TELEGRAM_API_HASH. Публичная тестовая пара Telegram запрещена релизным guard: без обоих secrets проверочная сборка завершится ошибкой. Если собрать проект локально без своих параметров подписи, будет использован публичный dummy key из репозитория; такой APK не заменит сборку, подписанную production-ключом.

Сборка из исходников

Нужны JDK 17, Android SDK 35, build-tools 35.0.0, NDK 27.2.12479018 и CMake 3.10.2.4988404. Для быстрого повторного native-build рекомендуется ccache.

git clone --recursive https://git2.zapret.moe/zastogram/ZaStoGram.git
cd ZaStoGram
git submodule update --init --recursive --depth=1

Получите собственные api_id и api_hash в Telegram API development tools и сохраните их вне репозитория:

# ~/.config/zastogram-signing/telegram-api.properties (права 0600)
TELEGRAM_API_ID=12345678
TELEGRAM_API_HASH=0123456789abcdef0123456789abcdef

Вместо файла можно передать TELEGRAM_API_ID и TELEGRAM_API_HASH через окружение. Локальный релиз и Forgejo Actions отказываются собирать APK с публичной тестовой парой Telegram.

Пример локальной arm64-сборки:

export ANDROID_HOME=/opt/android-sdk
export ANDROID_SDK_ROOT=/opt/android-sdk
export USE_CCACHE=1
export CCACHE_DIR="$HOME/.cache/zastogram-ccache"

./gradlew --build-cache \
  --no-configuration-cache \
  --parallel \
  -PzastoAbiFilter=arm64-v8a \
  :TMessagesProj_AppStandalone:assembleArm64Standalone

Gradle task-output cache уже включён для всего проекта. ccache повторно использует неизменившиеся C/C++-объекты даже после потери каталога .cxx. Configuration cache намеренно выключен: задачи Chaquopy 16.1 с ним пока несовместимы. Каждая ABI собирается отдельным запуском Gradle: при совместной конфигурации Chaquopy упаковывает runtime всех выбранных архитектур в каждый APK. Повторные запуски используют тот же Gradle daemon, task-output cache и ccache, поэтому кэш ускоряет сборку, но не попадает в готовое приложение. zastoAbiFilters и одновременный запуск нескольких standalone ABI-задач намеренно запрещены.

По умолчанию собирается stable. Для параллельно устанавливаемой dev-сборки передайте ZASTO_UPDATE_CHANNEL=dev; package id, Android label и встроенный update-channel переключатся вместе:

ZASTO_UPDATE_CHANNEL=dev ./gradlew --build-cache \
  -PzastoAbiFilter=arm64-v8a \
  :TMessagesProj_AppStandalone:assembleArm64Standalone

APK появится в:

TMessagesProj_AppStandalone/build/outputs/apk/arm64/standalone/app.apk

Перед собственной публикацией настройте отдельные Telegram api_id/api_hash и release keystore. Не публикуйте APK с чужой API-парой или публичным dummy key как официальный релиз своего форка.

Проверки

Основной MTProxy suite:

python3 Tools/check_mtproxy_all.py

Ключевые соседние guards:

python3 Tools/check_wss_transport_mode.py
python3 Tools/check_wss_official_default.py
python3 Tools/check_build_apk_workflow.py
python3 Tools/check_forgejo_update_contract.py
python3 Tools/check_plugin_client_utils_contract.py
python3 Tools/check_plugin_python_deps.py
python3 Tools/check_runtime_resilience.py

Guards проверяют не только наличие строк, но и границы модулей, wire-контракты, JNI-сигнатуры, partial writes, retry ownership, WSS TLS/WebSocket invariants и release identity. Они не заменяют установку APK и проверку на реальной сети.

Диагностика MTProxy

Dev APK включает подробные сетевые маркеры. На Windows/WSL лог можно собрать готовым скриптом:

D:\bin\platform-tools\adb.exe devices -l
powershell.exe -NoProfile -ExecutionPolicy Bypass \
  -File "$(wslpath -w Tools/collect_mtproxy_logs.ps1)" \
  -Adb "D:\bin\platform-tools\adb.exe" \
  -Package org.zastogram.messenger \
  -Seconds 180

Основные результаты:

  • mtproxy_markers.txt — события native/Java по времени;
  • mtproxy_analysis.txt — попытки и terminal phase;
  • mtproxy_runtime_contract.txt — проверка handshake/data-path инвариантов;
  • mtproxy_attempts.csv — отдельные FakeTLS-попытки;
  • mtproxy_endpoint_profile_stats.csv — агрегат endpoint + profile;
  • mtproxy_plain_account_stats.csv — обычные dd/legacy соединения;
  • mtproxy_proxy_check_stats.csv и mtproxy_scheduler_stats.csv — проверки и control plane.

Повторная проверка сохранённой сессии:

python3 Tools/verify_mtproxy_runtime_logs.py mtproxy-logs-live/<session>

mtproxy_runtime_contract.txt подтверждает порядок live-маркеров и наличие transport_state=. Сначала фиксируется endpoint_handshake_ok. endpoint_data_path_success должен появляться только после первого first_tls_app_recv для FakeTLS либо после first_mtproxy_packet_recv для обычного MTProxy.

Stable APK не включает принудительные сетевые логи.

Ограничения

  • FakeTLS делает старт MTProxy похожим на TLS, но не превращает MTProto в настоящий браузерный HTTP/2 или HTTP/1.1.
  • SNI берётся из ee-секрета и не ротируется независимо от него.
  • Record sizing, timing, fragmentation и startup cover — диагностические режимы, а не доказанная универсальная защита от любого DPI.
  • Официальный WSS работает только для route'ов Telegram DC1–DC5. Test, неизвестные и CDN DC используют обычный fallback transport.
  • Встроенный WSS не поддерживает custom gateway или SOCKS upstream.
  • Фоновая сеть не отменяет Doze, battery saver и остановку процесса Android.
  • Плагины имеют привилегии процесса приложения и требуют доверия к автору.
  • Это неофициальный форк и не гарантия постоянного обхода меняющихся правил фильтрации.

Основа и благодарности

  • DrKLO/Telegram — официальный Telegram Android;
  • tsrman/tg — рабочая база изменений FakeTLS, JA4 и интервалов;
  • telemt/tdlib-obf — идеи и референсы по профилям, DRS/IPT и диагностике.

Проект распространяется по условиям GPL-2.0.