Сигнатуры и метаданные: как DPI классифицирует трафик в эпоху TLS 1.3

От байтовых паттернов 2005 года до JA4 fingerprint и поведенческих ML-моделей

5 мая 2026 7 мин чтения TooTimes Team

Слово «DPI» в новостях обычно звучит так, будто это одна большая коробка, которая «читает интернет». На практике DPI — это семейство технологий, каждая из которых работает на своём слое и с разной точностью. И главное: в 2026 году ни одна из них не читает содержимого зашифрованной HTTPS-страницы. Им это и не нужно — для классификации хватает того, что соединение само показывает наружу.

Разберёмся, что такое сигнатура в инженерном смысле, как из ClientHello строится отпечаток клиента, какие поведенческие признаки отличают видео от звонка, и где у всех этих методов свои границы.

Эволюция методов классификации

2005  ─►  port-based (порт 80 = HTTP, 443 = HTTPS)
2010  ─►  string signatures (HTTP-заголовки, SNI)
2015  ─►  TLS fingerprinting (JA3)
2020  ─►  flow statistics (размеры, тайминги)
2023  ─►  JA4, behavioral ML
2026  ─►  ансамбли: JA4 + статистика + ML + IP-репутация

Каждый слой не заменяет предыдущий, а добавляется поверх.
Современная система использует все уровни сразу.
Чем больше шифруется содержимое, тем выше поднимается «уровень догадок».

Что такое DPI на самом деле

DPI (Deep Packet Inspection) — это не одна технология, а четыре поколения методов, которые в современных системах используются вместе:

  1. Stateless pattern matching. Простой регэксп по содержимому пакета. Работает только с открытыми протоколами (старый HTTP, FTP, IMAP без TLS). На современном HTTPS бесполезен.
  2. Stateful flow tracking. Запоминает состояние потока: SYN → SYN-ACK → ACK → данные. Может анализировать TLS handshake, ALPN, последовательность сообщений.
  3. Behavioral / statistical. Считает размеры пакетов, интервалы между ними, направления, длительность. Распознаёт классы приложений по «походке» потока.
  4. ML-based. Нейросети на тех же признаках, обученные на размеченных датасетах. Дают лучшую точность на сложных кейсах вроде нестандартных QUIC-приложений.

Базовое устройство DPI как класса оборудования есть в статье про глубокую инспекцию пакетов. Здесь сосредоточимся на признаках.

Сигнатуры: что узнаваемого осталось снаружи

В TLS 1.2 сигнатур было много — сертификат летел открытым текстом, и из него можно было вытащить имя CN, серийный номер, отпечаток. В TLS 1.3 сертификат зашифрован. Что осталось доступным наружу:

  • SNI — имя домена в первом ClientHello (если не включён ECH).
  • ALPN — список прикладных протоколов: h2, http/1.1, h3.
  • TLS-версия — 1.2/1.3 видны в supported_versions.
  • Cipher suites — порядок и состав предпочитаемых шифров.
  • Supported groups, signature algorithms.
  • QUIC initial packet pattern — характерные первые байты UDP-пакета QUIC v1: 0xC1 (long header) + Version Number 0x00000001.

Сигнатура — это узнаваемый шаблон в одном из этих полей. Например, точная последовательность TLS-расширений в порядке, в котором их генерирует Chrome 130 на macOS, отличается от того, что делает Chrome 130 на Android, а это уже отличается от cURL. Все эти отличия превращаются в отпечатки.

JA3 и JA4: цифровые отпечатки клиентов

В 2017 году в Salesforce придумали JA3 — алгоритм, который собирает из ClientHello стабильную строку и хеширует её в MD5. Формула: SSLVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats. Каждое поле — список значений через дефис, а потом всё через запятую и MD5.

Пример: для Chrome 90 JA3 был cd08e31494f9531f560d64c695473da9, для cURL 7.74 — e4d448cdf286ce1bd9aa31bc9eaaaab2. Один и тот же запрос к одному сайту даёт разные хэши в зависимости от клиента — это и есть fingerprint.

В 2023 году вышел JA4. Он решает три проблемы JA3:

  • Раздельный JA4 для TCP и QUIC — потому что ClientHello для них структурно отличается.
  • Сортировка extensions — JA3 был чувствителен к перестановке полей, что Chrome специально начал делать для борьбы с fingerprinting.
  • Включение ALPN, SNI и числа extension'ов — больше энтропии и устойчивость.

