Модератор: вероятно, при создании данной статьи использовался ИИ. Объёмы и профиль использования известны только автору.
Пошаговый разбор того, как ТСПУ анализирует трафик от первого SYN до поведенческого ML. С конкретными числами, реальными алгоритмами и объяснением почему одни протоколы умирают на первом байте, а другие живут месяцами.
Большинство объяснений про DPI звучат так: «система смотрит на пакеты и блокирует плохие». Примерно как объяснить работу компилятора словами «берёт код и делает программу» формально не ложь, но понять из этого что-либо невозможно.
Ниже то, что реально происходит с пакетом от момента выхода с твоего устройства до момента, когда ТСПУ принимает решение. Пошагово, с числами.
Нулевой момент: SYN-пакет
Ты нажимаешь Enter. Браузер или прокси-клиент отправляет TCP SYN на удалённый сервер.
В пакете: IP-заголовок (твой IP, IP назначения, TTL, протокол) и TCP-заголовок (порты, флаг SYN, sequence number, размер окна, TCP-опции). Данных приложения нет вообще — это просто «хочу соединиться».
ТСПУ на этом этапе уже смотрит, но не блокирует. Создаёт запись в таблице соединений: IP источника, IP назначения, порт, время начала. По наблюдениям сообщества ntc.party (для входа возможно потребуются танцы с бубном), первые пять пакетов соединения проходят без активного вмешательства — система собирает данные.
Пакеты 1–5: сбор контекста
За первые пять пакетов ТСПУ собирает базовый профиль соединения. Три вещи интересуют её здесь больше всего.
TTL. Windows отправляет TTL=128, Linux — 64, некоторые устройства — 255. Пакет с TTL=63 прошёл через один хоп от отправителя, TTL=62 через два. Это даёт приблизительную топологию между тобой и сервером. Нужно это для одного: детекции fake-пакетов. Zapret и аналогичные инструменты отправляют поддельные пакеты с намеренно заниженным TTL чтобы они доехали до ТСПУ, но не доехали до реального сервера. ТСПУ научилась это видеть.
TCP-опции. В SYN-пакете: MSS, Window Scale, SACK, Timestamps. Их набор и порядок — отдельный fingerprint. Linux-ядро отправляет один набор, Windows другой, iOS третий. Если заявленная ОС и реальный набор опций не совпадают — аномалия.
Размер первого пакета данных. Если первый содержательный пакет после рукопожатия короче 83 байт — подозрительно. TLS ClientHello намного длиннее. Очень короткий первый пакет: либо кастомный протокол, либо намеренное разбиение для обхода DPI.
Байты 0–5: протокольный маркер
Первые несколько байт данных приложения — самая быстрая проверка. Буквально memcmp() против таблицы паттернов.
TLS ClientHello начинается строго так:
16 03 01 xx xx 01 00 xx xx xx 03 03...
0x16 — Content Type: Handshake. 0x03 0x01 — TLS-версия (legacy-поле, всегда 1.0). 0x01 — Handshake Type: ClientHello. 0x03 0x03 — TLS 1.3 внутри ClientHello.
OpenVPN начинается иначе. Shadowsocks без обфускации выглядит как статистически случайные байты — что само по себе маркер. WireGuard имеет характерный UDP-заголовок. SSH начинается с SSH-2.0-.
Работает за микросекунды, стоит почти ничего, убивает OpenVPN, чистый WireGuard, SSH-туннели и старые Shadowsocks. VLESS с TLS эту проверку проходит — первые байты идентичны любому HTTPS.
Байты 6–300: TLS ClientHello и JA3
ClientHello — самый информативный пакет для детектора. Он содержит список cipher suites, список TLS-расширений с их содержимым, поддерживаемые elliptic curves, форматы точек, SNI в открытом виде, ALPN и GREASE-значения (если это настоящий Chrome).
Из всего этого вычисляется JA3-хэш:
JA3 = MD5( SSLVersion, Ciphers, # без GREASE-значений Extensions, # без GREASE, без padding (21) EllipticCurves, EllipticCurvePointFormats )
TLS Fingerprinting with JA3 and JA3S - Salesforce Engineering Blog — рекомендую ознакомиться. Реальный Chrome 120 на Windows 11 даёт конкретный хэш. Go-стандартная crypto/tls без uTLS — другой. Этот хэш известен и внесён в базы детекции.

JA4 — более новая версия (FoxIO, 2023): менее чувствителен к порядку расширений, разделяет клиентскую и серверную части, даёт более стабильный отпечаток. DPI-системы переходят на него.
SNI в ClientHello — открытый текст даже в TLS 1.3. Если SNI = icloud.com, а IP назначения принадлежит нидерландскому хостингу — несоответствие видно сразу.
ALPN — протокол приложения. Настоящий браузер предлагает h2 и http/1.1. Прокси-клиент без правильной настройки иногда не включает ALPN вообще — и это тоже аномалия.
Байты 300–3000: ServerHello и сертификат
Сервер отвечает ServerHello, потом Certificate. В сертификате три вещи интересны детектору.
Common Name и Subject Alternative Names. SNI в ClientHello говорил icloud.com значит сертификат должен быть Apple. Если пришёл Let's Encrypt на случайный домен — не совпадает.
Certificate Transparency Logs. Вс�� публичные TLS-сертификаты логируются в CT Logs. Существует ли этот сертификат? Выпущен ли на этот домен? Для самоподписанных ответ «нет».
ASN сервера против ожидаемого ASN домена. Apple держит серверы в AS714. Microsoft в AS8075. Сертификат говорит «я Microsoft», а пакеты приходят из AS24940 (Hetzner) — детектируемое несоответствие. Reality закрывает эту проблему полностью: TLS-сессия завершается на настоящем сервере Apple или Microsoft, сертификат настоящий, ASN совпадает.
Байты 3000–16 000: первые данные приложения
После завершения TLS-рукопожатия начинается зашифрованный трафик приложения. Содержимое недоступно. Но анализ продолжается — по метаданным потока.
Размеры пакетов. У браузерного HTTPS-трафика характерное распределение: HTTP-запросы маленькие (заголовки, GET), HTTP-ответы большие (контент). Асимметричный паттерн с пиками вокруг конкретных значений. Туннель с видео внутри — все пакеты близко к MTU (1400–1500 байт), равномерно. Туннель с интерактивным трафиком — мелкие пакеты в обоих направлениях. Ни то ни другое не похоже на браузерный HTTP.
Межпакетные интервалы. Браузер делает паузы: загрузил HTML — парсит, загружает CSS — парсит, загружает JS. Паузы десятки-сотни миллисекунд, с характерным распределением. VLESS-туннель под нагрузкой гонит данные непрерывно.
Соотношение входящего и исходящего. При обычном браузинге исходящий трафик намного меньше входящего, типичное соотношение 1:10 или 1:20. Туннель, по которому пользователь активно что-то отправляет, нарушает это соотношение.
Продолжительность соединения. Реальный браузер открывает HTTPS, загружает страни��у, держит несколько минут через keep-alive, закрывает. VLESS держит соединение открытым часами. Persistent connection к «iCloud» без единого характерного iCloud API-запроса — аномалия.
После 16 КБ: поведенческий ML
К этому моменту собрано достаточно для ML-классификатора.
Классификатор смотрит на ритм пакетов: реальный пользователь читает статью — загрузил страницу, затих на минуту, прокрутил, снова всплеск. Туннель под нагрузкой: равномерный поток без пауз.
На энтропию данных: зашифрованные данные высокоэнтропийны, но степень равномерности энтропии между пакетами у разных протоколов отличается. Туннель с несколькими слоями шифрования даёт другой энтропийный профиль, чем обычный HTTPS.
На паттерны мультиплексирования: HTTP/2 мультиплексирует несколько стримов в одно соединение. У реального браузера несколько параллельных стримов разного размера и разной продолжительности. Туннель, который гонит весь пользовательский трафик в один HTTP/2-поток, выглядит иначе.

Точность ML-классификаторов в лабораторных условиях достигает 95–99% для Shadowsocks и VMess. В продакшне ниже, ложные срабатывания дорого стоят. Но тренд понятен: система обучается непрерывно на реальном трафике.
Как блокировка срабатывает технически
Три метода, каждый со своим поведением.
TCP RST injection. ТСПУ вставляет в поток RST-пакет. Обе стороны получают сигнал «соединение разорвано» и закрывают его. Быстро и дёшево. Обходится через проверку sequence numbers — RST с неправильным числом клиент игнорирует.
Дроп пакетов. Пакет не доходит до назначения без уведомления сторон. Соединение зависает, потом таймаут. Сложнее обойти, потому что нет явного сигнала.
Замедление. Трафик намеренно throttle-ится: задержки, потери. Именно так работало замедление Twitter и YouTube — не блокировка, а деградация до состояния где пользоваться невозможно.
Как это знание применять
Каждая защита закрывает конкретный слой:
fingerprint: chrome в Xray — закрывает JA3-детекцию на уровне байт 6–300
Reality — закрывает несоответствие сертификата и ASN
XHTTP — закрывает поведенческую детекцию через нормализацию паттерна трафика
xPaddingBytes — нормализует распределение размеров пакетов
Правильный SNI-донор — закрывает IP/ASN несоответствие
Ни один инструмент в одиночку все слои не закрывает.
Неудобная деталь
Активный DPI стоит в разрыве сети и обрабатывает каждый пакет в реальном времени. Это даёт добавочный latency — на практике 1–5ms для большинства соединений. Для обычного пользователя незаметно, но статистически измеримо.
Есть инструменты, которые детектируют ТСПУ именно по этому признаку: отправляют специально сформированные пакеты и смотрят, изменился ли паттерн задержек. Работает.
¹ Редакция напоминает: изучение принципов работы DPI является потенциально опасным занятием, так как приводит к пониманию того, как именно устроена система стоимостью 20+ млрд рублей из федерального бюджета. Эти знания могут вызвать нежелательные побочные эффекты: критическое мышление, технический суверенитет и стойкое ощущение что деньги потрачены как-то не туда. Проконсультируйтесь с Роскомнадзором перед применением.
Если есть идеи для разбора, нашёл ошибку
или хочешь предложить тему — пиши на
aleksandr@murzin.digital Отвечаю.
