vaspvort
Ночной дозор
Команда форума
Модератор
ПРОВЕРЕННЫЙ ПРОДАВЕЦ
Private Club
Старожил
Migalki Club
Меценат💎
В последние годы в России активно развивается и применяется инфраструктура фильтрации трафика на уровне провайдеров. Основные технологии, которые используются для этого — ТСПУ (технические средства противодействия угрозам) и DPI (Deep Packet Inspection).
В этой статье мы разберём, как именно эти системы видят и классифицируют трафик, на каких полях и протоколах принимаются решения о блокировке, и какие техники применяются для обхода (с точки зрения механики, а не «инструкций»).
Основные функции ТСПУ:
Основные функции DPI:
Mirror/SPAN: копия трафика отправляется на DPI, оригинальный поток не прерывается. DPI может только анализировать и сигнализировать, но не вмешиваться напрямую.
Архитектура инспекции трафика сети
Модель OSI
Этого достаточно для: блокировок по IP, rate limiting, детектирования некоторых VPN/туннелей по паттернам.
Одним из наиболее важных расширений является SNI (Server Name Indication). SNI передаёт доменное имя сервера в открытом виде (например, server_name = example.com). Это необходимо серверу для выбора правильного SSL-сертификата, особенно когда несколько доменов размещены на одном IP-адресе.
DPI-системы активно используют эту особенность для блокировки сайтов. Алгоритм работы DPI выглядит следующим образом:
После того как DPI увидел SNI, возможны два основных сценария блокировки:
DNS как дополнительный источник информации
До начала TLS-handshake почти всегда выполняется DNS-запрос. Если DNS не зашифрован (стандартный UDP/TCP на порт 53), DPI видит QNAME (имя домена в запросе) и может блокировать соединение ещё на этапе разрешения домена. В случае использования зашифрованных протоколов, таких как DoH (DNS over HTTPS) или DoT (DNS over TLS), DNS-запрос скрыт, и DPI полагается на SNI, IP-адрес после разрешения или поведенческие признаки трафика.
Поведенческий анализ для сложных случаев
Когда прямых сигнатур (как SNI) недостаточно, DPI применяет статистический и поведенческий анализ:
Пример захвата SNI с помощью Scapy
Для понимания того, как DPI видит ваши пакеты, воспользуемся библиотекой scapy. Напишем простой сниффер, который выделяет домены из TLS-трафика.
from scapy.all import sniff
from scapy.layers.inet import IP
from scapy.layers.tls.all import TLSClientHello, TLSExtensionServerName
def extract_sni(pkt):
# Проверяем наличие TLS ClientHello в пакете
if TLSClientHello not in pkt:
return None
# Перебираем расширения в поисках ServerName
# В Scapy расширения лежат в поле .extensions или .ext (зависит от версии)
extensions = getattr(pkt[TLSClientHello], 'extensions', pkt[TLSClientHello].ext)
for ext in extensions:
if isinstance(ext, TLSExtensionServerName):
try:
# Извлекаем первый сервер из списка (обычно он там один)
server_name = ext.servernames[0].servername.decode('utf-8')
return server_name
except (IndexError, AttributeError):
continue
return None
def packet_callback(pkt):
sni = extract_sni(pkt)
if sni:
src_ip = pkt[IP].src
print(f"[DPI Alert] Detected SNI: {sni} from {src_ip}")
print("Сниффинг запущен. Ожидание TLS ClientHello...")
# Фильтр tcp port 443 ускоряет работу, отсекая лишний мусор
sniff(filter="tcp port 443", prn=packet_callback, store=0)
Ниже пример псевдокода, который создает сырой сокет и отправляет фрагментированный запрос:
from scapy.all import IP, TCP, Raw, send
def fragment_client_hello(dst_ip, dst_port, sni):
"""
Упрощённая демонстрация фрагментации TLS ClientHello.
Отправляет SYN, затем разбитый на 2 части пакет с началом ClientHello и SNI.
"""
# Шаг 1: Отправка SYN для начала TCP-handshake (упрощённо, без SYN-ACK)
ip = IP(dst=dst_ip)
tcp_syn = TCP(dport=dst_port, flags="S")
send(ip / tcp_syn, verbose=0)
# Пример начала ClientHello (TLS record header + начало handshake)
client_hello_start = b"\x16\x03\x01\x00\xaa\x01\x00\x00\xa6\x03\x03" # ContentType=22 (handshake), version=3.1 (TLS 1.0), length, etc.
# Часть с SNI (упрощённо, extension server_name)
sni_bytes = sni.encode('utf-8')
sni_extension = b"\x00\x00" + len(sni_bytes + 3).to_bytes(2, 'big') + b"\x00" + len(sni_bytes).to_bytes(2, 'big') + b"\x00" + sni_bytes # server_name extension
client_hello_sni = b"\x00\x00\x00" + sni_extension # Placeholder для остальной части
# Шаг 2: Фрагментированные пакеты (seq нужно корректировать на основе реального SYN-ACK)
# Part 1: Начало ClientHello
tcp_part1 = TCP(dport=dst_port, seq=1, ack=1, flags="PA") # Упрощённо, seq/ack должны быть реальными
part1 = ip / tcp_part1 / Raw(load=client_hello_start)
send(part1, verbose=0)
# Part 2: Продолжение с SNI (seq = предыдущий seq + len(payload part1))
tcp_part2 = TCP(dport=dst_port, seq=1 + len(client_hello_start), ack=1, flags="PA")
part2 = ip / tcp_part2 / Raw(load=client_hello_sni)
send(part2, verbose=0)
print(f"Фрагментированный ClientHello с SNI '{sni}' отправлен на {dst_ip}:{dst_port}")
# Пример вызова (требует root-прав: sudo python3 script.py)
# fragment_client_hello("93.184.216.34", 443, "example.com")
Но на 2026 год большинство DPI-систем в России всё ещё довольно эффективно блокируют QUIC по:
Глубокая инспекция пакетов на уровне L7 требует значительных вычислительных ресурсов: каждый поток необходимо разобрать, классифицировать и сопоставить с наборами сигнатур и политик в реальном времени. При росте пропускной способности сети это приводит к высокой нагрузке на DPI-узлы и необходимости компромиссов между глубиной анализа и производительностью.
Дополнительной проблемой является рост ложных срабатываний: схожие паттерны трафика у легитимных сервисов и запрещённых приложений могут приводить к ошибочной блокировке. DPI также сильно зависит от актуальности сигнатур — любые изменения в протоколах или реализации приложений требуют постоянного обновления правил, иначе эффективность фильтрации снижается.
Архитектурные ограничения
Многие сети используют асимметричную маршрутизацию, при которой прямой и обратный трафик проходят через разные узлы. В таких условиях DPI видит лишь часть сессии, что усложняет корректный анализ состояний TCP и прикладных протоколов.
Отдельной проблемой является распространение QUIC, работающего поверх UDP: отсутствие классического TCP-handshake и шифрование значительной части метаданных резко сокращают объём информации, доступной для инспекции.
В перспективе дополнительным ограничением становится внедрение ECH (Encrypted Client Hello), при котором поле SNI шифруется. Это лишает DPI одного из ключевых источников информации о целевом домене и вынуждает системы фильтрации полагаться почти исключительно на IP-адреса и поведенческие признаки.
Источник
В этой статье мы разберём, как именно эти системы видят и классифицируют трафик, на каких полях и протоколах принимаются решения о блокировке, и какие техники применяются для обхода (с точки зрения механики, а не «инструкций»).
Что такое ТСПУ и как оно связано с DPI
ТСПУ — это общее название комплекса оборудования и ПО, которое устанавливается у операторов связи в соответствии с требованиями законодательства (в первую очередь 149-ФЗ "О связи" (закон о "суверенном интернете"), 398-ФЗ и приказы Роскомнадзора). Это "чёрные ящики" на сетях провайдеров, под контролем Роскомнадзора (РКН). К 2023–2026 годам покрытие — 100% узлов связи, с переходом на отечественное оборудование (Сигналтек, Yadro, Ростелеком).Основные функции ТСПУ:
- Централизованно задаёт правила для DPI (что блокировать и как).
- Синхронизирует списки (в т.ч. реестры).
- Собирает отчёты от DPI и передаёт их в центр управления.
Основные функции DPI:
- DPI-анализ (глубокая проверка пакетов).
- Фильтрация по спискам запрещённых ресурсов (реестр РКН).
- Блокирование по IP, доменам, SNI, протоколам, сигнатурам.
- Протокольная идентификация (HTTP, HTTPS, QUIC, VPN-протоколы, Tor, Shadowsocks и др.).
- Сбор статистики и передача в центр управления.
Разница между DPI и ТСПУ
Место DPI в сети провайдера
DPI-узел находится в разрыве трафика (inline) или получает копию трафика (mirror/SPAN). В режиме inline система может:- пропускать пакет;
- дропать пакет;
- подменять ответ (RST, FIN, HTTP redirect);
- маркировать поток для дальнейшей обработки.
Mirror/SPAN: копия трафика отправляется на DPI, оригинальный поток не прерывается. DPI может только анализировать и сигнализировать, но не вмешиваться напрямую.
Архитектура инспекции трафика сети
- Клиент — пользователь (абонент).
- BRAS/BNG — узел провайдера, где пользователь (абонент) аутентифицируется и получает доступ в сеть.
- DPI — инспектирует и фильтрует трафик (inline или mirror).
- Upstream / IX — внешний интернет.
Что именно видит DPI
DPI анализирует трафик послойно, по модели OSI.
Модель OSI
L3–L4: IP и TCP/UDP
На этом уровне доступны: source/destination IP и port, TCP flags, sequence/ack numbers, размер и частота пакетов.Этого достаточно для: блокировок по IP, rate limiting, детектирования некоторых VPN/туннелей по паттернам.
L7: прикладной уровень
Для небезопасных протоколов (HTTP, DNS без шифрования) DPI видит полезную нагрузку целиком. Для зашифрованных протоколов (TLS) анализ ограничен метаданными.Как DPI видит домен в HTTPS-трафике (SNI)
Хотя современный интернет практически полностью перешёл на HTTPS (TLS), процесс установления соединения начинается в открытом виде. При инициации HTTPS-соединения клиент отправляет пакет ClientHello, который не зашифрован. Этот пакет содержит ключевую информацию: версию TLS, список поддерживаемых cipher suites и extensions.Одним из наиболее важных расширений является SNI (Server Name Indication). SNI передаёт доменное имя сервера в открытом виде (например, server_name = example.com). Это необходимо серверу для выбора правильного SSL-сертификата, особенно когда несколько доменов размещены на одном IP-адресе.
DPI-системы активно используют эту особенность для блокировки сайтов. Алгоритм работы DPI выглядит следующим образом:
- Перехватывает TCP-пакет с флагами PSH и ACK.
- Парсит структуру TLS Record.
- Извлекает значение поля server_name из расширения SNI.
- Сопоставляет его с политиками или чёрным списком (например, реестром запрещённых ресурсов).
- Принимает решение до установления полной TLS-сессии: в случае совпадения отправляет клиенту TCP RST (разрыв соединения), перенаправляет на заглушку или применяет другие меры блокировки.
После того как DPI увидел SNI, возможны два основных сценария блокировки:
- SNI-блокировка — разрыв соединения (TCP RST) сразу после получения ClientHello
- IP-блокировка — после разрешения домена (через DNS или DoH/DoT) в реестр добавляется IP-адрес, и блокируется уже по IP
DNS как дополнительный источник информации
До начала TLS-handshake почти всегда выполняется DNS-запрос. Если DNS не зашифрован (стандартный UDP/TCP на порт 53), DPI видит QNAME (имя домена в запросе) и может блокировать соединение ещё на этапе разрешения домена. В случае использования зашифрованных протоколов, таких как DoH (DNS over HTTPS) или DoT (DNS over TLS), DNS-запрос скрыт, и DPI полагается на SNI, IP-адрес после разрешения или поведенческие признаки трафика.
Поведенческий анализ для сложных случаев
Когда прямых сигнатур (как SNI) недостаточно, DPI применяет статистический и поведенческий анализ:
- Размер первых пакетов в соединении.
- Тайминги отправки и получения данных.
- Направление и объём трафика.
- Характер retransmission (повторных передач).
Пример захвата SNI с помощью Scapy
Для понимания того, как DPI видит ваши пакеты, воспользуемся библиотекой scapy. Напишем простой сниффер, который выделяет домены из TLS-трафика.
from scapy.all import sniff
from scapy.layers.inet import IP
from scapy.layers.tls.all import TLSClientHello, TLSExtensionServerName
def extract_sni(pkt):
# Проверяем наличие TLS ClientHello в пакете
if TLSClientHello not in pkt:
return None
# Перебираем расширения в поисках ServerName
# В Scapy расширения лежат в поле .extensions или .ext (зависит от версии)
extensions = getattr(pkt[TLSClientHello], 'extensions', pkt[TLSClientHello].ext)
for ext in extensions:
if isinstance(ext, TLSExtensionServerName):
try:
# Извлекаем первый сервер из списка (обычно он там один)
server_name = ext.servernames[0].servername.decode('utf-8')
return server_name
except (IndexError, AttributeError):
continue
return None
def packet_callback(pkt):
sni = extract_sni(pkt)
if sni:
src_ip = pkt[IP].src
print(f"[DPI Alert] Detected SNI: {sni} from {src_ip}")
print("Сниффинг запущен. Ожидание TLS ClientHello...")
# Фильтр tcp port 443 ускоряет работу, отсекая лишний мусор
sniff(filter="tcp port 443", prn=packet_callback, store=0)
Почему DPI не расшифровывает HTTPS
Важно понимать: DPI не расшифровывает содержимое TLS-трафика в обычном режиме работы. Для настоящей расшифровки потребовался бы полноценный MITM (man-in-the-middle), а это практически невозможно в масштабах провайдера по следующим причинам:- Нет приватного ключа сервера Без него невозможно расшифровать сессию TLS.
- Невозможно вмешаться в handshake без подмены сертификата Современные браузеры и приложения проверяют цепочку сертификатов и используют Certificate Transparency, HPKP (устаревший), Expect-CT, а также встроенные списки pinned сертификатов (например, в Chrome, Firefox, Telegram, Signal). Подмена сертификата сразу вызовет ошибку.
- на этапе до шифрования (ClientHello, SNI, JA3/JA4 отпечатки)
- по метаданным соединения (IP-адреса, порты, объём первых пакетов, тайминги)
- по поведенческим признакам и корреляции потоков (паттерны трафика, характер retransmission, размер пакетов, направление)
Механизмы обхода: Сегментация TCP
Один из классических способов обхода примитивных DPI — фрагментация пакета. Если разбить Client Hello на два TCP-сегмента, система фильтрации может не собрать их воедино для анализа сигнатуры, если она настроена на «потоковую» обработку без полноценного реассемблирования (что дорого по ресурсам).Ниже пример псевдокода, который создает сырой сокет и отправляет фрагментированный запрос:
from scapy.all import IP, TCP, Raw, send
def fragment_client_hello(dst_ip, dst_port, sni):
"""
Упрощённая демонстрация фрагментации TLS ClientHello.
Отправляет SYN, затем разбитый на 2 части пакет с началом ClientHello и SNI.
"""
# Шаг 1: Отправка SYN для начала TCP-handshake (упрощённо, без SYN-ACK)
ip = IP(dst=dst_ip)
tcp_syn = TCP(dport=dst_port, flags="S")
send(ip / tcp_syn, verbose=0)
# Пример начала ClientHello (TLS record header + начало handshake)
client_hello_start = b"\x16\x03\x01\x00\xaa\x01\x00\x00\xa6\x03\x03" # ContentType=22 (handshake), version=3.1 (TLS 1.0), length, etc.
# Часть с SNI (упрощённо, extension server_name)
sni_bytes = sni.encode('utf-8')
sni_extension = b"\x00\x00" + len(sni_bytes + 3).to_bytes(2, 'big') + b"\x00" + len(sni_bytes).to_bytes(2, 'big') + b"\x00" + sni_bytes # server_name extension
client_hello_sni = b"\x00\x00\x00" + sni_extension # Placeholder для остальной части
# Шаг 2: Фрагментированные пакеты (seq нужно корректировать на основе реального SYN-ACK)
# Part 1: Начало ClientHello
tcp_part1 = TCP(dport=dst_port, seq=1, ack=1, flags="PA") # Упрощённо, seq/ack должны быть реальными
part1 = ip / tcp_part1 / Raw(load=client_hello_start)
send(part1, verbose=0)
# Part 2: Продолжение с SNI (seq = предыдущий seq + len(payload part1))
tcp_part2 = TCP(dport=dst_port, seq=1 + len(client_hello_start), ack=1, flags="PA")
part2 = ip / tcp_part2 / Raw(load=client_hello_sni)
send(part2, verbose=0)
print(f"Фрагментированный ClientHello с SNI '{sni}' отправлен на {dst_ip}:{dst_port}")
# Пример вызова (требует root-прав: sudo python3 script.py)
# fragment_client_hello("93.184.216.34", 443, "example.com")
- Это псевдокод для демонстрации. В реальности нужно обработать SYN-ACK от сервера, рассчитать правильные seq/ack и использовать полный ClientHello (можно сгенерировать через Scapy's TLSClientHello).
- Фрагментация работает на уровне IP или TCP-сегментов, но современные DPI часто собирают фрагменты перед анализом.
- Важно: реальная фрагментация требует аккуратной работы с последовательными номерами, MSS, window size и т.д.
QUIC и HTTP/3 — новый вызов для DPI
С переходом многих сервисов на QUIC (UDP 443) классический SNI-анализ становится сложнее, потому что:- Initial пакет QUIC шифрует большую часть заголовков
- SNI тоже может быть зашифрован (ECH)
Но на 2026 год большинство DPI-систем в России всё ещё довольно эффективно блокируют QUIC по:
- UDP-порту 443
- сигнатурам Initial-пакета
- известным CID (Connection ID) крупных сервисов
- статистике трафика (объём, паттерны)
Ограничения DPI
Технические ограничения DPIГлубокая инспекция пакетов на уровне L7 требует значительных вычислительных ресурсов: каждый поток необходимо разобрать, классифицировать и сопоставить с наборами сигнатур и политик в реальном времени. При росте пропускной способности сети это приводит к высокой нагрузке на DPI-узлы и необходимости компромиссов между глубиной анализа и производительностью.
Дополнительной проблемой является рост ложных срабатываний: схожие паттерны трафика у легитимных сервисов и запрещённых приложений могут приводить к ошибочной блокировке. DPI также сильно зависит от актуальности сигнатур — любые изменения в протоколах или реализации приложений требуют постоянного обновления правил, иначе эффективность фильтрации снижается.
Архитектурные ограничения
Многие сети используют асимметричную маршрутизацию, при которой прямой и обратный трафик проходят через разные узлы. В таких условиях DPI видит лишь часть сессии, что усложняет корректный анализ состояний TCP и прикладных протоколов.
Отдельной проблемой является распространение QUIC, работающего поверх UDP: отсутствие классического TCP-handshake и шифрование значительной части метаданных резко сокращают объём информации, доступной для инспекции.
В перспективе дополнительным ограничением становится внедрение ECH (Encrypted Client Hello), при котором поле SNI шифруется. Это лишает DPI одного из ключевых источников информации о целевом домене и вынуждает системы фильтрации полагаться почти исключительно на IP-адреса и поведенческие признаки.
Кратко о других методах идентификации
- JA3 / JA4 — отпечатки TLS-клиента (очень эффективно для выявления VPN, прокси, ботов)
- HTTP/2 + HTTP/3 заголовки (псевдозаголовки, порядок, значения)
- Протокольные сигнатуры (WireGuard, OpenVPN, Shadowsocks, VLESS, VMess, Hysteria и др.)
- Анализ поведения (объём трафика, количество соединений, интервалы)
Заключение
Современные системы ТСПУ/DPI — это уже не просто «чёрные списки IP». Это сложные системы, которые комбинируют: пассивный анализ L4–L7, активное зондирование, машинное обучение для выявления аномалий, а также базы отпечатков TLS и протоколов. В настоящее время наблюдается настоящая «гонка вооружений» между архитекторами сетевых протоколов, стремящимися к большей приватности и устойчивости (например, через ECH, QUIC и обфускацию трафика), и разработчиками систем фильтрации, такими как ТСПУ и DPI, которые постоянно развиваются с помощью ИИ и новых сигнатур для выявления и блокировки нежелательного трафика. В перспективе, с ростом использования ECH, QUIC и ИИ в DPI, эволюция этих технологий продолжится, требуя от инженеров новых подходов к сетевой архитектуре.Источник







