Some checks failed
Published content check / validate (push) Failing after 5s
Каждая публикуемая заметка получила callout-шапку со ссылкой на свою страницу wiki.zapret.moe (на самой вики она вырезается транформером RemoveMirrorCallout, видна только на зеркале Obsidian Publish и в Forgejo) и SEO-поле description — 1–2 предложения для meta description обоих сайтов. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
135 lines
19 KiB
Markdown
135 lines
19 KiB
Markdown
---
|
||
date: 2026-06-12
|
||
tags:
|
||
- mtproto
|
||
- mtproxy
|
||
- dpi
|
||
- tspu
|
||
- ja4
|
||
- faketls
|
||
- tdlib
|
||
- telegram
|
||
aliases:
|
||
- tdlib-obf
|
||
- Клиентский TDLib с маскировкой JA4
|
||
- Stealth TDLib
|
||
- Обфусцированный TDLib
|
||
link: https://github.com/telemt/tdlib-obf
|
||
description: "tdlib-obf — форк TDLib с маскировкой MTProto под браузерный HTTPS: свежие JA4-профили Chrome/Firefox, ECH по маршруту и traffic shaping."
|
||
---
|
||
|
||
> [!mirror] Резервное зеркало
|
||
> Актуальная версия этой страницы — на основной вики: [wiki.zapret.moe/mtproxy/tdlib-obf-client-side-stealth](https://wiki.zapret.moe/mtproxy/tdlib-obf-client-side-stealth)
|
||
|
||
# 🦎 tdlib-obf — клиентский TDLib с маскировкой TLS-почерка под браузер
|
||
|
||
> [!info] О чём заметка
|
||
> `tdlib-obf` — форк **TDLib** (официальной библиотеки для написания Telegram-клиентов) от сообщества **telemt**, который маскирует MTProto-трафик под обычный браузерный HTTPS, чтобы обходить государственный DPI (Deep Packet Inspection — глубокая инспекция пакетов; в РФ — оборудование ТСПУ, Технические Средства Противодействия Угрозам). Главное: это **клиентская** реализация — она меняет TLS-почерк (JA4) именно там, где это вообще возможно, внутри самого клиента. Тем самым `tdlib-obf` — это «полноценный» ответ на тезис из [[mtproxy/ja4-sni-client-side|разбора, почему обход MTProxy клиентский]]: чистый слом JA4 серверный прокси сделать не может, а форк клиента — может.
|
||
|
||
> [!warning] Статус данных
|
||
> Технические детали ниже взяты в основном из **собственного аудит-документа проекта** (`docs/Documentation/STEALTH_IMPLEMENTATION_RU.md`, состояние на апрель–май 2026) — это самоотчёт авторов, **не независимая проверка**. Читай заявленные свойства маскировки как «по документации проекта», а не как подтверждённый внешним аудитом факт. Базовый коммит форка и ветка проверены напрямую по git (июнь 2026) и помечены отдельно.
|
||
|
||
---
|
||
|
||
## TL;DR
|
||
|
||
1. `tdlib-obf` — это **TDLib с обфускацией**: тот же API, но при сборке с флагом `TDLIB_STEALTH_SHAPING=ON` клиент строит TLS-рукопожатие, неотличимое (по замыслу) от реального браузера.
|
||
2. Маскировка решает ровно тот рычаг, который [[mtproxy/ja4-sni-client-side|можно дёргать только на клиенте]] — **JA4-почерк ClientHello**: вместо одного протухшего пресета Telegram используется реестр из 8 рантайм-профилей реальных браузеров (по аудит-доку — Chrome 120/131/133, Firefox 148/149, Safari, iOS, Android; в коде заведены и новые lanes), выбираемых на лету.
|
||
3. Заодно адресуется беда [[Zapret/mtproto/10-telemt-logs-dpi|#30733 (протухший отпечаток)]]: используемые Chrome-профили несут **post-quantum** `key_share` (ML-KEM), которого не было в старом почерке Telegram.
|
||
4. Работает **только через MTProto-прокси с FakeTLS** (`ProxySecret::emulate_tls()`). Прямые соединения не маскируются (а часть leak-путей прямого TCP-SYN в обход прокси форк, по документации, дополнительно закрыл).
|
||
5. Честное ограничение от самих авторов: после TLS идёт **сырой MTProto, а не настоящий HTTP** — полной неотличимости на уровне L7 проект не обещает.
|
||
6. Это **библиотека, а не готовый клиент**: своё приложение пишешь поверх неё (проще всего — консольный клиент на `libtdjson`).
|
||
|
||
---
|
||
|
||
## Термины (чтобы заметка читалась без контекста)
|
||
|
||
- **TDLib** (Telegram Database Library) — официальная библиотека от Telegram для написания клиентов. Сама по себе не приложение, а движок: берёт на себя протокол, шифрование, базу сообщений. Готовые клиенты (Unigram, Telegram X) построены поверх неё.
|
||
- **libtdjson** — собранная динамическая библиотека TDLib с JSON-интерфейсом, к которой подключаются из любого языка (Python, C++, и т.д.).
|
||
- **MTProto** — собственный транспортный протокол Telegram (шифрование + формат пакетов), поверх которого работает мессенджер.
|
||
- **DPI / ТСПУ** — DPI (Deep Packet Inspection) — глубокая инспекция пакетов; ТСПУ (Технические Средства Противодействия Угрозам) — это DPI-оборудование, установленное у российских операторов.
|
||
- **L7** — седьмой (прикладной) уровень модели OSI: грамматика самого протокола поверх TLS (HTTP/2, HTTP/1.1). «L7-неотличимость» — когда трафик неотличим от браузерного и на этом уровне, а не только в TLS-рукопожатии.
|
||
- **ClientHello / JA4 / SNI / FakeTLS** — раскрыты в [[mtproxy/ja4-sni-client-side|заметке про клиентскую сторону JA4/SNI]]. Кратко: ClientHello — первый незашифрованный пакет TLS, который шлёт клиент; JA4 — его отпечаток; FakeTLS — режим MTProxy, где трафик маскируется под HTTPS.
|
||
- **ECH** (Encrypted ClientHello) — расширение TLS, прячущее SNI внутри зашифрованной части рукопожатия.
|
||
- **DRS / IPT** — внутренние подсистемы формирования трафика (traffic shaping): Dynamic Record Sizing (динамический размер TLS-записей) и Inter-Packet Timing (имитация тайминга пакетов).
|
||
|
||
---
|
||
|
||
## Зачем это нужно: рычаг, который есть только у клиента
|
||
|
||
> [!example] На пальцах
|
||
> Представь, что у входа стоит охранник (ТСПУ) и узнаёт «гостей Telegram» по **визитке** (JA4-почерк ClientHello). У официального клиента визитка одна и та же, к тому же устаревшего образца — охранник выучил её наизусть. Сервер-прокси переклеить визитку не может: гость показывает её **до** того, как дойдёт до сервера. А `tdlib-obf` — это сам гость, который печатает себе **свежую визитку под видом обычного браузера** перед каждым выходом.
|
||
|
||
Архитектурный факт, разобранный в [[mtproxy/ja4-sni-client-side|отдельной заметке]]: JA4 и SNI лежат в ClientHello, а его шлёт **клиент**, и цензор видит этот пакет ещё до сервера. Поэтому чистый слом почерка возможен только до цензора — на стороне клиента. До сих пор это воплощалось как отдельный локальный relay (тестовый [gist Flowseal](https://gist.github.com/Flowseal/de630dd9d9ddaa86cc6bed9b473fae0c), который строит свой ClientHello). `tdlib-obf` идёт дальше: переносит ту же логику **внутрь самого клиента-движка**, без прослойки-relay.
|
||
|
||
---
|
||
|
||
## Как работает маскировка (4 слоя)
|
||
|
||
По документации проекта, stealth-контур включает четыре одновременно работающих слоя:
|
||
|
||
| Слой | Что делает |
|
||
|---|---|
|
||
| **Profile-driven ClientHello** | Реестр профилей реальных браузеров (по аудит-доку — Chrome 120/131/133, Firefox 148/149 вкл. macOS, Safari 26.3, iOS, Android; в коде есть и новые lanes — Chrome 147, Firefox 149 Windows/Android). Выбор «липкий» (sticky) — зависит от назначения, временного окна и платформы, чтобы не дёргать TLS-семейство на каждом соединении. Профили `verified` построены на реальных перехватах трафика, `advisory` — консервативные. |
|
||
| **Route-aware ECH** | Политика ECH зависит от маршрута: на RU/неизвестных маршрутах ECH **выключен**, на не-RU — включается с «предохранителем» (circuit breaker), который отрубает ECH для направления после нескольких ошибок. |
|
||
| **Transport shaping** | Имитация тайминга пакетов (IPT, не просто `sleep(random)`, а burst/idle-модель), динамический размер TLS-записей (DRS: slow-start → congestion-open → steady-state), классификация типа трафика (handshake / keepalive / bulk / interactive). |
|
||
| **Capture-driven верификация** | Сотни нативных тестов + «корпус» реальных перехватов, сверка отпечатков JA3/JA4 с эталонами, статистические прогоны на 1024 сидах — чтобы маскировка не «схлопывалась» в узнаваемый паттерн. |
|
||
|
||
> [!important] Это адресует «протухший почерк» #30733
|
||
> Беда официального клиента из [[Zapret/mtproto/10-telemt-logs-dpi|#30733]] не в номере версии (он как раз представляется свежим Chrome 134/macOS), а в том, что его отпечаток идёт **без** post-quantum `key_share`, тогда как реальные Chrome 131+ его уже несут. К концу 2025 уже около половины «человеческих» TLS несут `X25519MLKEM768` (по данным Cloudflare — ~43% к сентябрю и более 50% к декабрю 2025). По документации `tdlib-obf` синхронизирует PQ-группу между `supported_groups` и `key_share` в Chrome-профилях — то есть отпечаток выходит пост-квантовым, чего старому почерку Telegram не хватало.
|
||
|
||
> [!note] Что закрывает, а что нет
|
||
> `tdlib-obf` бьёт по рычагу **JA4/почерк** (и его свежесть). Условие «один и тот же SNI в залпе» из [[mtproxy/ja4-sni-client-side|детекта июня 2026]] — отдельная история: SNI в FakeTLS задаётся `ee`-секретом прокси (`tls_domain`), а не выводится из него, так что его ротация — вопрос того, к каким секретам/доменам подключается клиент, а не самого слоя маскировки. Третье условие — «залп на один ip:port» — частично снимается серверными мерами (pacing, разные порты), см. [[Zapret/mtproto/10-telemt-logs-dpi|разбор логов]].
|
||
|
||
---
|
||
|
||
## Как использовать
|
||
|
||
> [!tip] Главное правило сборки
|
||
> Маскировка включается **только** при сборке с `-DTDLIB_STEALTH_SHAPING=ON` и **только** в режиме FakeTLS-прокси (`ProxySecret::emulate_tls()`). Жёсткий контракт: если использовать `emulate_tls()`, но собрать с `TDLIB_STEALTH_SHAPING=OFF`, процесс **аварийно падает** (`LOG(FATAL)`), а не работает молча без маскировки — «забыть включить» нельзя.
|
||
|
||
`tdlib-obf` — это библиотека, поэтому «свой клиент» = твоё приложение поверх её API. Практичный путь без написания C++:
|
||
|
||
- [ ] Получить `api_id`/`api_hash` на [my.telegram.org](https://my.telegram.org).
|
||
- [ ] Собрать `libtdjson` из исходников с флагом `TDLIB_STEALTH_SHAPING=ON` (нужен компилятор **C++23**, OpenSSL, zlib ≥ 1.3.2, gperf, CMake — это единственная C++-часть).
|
||
- [ ] Взять готовый терминальный клиент на TDLib (например `tg` от paul-nameless) и указать ему путь к своей `libtdjson` через `library_path` — получаешь рабочий клиент в терминале без своего кода.
|
||
- [ ] Подключаться через **MTProto-прокси с FakeTLS-секретом** (`ee…`) — без него маскировки нет. Свой прокси можно поднять на [[mtproxy/mtproto-zig|mtproto.zig]] / telemt / mtg вне зоны блокировки.
|
||
|
||
> [!warning] Готовый десктоп-GUI «в лоб» не подойдёт
|
||
> Telegram Desktop и его форки (Kotatogram, Materialgram) **не используют TDLib** — у них свой MTProto-движок, подменить его на `tdlib-obf` нельзя. Из десктоп-GUI на TDLib есть **Unigram** (Windows), но его `develop` закреплён на более свежем коммите TDLib, чем база форка, и схема API (`td_api.tl`) за это время разошлась (на июнь 2026 — порядка 260 строк diff; точное число зависит от того, на какой коммит TDLib закреплён Unigram) — пересобрать Unigram с обфускацией можно только пересадив изменения форка на нужный коммит и разрулив конфликты. Поэтому самый дешёвый путь к рабочему клиенту — консольный/TUI на `libtdjson`.
|
||
|
||
---
|
||
|
||
## Честные ограничения
|
||
|
||
Авторы прямо перечисляют их в документации — это плюс к прозрачности (но прозрачность не заменяет независимую проверку):
|
||
|
||
> [!quote] Из документации проекта (раздел «Честные ограничения»)
|
||
> После TLS-рукопожатия идёт **сырой MTProto, а не браузероподобный HTTP**. Полная L7-неотличимость **не заявляется** — на уровне глубокой L7-аналитики (настоящий HTTP/2-фрейминг, грамматика HTTP/1.1) трафик всё ещё может выделяться. Runtime-реестр профилей консервативнее эмпирического корпуса, а генерация ServerHello зависит от серверной стороны.
|
||
|
||
Дополнительно:
|
||
|
||
- **QUIC/HTTP3 запрещены** — транспорт всегда TCP+TLS (`allow_quic=true` считается ошибкой конфигурации).
|
||
- Это **community-форк**, не официальный Telegram (лицензия MIT поверх Boost-лицензии TDLib).
|
||
|
||
---
|
||
|
||
## Версия и происхождение (проверено по git, июнь 2026)
|
||
|
||
- Дефолтная ветка репозитория — **`master`** (не `main`).
|
||
- Форк отделился от upstream TDLib на коммите `8fc2344f` (**25 апреля 2026**). Сам форк схему `td_api.tl` тоже правит (+91/−13 строк относительно базы) — это важно учитывать при попытке подружить его с готовым клиентом, заточенным под другую версию TDLib.
|
||
- Мейнтейнеры — сообщество telemt (то же, что и [[Zapret/mtproto/00-overview|MTProto-прокси telemt]]).
|
||
|
||
---
|
||
|
||
## 📚 См. также
|
||
|
||
- [[mtproxy/ja4-sni-client-side|Почему обход MTProxy клиентский (JA4/SNI)]] — архитектурный тезис, ответом на который и является tdlib-obf
|
||
- [[mtproxy/tsrman-tg-android-faketls|tsrman/tg — Telegram для Android со сменой JA4]] — родственный клиентский подход, но в виде готового приложения (форк Telegram-Android), а не библиотеки
|
||
- [[Zapret/mtproto/10-telemt-logs-dpi|Чтение логов telemt и #30733]] — протухший JA4-почерк официального клиента, который tdlib-obf лечит PQ-профилями
|
||
- [[mtproxy/mtproto-zig|MTProxy и mtproto.zig]] — серверная сторона FakeTLS-прокси, к которой подключается клиент
|
||
- [[mtproxy/faketls-relay-diagnosis|Релей или клиент: диагностика FakeTLS]] — как проверить снаружи, чей ClientHello релей не принимает, и какие требования он к нему предъявляет
|
||
- [[Zapret/mtproto/00-overview|MTProto Proxy — полный гайд]] — общий обзор экосистемы telemt
|
||
- [[VLESS/dpi-tls-june-2026|Сибирская схема: подсеть + фингерпринт + частота]] — та же логика «И трёх условий» и про свежесть почерка/ML-KEM
|
||
- 🔗 [tdlib-obf на GitHub](https://github.com/telemt/tdlib-obf) — исходники и документация (ветка `master`)
|
||
- 🔗 [tdesktop#30733](https://github.com/telegramdesktop/tdesktop/issues/30733) — протухший фингерпринт официального клиента
|