Zapret2: учебный roadmap “как это работает по коду”

Цель: дать простую, но технически точную картину того, что делает zapret2 (nfqws2/winws2) в сетевом стеке, и провести новичка-айтишника от базовых понятий TCP/IP до чтения кода и понимания стратегий lua-desync.

Этот roadmap — не “пресеты для обхода”, а учебная карта: что читать, что потрогать руками, и на какие файлы/функции смотреть, чтобы “в голове сложилось”.

0) Минимальная ментальная модель (в 30 секунд)

Zapret2 — это “перехватчик пакетов”:

  1. ОС/драйвер отдаёт программе сырые пакеты (raw IPv4/IPv6).
  2. zapret2 делает диссекцию (разбирает пакет в структуру: IP/TCP/UDP/payload).
  3. выбирает “профиль” и запускает цепочку Lua-инстансов --lua-desync=...
  4. Lua может:
    • отправить дополнительные пакеты (fake, multisplit, send, …),
    • изменить текущий пакет (pktmodVERDICT_MODIFY),
    • заблокировать текущий (VERDICT_DROP),
    • либо ничего не делать (VERDICT_PASS).

Главная идея анти‑DPI техник: заставить DPI “увидеть” одно, а конечный сервер/клиент — другое, используя различия в разборе, реассемблировании и обработке TCP/IP.

1) Словарь (обязательно выучить)

Если эти слова “не встают на место”, понимание кода будет мучительным:

  • raw packet: байты IPv4/IPv6 пакета как есть.
  • dissect (диссект): таблица/структура вида ip, ip6, tcp, udp, payload.
  • reconstruct (реконструкция): собрать raw-пакет обратно из диссекта.
  • flow / connection (поток/соединение): набор пакетов, которые относятся к одному TCP/UDP обмену.
  • conntrack / track: состояние потока, счётчики и кэш для Lua (desync.track).
  • l7proto: протокол потока (tls/http/quic/…).
  • l7payload: тип полезной нагрузки текущего пакета/группы (tls_client_hello/http_req/quic_initial/…).
  • reasm_data: реассемблированные данные (например, ClientHello в нескольких TCP сегментах).
  • replay: механизм “задержать и переиграть” куски, чтобы сначала запустить Lua и/или собрать reasm.
  • VERDICT_PASS / MODIFY / DROP: решение по текущему перехваченному пакету.
  • instance cutoff: добровольно выключить инстанс (или целый профиль) по направлению, чтобы не грузить CPU дальше.

2) Карта кода (куда смотреть в репозитории)

Опорные файлы/папки, которые дают 80% понимания:

  • nfq2/nfqws.c — “вход” (main), разбор CLI, приём пакетов из NFQUEUE и вызов dpi_desync_packet(...).
  • nfq2/desync.c — ядро обработки пакета: диссекция, выбор профиля, replay/reasm, вызов Lua, вердикт, checksum/fixups.
  • nfq2/protocol.c — распознавание payload’ов и TLS-модификации (TLSMod для tls_mod=...).
  • lua/zapret-lib.lua — библиотека: rawsend, сегментация по MSS, apply_fooling, маркеры resolve_pos, luaexec, argdebug, posdebug.
  • lua/zapret-antidpi.lua — набор “готовых” стратегий: fake, multisplit, multidisorder, …
  • docs/manual.md — справочник по параметрам и механизмам.

3) Уровни обучения (Roadmap)

Ниже — “уровни” как в игре: каждый даёт новую часть картины.

Уровень A — TCP/IP база (без этого всё остальное “в воздухе”)

Что понять:

  • чем отличается IP от TCP/UDP
  • что такое TCP sequence/ack и почему “переупорядочивание” важно
  • что такое MSS/MTU и почему сегментация бывает “двух уровней” (TCP сегменты vs IP фрагменты)
  • что такое checksum и почему badsum влияет на прием

Практика (самое простое):

  • прочитать “TCP header + seq/ack + flags” и объяснить словами, что делает SYN, ACK, RST, URG.

Уровень B — Перехват пакетов: где zapret “сидит”

Задача: понять, что программа стоит “между” сетевым стеком и сетью.

  • Linux: NFQUEUE → userspace → verdict обратно в kernel.
  • Windows: WinDivert → userspace → reinject/modify/drop.

Где смотреть в коде:

  • nfq2/nfqws.c (NFQUEUE callback, передача raw байтов в обработчик)
  • nfq2/desync.c (главный pipeline)

Контрольное понимание:

  1. что такое “перехваченный пакет”
  2. что означает “вердикт DROP” в точке перехвата
  3. почему fake может отправить пакет, но “оригинал” всё равно пойдёт дальше (если его не дропнуть)

Уровень C — Dissect/Reconstruct: “пакет как структура”

Задача: привыкнуть, что пакет в коде — это не “байты”, а структура.

Смотреть:

  • lua/zapret-lib.lua (функции отправки, реконструкции, checksum и т.п.)
  • docs/manual.md разделы про “standard reconstruct” / “rawsend” / “диссекция”

Контрольное понимание:

  • почему VERDICT_MODIFY обычно означает “пересобрать пакет из диссекта”, а не “поправить пару байтов”

Уровень D — Распознавание протоколов и payload’ов

Задача: отличать:

  • --filter-l7=tls (протокол потока)
  • --payload=tls_client_hello (тип текущей полезной нагрузки)

Смотреть:

  • docs/manual.md “Распознавание протоколов”
  • nfq2/protocol.c (логика детектов; TLS/HTTP/QUIC)

