feat(fuzzer): автоматический подбор и тюнинг DPI-стратегий для Zapret v2, Zapret v1 и ByeDPI

This commit is contained in:
Dushnilin
2026-08-26 22:18:35 +03:00
parent 6a85384111
commit dc6f0547b4
21 changed files with 7242 additions and 3102 deletions
+77 -63
View File
@@ -1,53 +1,55 @@
# 04. DPI Bypass & Desynchronization Engines
# 04. Движки обхода DPI и десинхронизации пакетов
Tachyon integrates three distinct local packet desynchronization engines that operate entirely on the router hardware without requiring an external proxy server (Zero-VPS mode).
Tachyon интегрирует три независимых локальных движка десинхронизации сетевых пакетов, которые функционируют непосредственно на оборудовании роутера без необходимости использования внешнего VPS или прокси-сервера (режим «Zero-VPS»).
---
## 1. Comparison Matrix: Zapret v1 vs Zapret v2 vs ByeDPI
## 1. Сравнительная матрица: Zapret v1 vs Zapret v2 vs ByeDPI
| Feature | Zapret v1 (`nfqws`) | Zapret v2 (`nfqws2`) | ByeDPI (`ciadpi`) |
| Параметр | Zapret v1 (`nfqws`) | Zapret v2 (`nfqws2`) | ByeDPI (`ciadpi`) |
|---|---|---|---|
| **Binary** | `/usr/bin/nfqws` | `/usr/bin/nfqws2` | `/usr/bin/ciadpi` |
| **Operating Model** | Kernel NFQueue Intercept | Kernel NFQueue Multi-Q | Local SOCKS5 / TProxy |
| **Target Protocols** | HTTP, TLS (ClientHello) | HTTP, TLS, QUIC, WireGuard | HTTP, TLS |
| **Packet Splitting** | `split2`, `disorder`, `fake` | `multisplit`, `seqovl`, `wsize`, `fake` | `--split-pos`, `--disorder`, `--fake` |
| **Multi-Vector Chains** | Single strategy per rule | Multi-phase composite chains | Composite SOCKS args |
| **CPU Overhead** | Minimal (< 1%) | Low (< 2%) | Low (< 2%) |
| **Best For** | Legacy OpenWrt, Basic DPI | YouTube 4K, Discord, TSPU | Non-root users, SOCKS routing |
| **Исполняемый файл** | `/usr/bin/nfqws` | `/usr/bin/nfqws2` | `/usr/bin/ciadpi` |
| **Модель работы** | Перехват через Kernel NFQueue | Multi-Queue NFQueue с Lua | Локальный SOCKS5 / TProxy |
| **Целевые протоколы** | HTTP, TLS (ClientHello) | HTTP, TLS, QUIC, WireGuard, UDP | HTTP, TLS |
| **Методы фрагментации** | `split2`, `disorder`, `fake` | `multisplit`, `seqovl`, `wsize`, `fake` | `--split-pos`, `--disorder`, `--fake` |
| **Многоуровневые цепочки** | 1 стратегия на правило | Сложные составные цепочки | Составные аргументы SOCKS |
| **Нагрузка на CPU** | Минимальная (< 1%) | Низкая (< 2%) | Низкая (< 2%) |
| **Оптимально для** | Базового DPI, старых роутеров | YouTube 4K, Discord, ТСПУ | Не-root окружений, SOCKS-роутинга |
---
## 2. Desynchronization Techniques Explained
## 2. Принципы и техники десинхронизации пакетов
Deep Packet Inspection (DPI) systems inspect packet headers (such as TLS Server Name Indication `SNI` or HTTP `Host` headers) to detect and block access. Desynchronization tricks the DPI into losing track of the connection state while the destination server reconstructs the stream normally.
Системы глубокого анализа пакетов (DPI / ТСПУ) анализируют заголовки сетевых протоколов (такие как `SNI` в расширении TLS ClientHello или заголовок `Host` в HTTP) для блокировки или замедления трафика.
Десинхронизация обманывает конечный автомат DPI, заставляя его потерять контекст TCP-сессии или пропустить целевой заголовок, в то время как целевой сервер корректно собирает исходный поток данных.
```
Original Stream: [TLS ClientHello with SNI] ──────────► (Blocked by DPI)
Исходный поток: [TLS ClientHello с SNI] ──────────► (Блокируется ТСПУ / DPI)
Desynchronized: [Fake Bad Checksum Packet] ──────────► (DPI resets state)
[Payload Part 1: Snippet] ──────────► (DPI misses SNI)
[Payload Part 2: Remainder] ─────────► (Server merges stream)
Десинхронизация: [Fake-пакет с неверной суммой/TTL] ──► (DPI сбрасывает состояние)
[Фрагмент 1: Начало ClientHello] ───► (DPI не видит полный SNI)
[Фрагмент 2: Окончание данных] ─────► (Сервер собирает TCP-поток)
```
### 2.1. Key Desync Strategies
### 2.1. Основные стратегии обхода
1. **`split2` / `multisplit`**:
* Splits the TCP segment right inside the TLS SNI or HTTP Host header. The DPI does not reassemble small fragments, while the end server's TCP stack reconstructs the full buffer seamlessly.
2. **`disorder` / `disorder2`**:
* Sends the second half of the packet before the first half with appropriate TCP sequence numbers. The DPI sees out-of-order data and skips inspection.
3. **`fake` / `fake_sni`**:
* Sends a fake TLS ClientHello packet with a low TTL (Time To Live). The DPI intercepts the fake packet and approves the connection; the packet dies before reaching the destination server.
4. **`seqovl` (Sequence Overlap)**:
* Sends a fake packet with overlapping sequence numbers that the server's TCP stack discards while the DPI's state machine is fooled.
5. **`wsize` (Window Size Manipulation)**:
* Forces a small TCP window size to prevent DPI from receiving full payloads in single bursts.
1. **`split2` / `multisplit` (Многопозиционное разделение)**:
* Разрезает TCP-сегмент непосредственно внутри поля TLS SNI или заголовка HTTP Host. Оборудование DPI не выполняет глубокую реассемблинг-сборку мелких фрагментов, а стек TCP целевого сервера склеивает поток без потерь.
2. **`disorder` / `disorder2` (Изменение порядка доставки)**:
* Отправляет вторую часть пакета раньше первой с корректными TCP Sequence Numbers. DPI видит фрагменты не по порядку и пропускает инспекцию.
3. **`fake` / `fake_sni` (Внедрение фейковых пакетов)**:
* Отправляет поддельный пакет TLS ClientHello с намеренно заниженным TTL (Time To Live). DPI перехватывает поддельный пакет и считает соединение легитимным, после чего пакет угасает в сети, не доходя до целевого сервера.
4. **`seqovl` (Наложение порядковых номеров / Sequence Overlap)**:
* Посылает пакет с перекрывающимся диапазоном TCP Sequence. Стек TCP на сервере отбрасывает дублирующиеся байты, тогда как DPI парсит неверные данные и теряет контроль над сессией.
5. **`wsize` (Манипуляция размером окна TCP Window Size)**:
* Принудительно устанавливает размер TCP-окна в 1–2 байта, заставляя клиент слать данные микросегментами, что ломает эвристики DPI.
---
## 3. Configuration & Runtime Management
## 3. Конфигурация и управление в UCI
### 3.1. Zapret v2 Configuration Example (`/etc/config/tachyon`)
### 3.1. Пример настройки Zapret v2 (`/etc/config/tachyon`)
```ini
config provider 'zapret2'
@@ -68,7 +70,7 @@ config rule 'youtube_rule'
list domain_pattern 'discord.com'
```
### 3.2. ByeDPI Configuration Example
### 3.2. Пример настройки ByeDPI
```ini
config provider 'byedpi'
@@ -81,42 +83,54 @@ config provider 'byedpi'
---
## 4. NFQueue Multiplexing & Conflict Prevention
## 4. Мультиплексирование NFQueue и изоляция очередей
* Kernel `nfnetlink_queue` requires unique queue numbers per daemon instance.
* Tachyon's `providers/nfqueue/runtime.uc` dynamically manages queue allocation:
* Default Zapret v1 queue: `200`
* Default Zapret v2 queue: `201`
* If both Zapret v1 and v2 are enabled simultaneously for different rules, Tachyon enforces strict queue isolation and prevents PID collisions.
* Подсистема ядра Linux `nfnetlink_queue` требует уникальный номер очереди (`qnum`) для каждого запущенного процесса демона.
* Модуль `providers/nfqueue/runtime.uc` в Tachyon динамически управляет выделением очередей:
* Базовая очередь Zapret v1: `200`
* Базовая очередь Zapret v2: `201`
* Очередь Strategy Fuzzer: `298` / `299`
* При одновременной активации Zapret v1 и Zapret v2 для разных правил маршрутизации Tachyon гарантирует строгую изоляцию очередей и исключает конфликты PID и fwmark.
## 4. AmneziaWG в sing-box-extended: верификация (2026-08)
---
Проверено против бинарника релиза `v1.13.18-extended-2.6.5` (shtorm-7/sing-box-extended):
## 5. Интеграция AmneziaWG в sing-box-extended (2026)
- `endpoint.amnezia` полностью реализован: `AmneziaOptions` (`transport/wireguard/endpoint_options.go`)
→ IPC `jc/jmin/jmax/s1-s4/h1-h4/i1-i5` (`transport/wireguard/endpoint.go`)
→ wireguard-go форк `shtorm-7/wireguard-go v0.0.4-extended-1.5.3`:
I1-I5 шлются отдельными пакетами ПЕРЕД handshake initiation
(`device/send.go SendHandshakeInitiation`), формат значения — hex-строка.
- Парсер конфига строгий: неизвестные поля и мусорные значения в `amnezia.*`
дают FATAL при старте, «молчаливого игнорирования» не существует.
- Генерация Tachyon (`generator_outbounds.uc add_awg_endpoint`) совпадает со
схемой форка: peer содержит required `allowed_ips`, `pre_shared_key` и
`persistent_keepalive_interval` опциональны, hex i1-i5 проходит
`uci_bin_to_hex` без двойного кодирования.
Проверено против релизного бинарника `v1.13.18-extended-2.6.5` (`shtorm-7/sing-box-extended`):
Следствие для диагностики: если AWG/WARP-туннель «TX есть, RX нет» на
sing-box-extended, конфиг секции применён корректно — причина вне Tachyon
(сервер, провайдер, UDP-фильтрация). Чек 6c доктора (1.2.91+) сообщает это
пользователю по свидетельствам из лога ядра.
- Секция `endpoint.amnezia` полностью реализована в форке: `AmneziaOptions` (`transport/wireguard/endpoint_options.go`) → параметры IPC `jc / jmin / jmax / s1-s4 / h1-h4 / i1-i5`.
- Форк `shtorm-7/wireguard-go v0.0.4-extended-1.5.3`: пакеты `I1–I5` отправляются отдельными дейтаграммами **перед** инициализацией рукопожатия (`SendHandshakeInitiation`), значение задается в hex-формате.
- Генератор Tachyon (`singbox/generator_outbounds.uc` -> `add_awg_endpoint`) формирует конфигурацию, полностью совместимую со схемой форка:
- Секция `peer` содержит обязательный `allowed_ips`.
- Параметры `pre_shared_key` и `persistent_keepalive_interval` опциональны.
- Hex-значения `i1–i5` передаются через `uci_bin_to_hex` без повторного кодирования.
- **Диагностика:** если AWG/WARP-туннель имеет состояние «TX есть, RX нет» на sing-box-extended, конфиг применен корректно — причина во внешней UDP-фильтрации провайдера или блокировке сервера.
Кейс «kernel работает, sing-box нет» с идентичным conf остаётся внешним:
различие в реализации special-handshake между amneziawg-linux kernel-модом
и userspace-форком может быть критично только для конкретных строгих
серверов. Шаги диагностики для таких случаев:
---
1. `tcpdump -i any -X udp port <порт>` — сравнить первые байты I1-пакетов
kernel vs sing-box (у special-handshake пакетов префикс `c7`).
2. Временно убрать i1-i5 из секции: если handshake поднимется — сервер
не требует special handshake, а требует его некорректную передачу.
3. Попробовать вариант ядра sing-box-lx как эксперимент.
## 6. Strategy Fuzzer и автоматический подбор стратегий
Tachyon включает встроенный модуль автоматического тестирования стратегий обхода — **Strategy Fuzzer & Auto-Tuner** (`diagnostics/fuzzer.uc`), который избавляет от необходимости вручную подбирать флаги `nfqws2` или `ciadpi`.
### 6.1. Механизм работы
- **Изолированный сэндбокс:** Тестирование выполняется через временные очереди `qnum 298/299` с сокетной меткой `0x08000000` (для Zapret) либо через локальный порт `127.0.0.1:11089` (для ByeDPI), не затрагивая активный домашний трафик.
- **Метрический скоринг:** Замеряются время TLS-рукопожатия, TTFB (время до первого байта), битрейт загрузки чанка потокового видео (MB/s) и HTTP-код ответа.
- **1-Click Apply:** Победившая стратегия мгновенно применяется к правилу YouTube/Discord или в глобальные параметры провайдера с автоматической перезагрузкой службы.
### 6.2. Команды управления через CLI
```sh
# Запуск бенчмарка стратегий
tachyon fuzzer_start <engine> <target> [custom_url] [rule_section]
# Просмотр текущего прогресса и результатов
tachyon fuzzer_status
# Остановка фонового бенчмарка
tachyon fuzzer_stop
# Применение выбранной стратегии в UCI
tachyon fuzzer_apply <engine> "<strategy_args>" [target_rule_or_global]
# Вывод доступной матрицы стратегий
tachyon fuzzer_strategies
```