| `ja4_raw` | `string` | Raw JA4 material used for the hashed parts. |
| `total` | `u64` | Complete ClientHello observations for this bucket. |
| `auth_success` | `u64` | TLS-authenticated observations for this bucket. |
| `bad_or_probe` | `u64` | Complete ClientHello observations later classified as bad/probe. |
| `first_seen_epoch_secs` | `u64` | First observation timestamp. |
| `last_seen_epoch_secs` | `u64` | Last observation timestamp. |
JA3 follows the Salesforce ClientHello field order. JA4 follows the FoxIO TLS-client `a_b_c` format; GREASE values are excluded and no high-cardinality Prometheus labels are emitted for fingerprints.
| `/v1/runtime/me-selftest` | No | ME pool unavailable => `enabled=false`, `reason=source_unavailable` | `enabled=true`, full payload |
| `/v1/runtime/connections/summary` | `runtime_edge_enabled=false` => `enabled=false`, `reason=feature_disabled` | Recompute lock contention with no cache entry => `enabled=true`, `reason=source_unavailable` | `enabled=true`, full payload |
| `/v1/runtime/events/recent` | `runtime_edge_enabled=false` => `enabled=false`, `reason=feature_disabled` | Not used in current implementation | `enabled=true`, full payload |
| `/v1/runtime/tls-fingerprints` | `runtime_edge_enabled=false` => `enabled=false`, `reason=feature_disabled` | Not used in current implementation | `enabled=true`, full payload |
Этот документ описывает, как использовать JA3/JA4 telemetry в Telemt для диагностики блокировок, которые происходят на основе TLS ClientHello, особенно JA4 TLS client fingerprint.
Цель документа практическая: помочь оператору понять, какой клиентский TLS-отпечаток реально доходит до Telemt, как он распределён по IP/CIDR/пользователям, и как отделить JA4-based фильтрацию от блокировки по IP, SNI, домену, server flight или активному сканированию.
## Коротко
JA3 и JA4 описывают форму TLS ClientHello. ClientHello отправляет клиент, поэтому JA3/JA4 в этом контексте являются fingerprint'ами клиентской TLS-реализации, а не Telemt как сервера.
Telemt собирает JA3/JA4 только из уже прочитанного полного ClientHello:
- без packet capture;
- без MITM;
- без расшифровки TLS;
- без дополнительных сетевых чтений;
- без Prometheus labels с высокой кардинальностью;
- с ограниченным in-memory TTL/cap collector.
Собранные данные доступны:
- через API: `GET /v1/runtime/tls-fingerprints`;
- через `/beobachten`, если `general.beobachten=true`.
Основная польза:
- увидеть, какие JA4 реально используют клиенты;
- понять, один ли fingerprint страдает у всех пользователей;
- отделить проблему клиента от проблемы IP/ASN/домена;
- увидеть, доходят ли проблемные соединения до Telemt вообще;
- сравнить successful TLS-auth и bad/probe поток для одного fingerprint;
- собрать evidence для последующего изменения клиента, маршрута или deployment-профиля.
## Что такое JA3
JA3 - старый и широко совместимый способ получить hash от TLS ClientHello.
Значения внутри полей записываются в порядке, в котором они пришли в ClientHello. GREASE values исключаются. Итоговая строка хэшируется MD5, поэтому в API есть два поля:
-`ja3` - MD5 hash;
-`ja3_raw` - исходная строка, из которой получен hash.
Практическое значение JA3 в 2026 году ограничено тем, что современные TLS-клиенты и браузерные стеки могут менять порядок extensions. Поэтому JA3 полезен как совместимый исторический сигнал, но для диагностики современных блокировок обычно важнее JA4.
## Что такое JA4
JA4 TLS client fingerprint - более структурированный fingerprint ClientHello.
JA4 в Telemt считается для TLS-over-TCP ClientHello и имеет форму:
| `d` / `i` | Есть SNI domain (`d`) или SNI отсутствует (`i`). |
| `15` | Количество cipher suites без GREASE, capped до `99`. |
| `16` | Количество extensions без GREASE, capped до `99`. |
| `h2`, `h1`, `00` | ALPN marker: первый и последний символ первого ALPN value или `00`. |
| `cipher_hash` | SHA256 от отсортированного списка ciphers, первые 12 hex chars. |
| `extension_hash` | SHA256 от отсортированных extensions плюс signature algorithms, первые 12 hex chars. |
Важное отличие JA4 от JA3: JA4 нормализует часть полей, поэтому он устойчивее к простому изменению порядка extensions. Это делает JA4 удобным для фильтров и одновременно полезным для диагностики таких фильтров.
## Где Telemt видит ClientHello
В TLS/FakeTLS режиме Telemt получает первые bytes соединения и определяет, похоже ли оно на TLS handshake. Если record является полным ClientHello и проходит bounds checks, Telemt один раз парсит его для JA3/JA4.
Дальше возможны три исхода:
1.**Успешный MTProxy/FakeTLS клиент**
- Telemt принимает TLS-auth;
- fingerprint записывается в global/IP/CIDR scopes;
- после успешной TLS-auth Telemt добавляет user scope.
2.**Bad client или probe**
- ClientHello полный, но auth не проходит;
- fingerprint записывается в global/IP/CIDR scopes;
- user scope не записывается;
-`bad_or_probe` увеличивается.
3.**Неполный или обрезанный ClientHello**
- fingerprint не считается;
- такие случаи остаются в существующих bad-class counters.
Если фильтр режет трафик до того, как TCP connection или ClientHello дошли до процесса Telemt, Telemt не увидит этот fingerprint. Это важнейшее диагностическое отличие: отсутствие fingerprint'а во время жалобы пользователя часто означает блокировку до приложения, а не проблему внутри Telemt.
## Включение сбора
Collector включается, когда включён хотя бы один потребитель:
```toml
[general]
beobachten=true
beobachten_minutes=10
```
или:
```toml
[server.api]
runtime_edge_enabled=true
runtime_edge_top_n=50
```
Практически:
- для файлового/metrics endpoint анализа достаточно `general.beobachten=true`;
- для API snapshot нужен `server.api.runtime_edge_enabled=true`;
-`general.beobachten_minutes` задаёт retention window для fingerprint buckets;
-`server.api.runtime_edge_top_n` задаёт default Top-N размер API snapshot.
| Нет новых rows для IP/CIDR пользователя | Блокировка до Telemt: routing, firewall, ISP/DPI drop, IP block, SYN/TCP reset, UDP/TCP path issue. |
| Есть `by_ip`/`by_cidr`, но нет `by_user` | ClientHello дошёл, но TLS-auth/MTProxy layer не дошёл до успешного пользователя. Возможны bad key, probe, wrong client, active scanner, обрыв после ClientHello. |
| Есть `by_user.auth_success` | Клиентский JA4 дошёл и был принят Telemt. Если пользователь всё равно видит проблему, искать нужно дальше: relay path, Telegram upstream, quota, route mode, session cancellation, ME/direct routing. |
| Резко растёт `bad_or_probe` для одного JA4 | Вероятны сканеры или неправильные клиенты с тем же fingerprint family. |
### 3. Сравнить working и blocked случаи
Снимите snapshot во время working case и blocked case:
- есть ли `auth_success` для того же `ja4` из других сетей;
- отличается ли `bad_or_probe` между сетями.
Ключевая матрица:
| Working JA4 | Blocked JA4 | Вывод |
| --- | --- | --- |
| Same | Same, но blocked network не доходит до Telemt | Вероятна фильтрация по JA4 + destination/IP/SNI/network до приложения. |
| Same | Same, доходит и `auth_success>0` | JA4 ClientHello не является точкой отказа; искать post-auth проблему. |
| Different | Blocked только один JA4 | Вероятен client-version/platform-specific fingerprint block. |
| Same | `bad_or_probe` растёт, `auth_success=0` | Возможно, доходит не тот клиент/secret или фильтр/прокси ломает поток после ClientHello. |
### 4. Разделить client JA4 и server fingerprint
JA4 ClientHello - это клиентская сторона. Настройки Telemt вроде TLS-front server flight, `mask_host`, ticket-tail или CCS replay не меняют ClientHello, который отправляет Telegram client.
Если фильтр принимает решение строго после ClientHello, то серверные улучшения могут не помочь. В этом случае полезные действия:
- проверить обновление Telegram client;
- сравнить платформы и версии клиента;
- проверить, меняется ли JA4 на другой версии;
- проверить, блокируется ли тот же JA4 к другому destination;
- проверить, блокируется ли другой JA4 к тому же Telemt IP/SNI;
- собрать evidence для client-side fingerprint fix.
Если ClientHello проходит, а блокировка возникает после server response, тогда уже важны:
- форма FakeTLS server flight;
- TLS front profile fidelity;
-`mask_host` поведение для non-auth clients;
- certificate/provenance fallback для сканеров;
- TCP relay behavior;
- upstream route к Telegram.
### 5. Коррелировать с packet capture
Telemt collector показывает только то, что процесс увидел. Для подтверждения фильтрации до Telemt нужен внешний capture.
На сервере:
```bash
sudo tcpdump -i any -w telemt-clienthello.pcap host CLIENT_IP and port 443
Если на клиентской стороне capture видит ClientHello, а серверный capture не видит, проблема в сети между клиентом и сервером. Если серверный capture видит ClientHello, но Telemt API не видит fingerprint, проверьте порт, listener, PROXY protocol, TLS record fragmentation и bounds/errors.
## Практические сценарии
### Сценарий A: один JA4 перестал работать у многих пользователей
Признаки:
- один `ja4` доминирует в жалобах;
-у разных source CIDR нет `auth_success`;
- working пользователи используют другой JA4;
- обновление клиента меняет поведение.
Вероятный вывод: фильтр на стороне сети научился распознавать конкретный ClientHello family.
Действия:
- сравнить Telegram client versions;
- проверить, не используют ли пользователи старые клиенты;
- проверить другой client version через ту же сеть.
### Сценарий B: один CIDR не работает, JA4 обычный
Признаки:
- тот же `ja4` успешно работает из других сетей;
- проблемный `/24` или `/56` не доходит до Telemt или не получает `auth_success`;
- нет общей корреляции по версии клиента.
Вероятный вывод: проблема не в JA4 alone, а в source network policy или destination reputation.
Действия:
- сменить route/VPS/IP;
- проверить port;
- проверить SNI/domain reputation;
- сравнить с другим Telemt endpoint;
- смотреть server-side packet capture.
### Сценарий C: много `bad_or_probe` на одном JA4
Признаки:
-`bad_or_probe` высокий;
-`by_user` пустой или слабый;
- source IP/CIDR разнообразные;
- попытки не соответствуют реальным пользователям.
Вероятный вывод: активное сканирование или нерелевантный TLS traffic с похожим ClientHello.
Действия:
- смотреть `/beobachten` по IP classes;
- проверить `unknown_tls_sni` и bad-client counters;
- убедиться, что fallback `mask_host` отвечает правдоподобно;
- не делать вывод о блокировке пользователей только по global `bad_or_probe`.
### Сценарий D: `auth_success` есть, но пользователь жалуется
Признаки:
- fingerprint присутствует в `by_user`;
-`auth_success` растёт;
- соединение проходит TLS-auth.
Вероятный вывод: JA4 ClientHello не является причиной отказа в этом случае.
Действия:
- проверить user enabled/disabled status;
- проверить quota;
- проверить direct/ME route;
- проверить upstream health;
- проверить runtime events;
- смотреть relay/session logs.
## Что нельзя вывести из JA3/JA4
JA3/JA4 не говорят:
- почему сеть приняла решение о блокировке;
- какой именно vendor DPI используется;
- был ли block только по JA4 или по связке JA4+IP+SNI;
- что произошло с соединением после TLS-auth;
- как выглядит server-side TLS fingerprint;
- как ведёт себя HTTP layer после TLS.
JA3/JA4 также не являются уникальной идентичностью человека. Это fingerprint клиентской TLS-реализации и её настроек. Один fingerprint может быть у большого числа пользователей.
## Ограничения collector'а Telemt
- Считается только TLS ClientHello, который полностью дошёл до Telemt.
- QUIC/DTLS/HTTP JA4 variants не собираются.
- Truncated ClientHello не fingerprint'ится.
- User scope появляется только после успешной TLS-auth.
-`by_ip` и `by_cidr` отражают source address после нормализации/PROXY protocol path, если он используется.
- Collector bounded: при большом количестве уникальных buckets возможен рост `dropped_total`.
- Retention зависит от `general.beobachten_minutes`.
- Данные runtime in-memory; это snapshot для диагностики, а не долговременное хранилище.
## Рекомендованный workflow расследования
1. Включить `runtime_edge_enabled=true` и разумный `runtime_edge_top_n`, например `100`.
2. Зафиксировать baseline в период нормальной работы.
3. Во время жалобы снять API snapshot и `/beobachten`.
- **Описание**: Включает "криминалистическое" наблюдения для каждого IP-адреса. Анализирует поведение всех подключений и записывает возможные типы клиентов, которые посылают active-probing запросы.
- **Описание**: Включает "криминалистическое" наблюдения для каждого IP-адреса. Анализирует поведение всех подключений, записывает возможные типы клиентов, которые посылают active-probing запросы, и добавляет snapshot’ы TLS JA3/JA4 fingerprint’ов в Beobachten output, когда есть данные.
- **Пример**:
```toml
@@ -641,7 +641,7 @@
```
## beobachten_minutes
- **Ограничения / валидация**: Должно быть `> 0` (минут).
- **Описание**: Время хранения (минуты) для сегментов наблюдения по каждому IP-адресу.
- **Описание**: Время хранения (минуты) для сегментов наблюдения по каждому IP-адресу и in-memory bucket’ов TLS fingerprint’ов.
- **Пример**:
```toml
@@ -2179,7 +2179,7 @@
```
## runtime_edge_top_n
- **Ограничения / валидация**: `1..=1000`.
- **Описание**: Размер выборки Top-N для рейтинга (leaderboard) edge-соединений.
- **Описание**: Размер выборки Top-N для snapshot’ов рейтинга edge-соединений и TLS fingerprint’ов.
> Проблема с TLS отпечатком исправлена в последних версиях клиентов Telegram для Desktop / Android / iOS.
> Обновите свой клиент для корректной работы с MTProxy Fake-TLS!
- Для расследования блокировок на базе JA4 ClientHello используйте отдельную инструкцию: [`JA3 и JA4 анализ в Telemt`](Architecture/Fronting-splitting/TLS_JA3_JA4_ANALYSIS.ru.md).
- Мы считаем это прорывом, которому на сегодняшний день нет стабильных аналогов;
- Исходя из этого: если `telemt` настроен правильно, **режим TLS полностью идентичен реальному «рукопожатию» + обмену данными** с указанным хостом;
- Вот наши доказательства:
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.