todo/mtproxy/tdlib-obf-client-side-stealth.md
loop-uh 0ad0bcc8dd
Some checks failed
Published content check / validate (push) Failing after 5s
seo+зеркало: [!mirror]-плашка со ссылкой на вики и description во frontmatter всех заметок
Каждая публикуемая заметка получила callout-шапку со ссылкой на свою страницу
wiki.zapret.moe (на самой вики она вырезается транформером RemoveMirrorCallout,
видна только на зеркале Obsidian Publish и в Forgejo) и SEO-поле description —
1–2 предложения для meta description обоих сайтов.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-26 22:05:57 +03:00

135 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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) — протухший фингерпринт официального клиента