Сигнатуры и метаданные: как DPI классифицирует трафик в эпоху TLS 1.3
От байтовых паттернов 2005 года до JA4 fingerprint и поведенческих ML-моделей
Слово «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) — это не одна технология, а четыре поколения методов, которые в современных системах используются вместе:
- Stateless pattern matching. Простой регэксп по содержимому пакета. Работает только с открытыми протоколами (старый HTTP, FTP, IMAP без TLS). На современном HTTPS бесполезен.
- Stateful flow tracking. Запоминает состояние потока: SYN → SYN-ACK → ACK → данные. Может анализировать TLS handshake, ALPN, последовательность сообщений.
- Behavioral / statistical. Считает размеры пакетов, интервалы между ними, направления, длительность. Распознаёт классы приложений по «походке» потока.
- 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 странах, без логов.
Посмотреть тарифы