Формат JA4: q13d1516h2_8daaf6152771_b186095e22b6 — где q=QUIC, 13=TLS 1.3, d=DNS, остальное хеши. Полный документ — github.com/FoxIO-LLC/ja4.

Что отпечаток показывает: тип клиента (Chrome / Firefox / Safari / cURL / Python requests / Go http), версию и иногда платформу. Что не показывает: какой сайт открыт и что внутри. Это именно классификация клиента.

Поведение потока: размеры, тайминги, направления

Когда сигнатур не хватает (а с TLS 1.3 + ECH + рандомизацией Chrome их хватать перестаёт всё чаще), в дело идёт статистика. Идея простая: разные классы приложений по-разному распределяют пакеты во времени.

КлассХарактерный паттерн
VoIP (Discord voice, WhatsApp call)RTP-пакеты по 60–200 байт каждые 20 мс ровно, симметричный поток
Видеостриминг (YouTube, Netflix)Burst 5–10 секунд большими TCP-пакетами, потом пауза 10–30 с, повтор. Адаптивный битрейт меняет размер бёрстов.
Веб-страницаПервые 5–10 пакетов крупные (HTML, CSS, JS), потом россыпь мелких (картинки, шрифты, аналитика)
Игровой клиентНебольшие UDP-пакеты с регулярным интервалом 50–100 мс, симметрия
Bulk download (apt, обновление)Один поток, постоянно полные пакеты максимального размера, запрос → большой ответ

Эти признаки можно посчитать на первых 10–20 пакетах потока, что важно для inline-классификаторов: они должны принять решение быстро, не прочитав весь поток до конца.

Как современные приложения «размывают» fingerprint

Поскольку JA3/JA4 классифицирует клиентов, разработчики библиотек начали сознательно делать fingerprint менее уникальным:

  • Random extension order в Chrome. С версии 110 Chrome перетасовывает порядок расширений в ClientHello. JA3 каждого Chrome теперь разный — JA4 это учитывает.
  • Browser-imitating libraries. Библиотеки cycletls, curl-impersonate, requests-go умеют отдавать ClientHello, неотличимый от Chrome или Safari. Полезно для legitimate-парсинга, но создаёт проблему классификации.
  • QUIC padding. RFC 9000 разрешает добавлять padding-фреймы в QUIC-пакеты, что меняет размеры и сглаживает поведенческие признаки.
  • HTTP/3 SETTINGS frames можно мешать в разном порядке.

Когда сигнатур мало: ML-классификаторы

На современных нагрузках точность одного признака редко превышает 80%. Поэтому промышленные DPI собирают ансамбли: JA4 + первые 10 размеров пакетов + интервалы + направление + IP-репутация → подаётся на градиентный бустинг или нейросеть. Это даёт точность 95–99% на типовых классах при условии регулярной переобучки.

Главная сложность ML-подхода — drift. Через месяц после обновления Chrome появляется новый JA4, и модель должна это учитывать. Поэтому реальные системы переобучаются раз в неделю-две на свежем размеченном корпусе.

Границы точности и где всё ломается

Несколько случаев, когда DPI ошибается чаще, чем хочется:

  • Похожие приложения. Discord voice и Telegram voice выглядят почти одинаково в первой минуте — оба RTP, оба маленькие пакеты с регулярным интервалом.
  • Сжатые потоки внутри HTTPS. Сайты с long-poll, gRPC streaming или WebSocket по поведению похожи на realtime, хотя это просто веб.
  • QUIC в режиме анонимизированных fingerprints. Cloudflare QUIC и Google QUIC сейчас отличаются от типового Chrome, и это ломает статические правила.
  • Multi-party CDN. Один и тот же anycast-IP может обслуживать тысячи разных доменов с разным поведением.

Вывод простой: одного признака никогда не хватает. Поэтому в новостях фразы «DPI определяет» обычно стоит читать как «DPI определяет с такой-то вероятностью».

Итого

Современный DPI — это не про чтение писем, а про сложение слабых сигналов. SNI + JA4 + размеры пакетов + тайминги + IP-репутация → класс приложения с какой-то вероятностью. Чем больше веб уходит в TLS 1.3, ECH и QUIC, тем точнее должны быть статистические методы и тем сильнее работа смещается в сторону ML. Это вечная гонка между прятками и поиском.

Нужен стабильный защищённый доступ к интернету?

TooTimes — зашифрованный туннель до серверов в 9 странах, без логов.

Посмотреть тарифы
✎ Панель блога