Files
telemt/docs/Architecture/Fronting-splitting/TLS_JA3_JA4_ANALYSIS.ru.md
2026-06-03 15:32:32 +03:00

24 KiB
Raw Blame History

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:

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 и имеет форму:

t<version><sni_marker><cipher_count><extension_count><alpn_marker>_<cipher_hash>_<extension_hash>

Пример:

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 включается, когда включён хотя бы один потребитель:

[general]
beobachten = true
beobachten_minutes = 10

или:

[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:

curl -s http://127.0.0.1:9091/v1/runtime/tls-fingerprints

С явным лимитом:

curl -s 'http://127.0.0.1:9091/v1/runtime/tls-fingerprints?limit=100'

Если API защищён header'ом:

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 с:

{
  "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 глобально:

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 по пользователям:

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:

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:

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:

curl -s http://127.0.0.1:9090/beobachten

Фрагмент:

[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

Во время попытки подключения проблемного пользователя смотрите:

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:

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.

На сервере:

sudo tcpdump -i any -w telemt-clienthello.pcap host CLIENT_IP and port 443

Быстрый tshark вывод ClientHello fields:

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 блокировке соберите:

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.

Источники форматов