Как работает подмена TCP-стекла для обхода DPI (Deep Packet Inspection)
Содержание
- Как работает подмена TCP-стека для обхода DPI
- Почему DPI так опасен
- Что такое TCP-стек и почему его можно подменить
- Как подмена стека обманывает DPI
- Реальный пример: подмена под Chrome на Linux
- Включаем timestamp
- Меняем window scale на 8 (как в Windows 10)
- Устанавливаем MSS в 1460 (стандарт для Ethernet)
- Профили TCP-стека для разных ОС
- Инструменты для подмены
- Подмена TTL на 128
- Подмена MSS на 1460
- Как DPI распознаёт подмену
- Почему подмена не панацея
- Практический кейс: обход DPI на lexic.ml
- Устанавливаем параметры как на Android
- Подменяем TTL на 64 (Android)
- Как проверить, что подмена сработала
- Когда подмена не нужна
- Вывод
Как работает подмена TCP-стека для обхода DPI
Deep Packet Inspection — зверь хитрый. Он не просто смотрит заголовки пакетов, а лезет внутрь, анализирует сигнатуры, поведение протоколов. И если ваш трафик выглядит как стандартный HTTP или TLS — DPI его раскусит за секунду. Подмена TCP-стека — один из способов запутать анализатор.
Идея простая: изменить то, как ваша система отправляет TCP-пакеты, чтобы они не совпадали с ожидаемым профилем. DPI часто полагается на типовые характеристики стека — размер окна, последовательность флагов, тайминги. Сделай их нестандартными — и фильтр начнёт тупить.
Почему DPI так опасен
Обычный файрвол смотрит на IP и порты. DPI же копает глубже — до седьмого уровня OSI. Он видит ваш HTTP-запрос, TLS-рукопожатие, даже зашифрованный трафик может быть профилирован по размеру пакетов и временным задержкам.
В некоторых странах DPI используется для блокировки VPN, Tor, прокси. Например, в Китае Great Firewall анализирует первые пакеты TLS-соединения и режет их, если видит характерные признаки OpenVPN или Shadowsocks.
Что такое TCP-стек и почему его можно подменить
TCP-стек — это реализация протокола в ядре ОС. У Linux, Windows, FreeBSD, macOS — свои особенности. Они проявляются в:
- Начальном размере окна (window scale)
- Порядке TCP-флагов (SYN, SYN-ACK, ACK)
- Значениях опций (MSS, SACK, timestamp)
- Поведении при ретрансмиссии
DPI собирает эти параметры в отпечаток (fingerprint). Если ваш стек совпадает с известным — трафик могут пропустить. Если нет — заблокировать. Или наоборот: если вы используете типичный OpenVPN-стек, его сразу отсекут.
Как подмена стека обманывает DPI
Суть — сделать ваш трафик похожим на легитимный. Например, подменить параметры TCP под браузер Chrome на Windows 10. Или под Android Chrome. DPI видит: window scale 8, MSS 1460, timestamp включён — похоже на настоящий браузер. Пропускаем.
Есть два подхода:
1. **Модификация ядра** — править sysctl в Linux или использовать iproute2 для настройки TCP-параметров.
2. **Прокси-утилиты** — вроде `goodbyedpi`, `zapret`, `bypass` — они перехватывают пакеты на лету и меняют их характеристики.
Реальный пример: подмена под Chrome на Linux
Допустим, вы на Ubuntu. Типичный Linux-стек имеет window scale 7, MSS 1460, timestamp выключен. DPI видит — это Linux. Если вы используете прокси, его тоже могут заблокировать.
Меняем параметры:
```bash
Включаем timestamp
echo 1 > /proc/sys/net/ipv4/tcp_timestamps
Меняем window scale на 8 (как в Windows 10)
echo 8 > /proc/sys/net/ipv4/tcp_window_scaling
Устанавливаем MSS в 1460 (стандарт для Ethernet)
echo 1460 > /proc/sys/net/ipv4/tcp_mss
```
После этого ваш стек станет похож на Windows 10. DPI увидит: window scale 8, timestamp есть — пропускаем.
Но это грубый метод. DPI может анализировать несколько параметров одновременно. Например, комбинация window scale + MSS + порядок флагов. Для точной подмены используют готовые профили.
Профили TCP-стека для разных ОС
Вот таблица типичных параметров:
| ОС | Window Scale | MSS | Timestamp | SACK | TTL |
|---|---|---|---|---|---|
| Windows 10 | 8 | 1460 | Да | Да | 128 |
| Linux (Ubuntu) | 7 | 1460 | Нет | Да | 64 |
| macOS | 7 | 1460 | Да | Да | 64 |
| Android | 7 | 1440 | Да | Да | 64 |
| iOS | 7 | 1440 | Да | Да | 64 |
DPI смотрит на TTL (Time To Live). Windows по умолчанию 128, Linux — 64. Если ваш пакет пришёл с TTL=64, а window scale как у Windows — это подозрительно. DPI может зафиксировать несоответствие и заблокировать.
Поэтому подмена стека — это комплексная задача. Нужно менять не только параметры TCP, но и TTL, и поведение при ретрансмиссии.
Инструменты для подмены
**goodbyedpi** — популярная утилита для обхода DPI в России. Она перехватывает пакеты и меняет их на лету. Работает на уровне ядра, не требует правки конфигов.
Пример запуска:
```bash
goodbyedpi -f 2 -e 1 -r 1 --blacklist blacklist.txt
```
Флаги `-f 2` и `-e 1` меняют порядок флагов TCP, `-r 1` включает подмену window scale.
**zapret** — более мощный инструмент. Умеет подменять MSS, TTL, window scale, а также фрагментировать пакеты. Конфиг в `/etc/zapret/config`.
Пример:
```bash
Подмена TTL на 128
iptables -t mangle -A POSTROUTING -j TTL --ttl-set 128
Подмена MSS на 1460
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN SYN -j TCPMSS --set-mss 1460
```
**bypass** — для обхода DPI на уровне приложений. Запускается как прокси, подменяет параметры соединения.
Как DPI распознаёт подмену
Хитрые DPI-системы не просто смотрят на параметры, а анализируют поведение. Например:
- Если window scale меняется в процессе соединения — это подозрительно.
- Если TTL не соответствует начальному значению — тоже.
- Если порядок флагов нелогичен (например, SYN-ACK приходит без SYN) — блокировка.
Есть ещё техника "активного зондирования". DPI отправляет вашему клиенту специальный пакет и смотрит, как он реагирует. Если ответ не совпадает с ожидаемым для вашей ОС — трафик режется.
Например, DPI может отправить пакет с RST-флагом. Настоящий Windows-клиент проигнорирует его, если соединение уже закрыто. А Linux-клиент может ответить ACK. DPI видит несоответствие — блокирует.
Почему подмена не панацея
Подмена TCP-стека — это игра в кошки-мышки. DPI постоянно обновляется. То, что работало вчера, сегодня может быть заблокировано.
Кроме того, подмена не решает проблему анализа содержимого. Если вы передаёте явно запрещённые данные (например, ключи от VPN), DPI может их обнаружить даже с подменённым стеком.
Для серьёзного обхода нужно комбинировать методы: подмена стека + шифрование + фрагментация пакетов + использование случайных портов.
Практический кейс: обход DPI на lexic.ml
На lexic.ml мы используем подмену TCP-стека как часть защиты. Клиенты подключаются через IPv6-прокси, и мы настраиваем параметры так, чтобы трафик выглядел как обычный HTTPS-запрос с мобильного устройства.
Пример настройки для клиента на Linux:
```bash
Устанавливаем параметры как на Android
sysctl -w net.ipv4.tcp_window_scaling=1
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_sack=1
sysctl -w net.ipv4.tcp_mss=1440
Подменяем TTL на 64 (Android)
iptables -t mangle -A POSTROUTING -j TTL --ttl-set 64
```
После этого DPI видит: window scale 7, MSS 1440, timestamp включён, TTL 64 — похоже на Android. Пропускает.
Но это не гарантия. DPI может анализировать и другие параметры, например, размер первоначального окна (initial window). У Android он часто 10, у Linux — 14. Если не подменить, DPI заметит.
Как проверить, что подмена сработала
Используйте онлайн-сервисы вроде `tcpdump` или `wireshark`. Захватите пакет и посмотрите его параметры:
```bash
tcpdump -i eth0 -X -vvv 'tcp port 443'
```
Сравните с эталонным профилем. Если window scale, MSS, TTL совпадают — подмена удалась.
Ещё есть утилита `p0f`, которая определяет ОС по TCP-стеку. Она покажет, что ваш клиент теперь выглядит как Windows или Android.
Когда подмена не нужна
Если вы используете HTTPS с правильными сертификатами и DPI не блокирует TLS — подмена излишня. Она нужна только когда DPI режет трафик по сигнатурам.
Также подмена бесполезна против DPI, который анализирует содержимое на уровне приложений. Например, если DPI распознаёт протокол QUIC по первым байтам — подмена TCP-стека не поможет.
Вывод
Подмена TCP-стека — мощный, но не универсальный метод. Он работает против DPI, который полагается на fingerprinting. Но требует тонкой настройки и постоянного обновления.
Комбинируйте с другими техниками: фрагментация, шифрование, случайные порты. И не забывайте про TTL — это один из ключевых параметров, который DPI проверяет в первую очередь.