mirror of
https://github.com/telemt/telemt.git
synced 2026-06-09 20:41:44 +03:00
JA3 + JA4 Docs
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
@@ -103,6 +103,7 @@ Notes:
|
||||
| `GET` | `/v1/runtime/me-selftest` | none | `200` | `RuntimeMeSelftestData` |
|
||||
| `GET` | `/v1/runtime/connections/summary` | none | `200` | `RuntimeEdgeConnectionsSummaryData` |
|
||||
| `GET` | `/v1/runtime/events/recent` | none | `200` | `RuntimeEdgeEventsData` |
|
||||
| `GET` | `/v1/runtime/tls-fingerprints` | optional `limit=1..1000` | `200` | `RuntimeEdgeTlsFingerprintsData` |
|
||||
| `GET` | `/v1/stats/users/active-ips` | none | `200` | `UserActiveIps[]` |
|
||||
| `GET` | `/v1/stats/users` | none | `200` | `UserInfo[]` |
|
||||
| `GET` | `/v1/users` | none | `200` | `UserInfo[]` |
|
||||
@@ -815,6 +816,43 @@ An empty request body is accepted and generates a new secret automatically.
|
||||
| `event_type` | `string` | Event kind identifier. |
|
||||
| `context` | `string` | Context text (truncated to implementation-defined max length). |
|
||||
|
||||
### `RuntimeEdgeTlsFingerprintsData`
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `enabled` | `bool` | Endpoint availability under `runtime_edge_enabled`. |
|
||||
| `reason` | `string?` | `feature_disabled` when endpoint is disabled. |
|
||||
| `generated_at_epoch_secs` | `u64` | Snapshot generation timestamp. |
|
||||
| `data` | `RuntimeEdgeTlsFingerprintsPayload?` | Null when unavailable. |
|
||||
|
||||
#### `RuntimeEdgeTlsFingerprintsPayload`
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `limit` | `usize` | Effective Top-N row count. |
|
||||
| `retention_secs` | `u64` | In-memory retention window, derived from `general.beobachten_minutes`. |
|
||||
| `capacity` | `usize` | Maximum retained fingerprint buckets. |
|
||||
| `dropped_total` | `u64` | Buckets dropped because the collector was full. |
|
||||
| `parse_error_total` | `u64` | Complete ClientHello records that could not be fingerprinted. |
|
||||
| `by_fingerprint` | `RuntimeEdgeTlsFingerprintRow[]` | Global JA3/JA4 leaderboard. |
|
||||
| `by_ip` | `RuntimeEdgeTlsFingerprintRow[]` | Source-IP scoped leaderboard. |
|
||||
| `by_cidr` | `RuntimeEdgeTlsFingerprintRow[]` | Source CIDR scoped leaderboard (`/24` for IPv4, `/56` for IPv6). |
|
||||
| `by_user` | `RuntimeEdgeTlsFingerprintRow[]` | Authenticated user scoped leaderboard. |
|
||||
|
||||
#### `RuntimeEdgeTlsFingerprintRow`
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `scope` | `string?` | IP, CIDR, or username; absent in `by_fingerprint`. |
|
||||
| `ja3` | `string` | JA3 MD5 hash. |
|
||||
| `ja3_raw` | `string` | Raw JA3 field string. |
|
||||
| `ja4` | `string` | JA4 TLS client fingerprint. |
|
||||
| `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.
|
||||
|
||||
### `ZeroAllData`
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
@@ -1293,6 +1331,7 @@ Additional runtime endpoint behavior:
|
||||
| `/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 |
|
||||
|
||||
## ME Fallback Behavior Exposed Via API
|
||||
|
||||
|
||||
507
docs/Architecture/Fronting-splitting/TLS_JA3_JA4_ANALYSIS.ru.md
Normal file
507
docs/Architecture/Fronting-splitting/TLS_JA3_JA4_ANALYSIS.ru.md
Normal file
@@ -0,0 +1,507 @@
|
||||
# JA3 и JA4 анализ в Telemt
|
||||
|
||||
Этот документ описывает, как использовать 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.
|
||||
|
||||
JA3 строится из ClientHello fields:
|
||||
|
||||
```text
|
||||
SSLVersion,Cipher,SSLExtension,EllipticCurve,EllipticCurvePointFormat
|
||||
```
|
||||
|
||||
Значения внутри полей записываются в порядке, в котором они пришли в 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 и имеет форму:
|
||||
|
||||
```text
|
||||
t<version><sni_marker><cipher_count><extension_count><alpn_marker>_<cipher_hash>_<extension_hash>
|
||||
```
|
||||
|
||||
Пример:
|
||||
|
||||
```text
|
||||
t13d1516h2_8daaf6152771_e5627efa2ab1
|
||||
```
|
||||
|
||||
Части JA4:
|
||||
|
||||
| Часть | Смысл |
|
||||
| --- | --- |
|
||||
| `t` | TLS over TCP. Telemt сейчас не считает JA4 для QUIC/DTLS. |
|
||||
| `13`, `12`, `11`, `10` | TLS version, предпочтительно из `supported_versions`. |
|
||||
| `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.
|
||||
|
||||
## API snapshot
|
||||
|
||||
Endpoint:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:9091/v1/runtime/tls-fingerprints
|
||||
```
|
||||
|
||||
С явным лимитом:
|
||||
|
||||
```bash
|
||||
curl -s 'http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=100'
|
||||
```
|
||||
|
||||
Если API защищён header'ом:
|
||||
|
||||
```bash
|
||||
curl -s \
|
||||
-H 'Authorization: Bearer YOUR_TOKEN' \
|
||||
'http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=100'
|
||||
```
|
||||
|
||||
Если `runtime_edge_enabled=false`, endpoint возвращает payload с:
|
||||
|
||||
```json
|
||||
{
|
||||
"enabled": false,
|
||||
"reason": "feature_disabled"
|
||||
}
|
||||
```
|
||||
|
||||
### Структура payload
|
||||
|
||||
Основные поля:
|
||||
|
||||
| Поле | Смысл |
|
||||
| --- | --- |
|
||||
| `retention_secs` | Текущее TTL окно collector'а. |
|
||||
| `capacity` | Максимум retained buckets. |
|
||||
| `dropped_total` | Сколько новых buckets отброшено из-за cap. |
|
||||
| `parse_error_total` | Сколько полных ClientHello не удалось распарсить. |
|
||||
| `by_fingerprint` | Top fingerprints глобально. |
|
||||
| `by_ip` | Top fingerprints по exact source IP. |
|
||||
| `by_cidr` | Top fingerprints по source prefix: IPv4 `/24`, IPv6 `/56`. |
|
||||
| `by_user` | Top fingerprints по authenticated user. |
|
||||
|
||||
Строка snapshot:
|
||||
|
||||
| Поле | Смысл |
|
||||
| --- | --- |
|
||||
| `scope` | IP, CIDR или username. В `by_fingerprint` отсутствует. |
|
||||
| `ja3` | JA3 hash. |
|
||||
| `ja3_raw` | Raw JA3 string. |
|
||||
| `ja4` | JA4 TLS client fingerprint. |
|
||||
| `ja4_raw` | Raw JA4 material. |
|
||||
| `total` | Сколько полных ClientHello попало в этот bucket. |
|
||||
| `auth_success` | Сколько из них успешно прошли TLS-auth. |
|
||||
| `bad_or_probe` | Сколько были bad/probe после полного ClientHello. |
|
||||
| `first_seen_epoch_secs` | Первый timestamp bucket'а. |
|
||||
| `last_seen_epoch_secs` | Последний timestamp bucket'а. |
|
||||
|
||||
### Быстрый просмотр через jq
|
||||
|
||||
Top JA4 глобально:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:9091/v1/runtime/tls-fingerprints \
|
||||
| jq -r '.data.data.by_fingerprint[] | [.ja4, .total, .auth_success, .bad_or_probe] | @tsv'
|
||||
```
|
||||
|
||||
Top JA4 по пользователям:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=100 \
|
||||
| jq -r '.data.data.by_user[] | [.scope, .ja4, .total, .auth_success] | @tsv'
|
||||
```
|
||||
|
||||
Top JA4 по CIDR:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=100 \
|
||||
| jq -r '.data.data.by_cidr[] | [.scope, .ja4, .total, .auth_success, .bad_or_probe] | @tsv'
|
||||
```
|
||||
|
||||
Ошибки парсинга и drops:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:9091/v1/runtime/tls-fingerprints \
|
||||
| jq '.data.data | {retention_secs, capacity, dropped_total, parse_error_total}'
|
||||
```
|
||||
|
||||
## Beobachten output
|
||||
|
||||
Если включён endpoint metrics, `/beobachten` содержит обычные forensic buckets и, когда есть данные, append-only секцию TLS fingerprints:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:9090/beobachten
|
||||
```
|
||||
|
||||
Фрагмент:
|
||||
|
||||
```text
|
||||
[tls_fingerprints]
|
||||
retention_secs=600 capacity=65536 dropped_total=0 parse_error_total=0
|
||||
[tls_fingerprints.by_fingerprint]
|
||||
ja4=t13d1516h2_8daaf6152771_e5627efa2ab1 ja3=... total=42 auth_success=41 bad_or_probe=1 first_seen=... last_seen=...
|
||||
[tls_fingerprints.by_cidr]
|
||||
scope=203.0.113.0/24 ja4=t13d1516h2_8daaf6152771_e5627efa2ab1 ja3=... total=10 auth_success=10 bad_or_probe=0 first_seen=... last_seen=...
|
||||
```
|
||||
|
||||
`/beobachten` удобен для быстрой операторской диагностики без API client. API удобнее для автоматической корреляции.
|
||||
|
||||
## Как анализировать JA4-based блокировку
|
||||
|
||||
### 1. Зафиксировать симптом
|
||||
|
||||
Перед анализом нужно записать:
|
||||
|
||||
- какие пользователи жалуются;
|
||||
- какая версия Telegram client используется;
|
||||
- какая платформа: Desktop, Android, iOS;
|
||||
- какой источник сети: mobile ISP, home ISP, corporate network, country/region;
|
||||
- работает ли тот же пользователь через другой network path;
|
||||
- работает ли другой пользователь с того же IP/CIDR;
|
||||
- видит ли Telemt новые ClientHello от проблемного пользователя в момент попытки.
|
||||
|
||||
JA4 без контекста почти всегда недостаточен. Фильтры часто используют сочетание:
|
||||
|
||||
- JA4;
|
||||
- destination IP;
|
||||
- SNI;
|
||||
- порт;
|
||||
- ASN/source network;
|
||||
- rate или connection pattern;
|
||||
- reputation домена/IP;
|
||||
- active probing result.
|
||||
|
||||
### 2. Проверить, доходит ли ClientHello до Telemt
|
||||
|
||||
Во время попытки подключения проблемного пользователя смотрите:
|
||||
|
||||
```bash
|
||||
curl -s 'http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=200' \
|
||||
| jq '.data.data.by_user, .data.data.by_ip, .data.data.by_cidr'
|
||||
```
|
||||
|
||||
Интерпретация:
|
||||
|
||||
| Наблюдение | Вероятный вывод |
|
||||
| --- | --- |
|
||||
| Нет новых 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:
|
||||
|
||||
```bash
|
||||
curl -s 'http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=500' > tls-fp-working.json
|
||||
curl -s 'http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=500' > tls-fp-blocked.json
|
||||
```
|
||||
|
||||
Сравните:
|
||||
|
||||
- появился ли тот же `ja4` в blocked сети;
|
||||
- меняется ли `ja4` между версиями клиента;
|
||||
- меняется ли только IP/CIDR при том же `ja4`;
|
||||
- есть ли `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
|
||||
```
|
||||
|
||||
Быстрый tshark вывод ClientHello fields:
|
||||
|
||||
```bash
|
||||
tshark -r telemt-clienthello.pcap -Y "tls.handshake.type == 1" -T fields \
|
||||
-e frame.time_epoch \
|
||||
-e ip.src \
|
||||
-e ip.dst \
|
||||
-e tcp.srcport \
|
||||
-e tcp.dstport \
|
||||
-e tls.handshake.extensions_server_name \
|
||||
-e tls.handshake.extensions_alpn_str
|
||||
```
|
||||
|
||||
Если на клиентской стороне 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;
|
||||
- проверить, не используют ли пользователи старые клиенты;
|
||||
- собрать `ja4`, `ja4_raw`, platform/version, source network;
|
||||
- проверить тот же client через другую сеть;
|
||||
- проверить другой 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`.
|
||||
4. Сравнить `by_user`, `by_ip`, `by_cidr`, `by_fingerprint`.
|
||||
5. Проверить, появляется ли problematic source в Telemt вообще.
|
||||
6. Если не появляется, снять packet capture на сервере и клиенте.
|
||||
7. Если появляется без `auth_success`, проверить secret/client/proxy link и bad/probe counters.
|
||||
8. Если появляется с `auth_success`, исключить JA4 ClientHello как primary cause и перейти к relay/upstream/runtime диагностике.
|
||||
9. Если один JA4 стабильно коррелирует с block, собрать client version/platform evidence.
|
||||
10. Проверить, меняет ли обновление клиента JA4 и результат подключения.
|
||||
|
||||
## Минимальный incident report
|
||||
|
||||
Для полезного отчёта по JA4-based блокировке соберите:
|
||||
|
||||
```text
|
||||
time_window:
|
||||
telemt_version:
|
||||
server_ip:
|
||||
server_port:
|
||||
tls_domain:
|
||||
mask_host:
|
||||
client_platform:
|
||||
client_version:
|
||||
source_network:
|
||||
source_ip_or_cidr:
|
||||
ja4:
|
||||
ja4_raw:
|
||||
ja3:
|
||||
total:
|
||||
auth_success:
|
||||
bad_or_probe:
|
||||
seen_in_by_user: yes/no
|
||||
seen_in_by_ip: yes/no
|
||||
seen_in_by_cidr: yes/no
|
||||
server_tcpdump_seen_clienthello: yes/no
|
||||
client_tcpdump_sent_clienthello: yes/no
|
||||
works_from_other_network: yes/no
|
||||
works_with_other_client_version: yes/no
|
||||
```
|
||||
|
||||
Этот набор обычно достаточен, чтобы отличить client fingerprint block от IP/SNI/reputation block и от post-auth проблем Telemt.
|
||||
|
||||
## Источники форматов
|
||||
|
||||
- JA3 reference: https://github.com/salesforce/ja3
|
||||
- JA4 technical details: https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md
|
||||
|
||||
@@ -632,7 +632,7 @@ This document lists all configuration keys accepted by `config.toml`.
|
||||
```
|
||||
## beobachten
|
||||
- **Constraints / validation**: `bool`.
|
||||
- **Description**: Enables per-IP forensic observation buckets.
|
||||
- **Description**: Enables per-IP forensic observation buckets and appends TLS JA3/JA4 fingerprint snapshots to Beobachten output when available.
|
||||
- **Example**:
|
||||
|
||||
```toml
|
||||
@@ -641,7 +641,7 @@ This document lists all configuration keys accepted by `config.toml`.
|
||||
```
|
||||
## beobachten_minutes
|
||||
- **Constraints / validation**: Must be `> 0` (minutes).
|
||||
- **Description**: Retention window (minutes) for per-IP observation buckets.
|
||||
- **Description**: Retention window (minutes) for per-IP observation buckets and in-memory TLS fingerprint buckets.
|
||||
- **Example**:
|
||||
|
||||
```toml
|
||||
@@ -2173,7 +2173,7 @@ Note: This section also accepts the legacy alias `[server.admin_api]` (same sche
|
||||
```
|
||||
## runtime_edge_top_n
|
||||
- **Constraints / validation**: `1..=1000`.
|
||||
- **Description**: Top-N size for edge connection leaderboard.
|
||||
- **Description**: Top-N size for edge connection and TLS fingerprint leaderboard snapshots.
|
||||
- **Example**:
|
||||
|
||||
```toml
|
||||
|
||||
@@ -632,7 +632,7 @@
|
||||
```
|
||||
## beobachten
|
||||
- **Ограничения / валидация**: `bool`.
|
||||
- **Описание**: Включает "криминалистическое" наблюдения для каждого 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’ов.
|
||||
- **Пример**:
|
||||
|
||||
```toml
|
||||
|
||||
@@ -40,6 +40,8 @@ hello2 = "ad_tag2"
|
||||
> Проблема с 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