Почему это важно: Маркеры (host, midsld, sniext, …) работают только когда запущена правильная “логика понимания payload”.

Уровень E — reasm / replay: “почему иногда нужен кусок будущего”

Задача: понять, зачем reasm_data и почему некоторые payload’ы (например TLS ClientHello) приходят частями.

Смотреть:

  • docs/manual.md про “особенности приема многопакетных пейлоадов”
  • lua/zapret-antidpi.lua: multisplit/multidisorder используют desync.reasm_data если есть

Уровень F — Lua pipeline: что такое --lua-desync

Ключевые мысли:

  • профиль — это цепочка инстансов --lua-desync=... в порядке указания
  • каждый инстанс получает desync (диссект + контекст потока + аргументы)
  • вердикт строится по приоритету DROP > MODIFY > PASS
  • можно резать/ограничивать вызовы через --payload, --out-range, instance_cutoff

Смотреть:

  • docs/manual.md “Вызов Lua кода”
  • lua/zapret-lib.lua: luaexec, argdebug, posdebug

Уровень G — Стратегии (на пальцах + по коду)

Сначала учим 3 опорные техники:

  • fake — отправить ложный пакет (см. [[fake]])
  • multisplit — разрезать payload на сегменты по маркерам (см. [[multisplit]])
  • multidisorder — разрезать и отправить сегменты в обратном порядке (см. [[multidisorder]])

Потом добавляем “слои”:

  • fooling (TTL, tcp_md5, flags…) — чтобы фейки не принимались сервером
  • seqovl — скрытый фейк внутри реального сегмента (на уровне sequence)
  • ipfrag — IP-фрагментация поверх TCP-сегментации

4) Лабораторные (простые упражнения, чтобы “пощупать” код)

Это можно делать даже без глубоких знаний: важно смотреть логи и связывать их с параметрами.

Лаба 1 — увидеть desync живьём

В профиль добавь:

--lua-desync=pktdebug

Цель: увидеть структуру desync (где tcp/ip/payload, где track, где l7payload).

Лаба 2 — увидеть аргументы инстанса

--lua-desync=argdebug:dir=out:payload=tls_client_hello:tcp_md5

Цель: привыкнуть к синтаксису arg1[=val]:flag.

Лаба 3 — увидеть счётчики conntrack и reasm/replay

--lua-desync=posdebug

Цель: понять n/d/b/s/p и где появляется reasm/decrypt/replay.

Лаба 4 — сделать “мини‑эксперимент” через luaexec

--lua-desync=luaexec:code="DLOG('len payload '..#desync.dis.payload)"

Цель: понять, что Lua — это “инструмент”, а не магия: он читает/пишет поля, и всё остальное — отправка/реконструкция.

5) Рекомендованный порядок чтения твоих заметок (индекс)

  1. [[Zapret2 - lua-desync]] (как передаются аргументы и как устроены инстансы)
  2. [[Zapret2 - payload]] (payload types, зачем фильтровать)
  3. [[Zapret2 - out-range]] (ограничение вызовов по фазам потока)
  4. [[Zapret2 - blob]] (как загружать бинарные данные)
  5. [[fake]][[multisplit]][[multidisorder]]

6) Дорожная карта “на 2 недели” (по 30–60 минут в день)

Неделя 1 — “собрать картину”

  1. День 1: словарь + что такое VERDICT_*
  2. День 2: TCP seq/ack + MSS/MTU (почему есть “двойная сегментация”)
  3. День 3: --payload vs --filter-l7
  4. День 4: pktdebug/argdebug/posdebug (смотреть логи)
  5. День 5: fake (понять, почему без DROP это “второй пакет”)
  6. День 6–7: маркеры resolve_pos и идея pos=host,midsld,endhost

Неделя 2 — “читать стратегии как код”

  1. День 8: multisplit (pos + seqovl + nodrop)
  2. День 9: multidisorder (обратный порядок + seqovl‑маркер)
  3. День 10: standard fooling (TTL/MD5/flags/badsum)
  4. День 11: ipfrag (как отдельный слой после сегментации)
  5. День 12: reasm/replay и почему “режем reasm только один раз”
  6. День 13: составить свой “микро‑профиль” из 2–3 --lua-desync и объяснить словами зачем каждый
  7. День 14: ревизия: можешь ли ты по команде --lua-desync=... предсказать “что улетит в сеть” и “что будет с оригиналом”

7) Что сделаем дальше (следующий шаг документации)

Если хочешь, я разверну этот roadmap в набор уроков (несколько файлов):

  • Урок 01: “Пакет → диссект → реконструкция”
  • Урок 02: “payload types и маркеры”
  • Урок 03: “Lua pipeline, инстансы, вердикты”
  • Урок 04: “fake + fooling”
  • Урок 05: “multisplit/multidisorder + seqovl”
  • Урок 06: “ipfrag, MSS и почему порядок важен”

И добавлю “мини‑чеклисты” вроде: “как понять, что сейчас ломает соединение” и “как дебажить стратегию без хаоса”.

Уже добавленные “уроки для новичков”

  • [[Zapret2 - 01 - Сетевой стек для новичков (L2-L7)]]
  • [[Zapret2 - 02 - TCP для новичков (seq/ack, окна, MSS)]]
  • [[Zapret2 - 03 - Перехват пакетов и вердикты (NFQUEUE/WinDivert)]]
  • [[Zapret2 - 04 - Dissect/Reconstruct и структура desync]]
  • [[Zapret2 - 05 - Payload types, reasm/replay и маркеры]]
  • [[Zapret2 - 06 - Lua pipeline: инстансы, args, дебаг]]