Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-13 22:03:09 +00:00

update docs

This commit is contained in:
bol-van
2025-12-26 14:28:43 +03:00
parent 6077d363ec
commit f458a76880
2 changed files with 101 additions and 101 deletions

View File

@@ -25,11 +25,11 @@
- [Отладка](#отладка)
- [Виртуальные машины](#виртуальные-машины)
- [Песочница](#песочница)
- [Вызов LUA кода](#вызов-lua-кода)
- [Вызов Lua кода](#вызов-lua-кода)
- [Передача блобов](#передача-блобов)
- [Внутрипрофильные фильтры](#внутрипрофильные-фильтры)
- [Типичная схема вызова инстансов внутри профиля](#типичная-схема-вызова-инстансов-внутри-профиля)
- [Прототип LUA функции](#прототип-lua-функции)
- [Прототип Lua функции](#прототип-lua-функции)
- [Структура таблицы desync](#структура-таблицы-desync)
- [Структура диссекта](#структура-диссекта)
- [Особенности приема многопакетных пейлоадов](#особенности-приема-многопакетных-пейлоадов)
@@ -264,9 +264,9 @@ zapret2 является пакетным манипулятором, основ
Главный компонент zapret2 - программа [nfqws2](#nfqws2) (dvtws2 на BSD, winws2 на Windows), написанная на C, которая и является пакетным манипулятором.
Содержит функции по перехвату пакетов, базовой [фильтрации](#использование-множественных-профилей), рапознавания основных протоколов и пейлоадов, поддержки хост и IP [листов](#фильтрация-по-листам), [автоматических](#детектор-неудач-автохостлистов) хостлистов
с распознаванием блокировок, систему множественных [профилей](#использование-множественных-профилей) (стратегий), возможности по [отсылке](#прием-и-отсылка-пакетов) raw пакетов и другие сервисные функции.
Однако, там нет никаких возможностей собственно для воздействия на трафик. Это вынесено в код на языке LUA, вызываемый из [nfqws2](#nfqws2).
Однако, там нет никаких возможностей собственно для воздействия на трафик. Это вынесено в код на языке Lua, вызываемый из [nfqws2](#nfqws2).
Поэтому следующая по важности часть проекта - LUA код. В базовый комплект входит библиотека функций-хелперов [zapret-lib.lua](#библиотека-базовых-функций-zapret-liblua), библиотека программ автономных атак на DPI [zapret-antidpi.lua](#библиотека-программ-атаки-на-dpi-zapret-antidpilua), библиотека функций принятия динамических решений (оркестрации) [zapret-auto.lua](#библиотека-программ-автоматизации-и-оркестрации-zapret-autolua).
Поэтому следующая по важности часть проекта - Lua код. В базовый комплект входит библиотека функций-хелперов [zapret-lib.lua](#библиотека-базовых-функций-zapret-liblua), библиотека программ автономных атак на DPI [zapret-antidpi.lua](#библиотека-программ-атаки-на-dpi-zapret-antidpilua), библиотека функций принятия динамических решений (оркестрации) [zapret-auto.lua](#библиотека-программ-автоматизации-и-оркестрации-zapret-autolua).
Дополнительно присутствует набор тестов C функций `zapret-tests.lua`, средство обфускации wireguard протокола `zapret-wgobfs.lua` и средство записи дампа пакетов в cap файлы `zapret-pcap.lua`.
Функции перенаправления трафика из ядра в [Linux](#перехват-трафика-в-ядре-linux) возложены на [iptables](#перехват-трафика-с-помощью-iptables) и [nftables](#перехват-трафика-с-помощью-nftables), в [FreeBSD](#перехват-трафика-в-ядре-freebsd) - на [ipfw](#перехват-трафика-в-ядре-freebsd), в [OpenBSD](#перехват-трафика-в-ядре-openbsd) - на [pf](#перехват-трафика-в-ядре-openbsd), в [Windows](#перехват-трафика-в-ядре-windows) - встроены в сам процесс winws2 посредством драйвера windivert.
@@ -322,40 +322,40 @@ conntrack отслеживает логическое направление п
и при необходимости переключение профиля. Таких переключений может быть за время существования потока до двух, поскольку есть лишь 2 изменяемых параметра.
Профиль выбран. Из чего состоит его содержание, отвечающее за действия ?
За действия отвечают LUA функции. В профиле их может быть произвольное количество.
Каждый вызов LUA функции из профиля называется инстансом. Функция может быть одна, вызовов несколько - с разными параметрами.
За действия отвечают Lua функции. В профиле их может быть произвольное количество.
Каждый вызов Lua функции из профиля называется инстансом. Функция может быть одна, вызовов несколько - с разными параметрами.
Поэтому и применяется понятие инстанса - экземпляра вызываемой функции, который идентифицируется номером профиля и порядковым номером вызова внутри профиля.
Инстансы вызываются через параметры `--lua-desync`. Каждый инстанс получает набор произвольных параметров, задаваемых в `--lua-desync`.
Порядок вызовов имеет принципиальное значение для логики стратегии и выполняется строго в порядке задания параметров `--lua-desync`.
Присутствуют и [внутипрофильные фильтры](#внутрипрофильные-фильтры). Их 3 типа - фильтр `--payload` - список принимаемых инстансом пейлоадов, и 2 диапазонных фильтра `--in-range` и `--out-range`,
позволяющих задать диапазон позиций внутри потока, который интересен для инстанса. Внутрипрофильные фильтры после их определения действуют на все последующие инстансы
до их переопределения. Главный смысл наличия внутрипрофильных фильтров - сократить число относительно медленных вызовов LUA , принимая максимум решений на стороне C кода.
до их переопределения. Главный смысл наличия внутрипрофильных фильтров - сократить число относительно медленных вызовов Lua , принимая максимум решений на стороне C кода.
Пакет пришел в LUA инстанс. Функция имеет 2 [параметра](#прототип-lua-функции) - ctx и desync. ctx - это контекст для связи с некоторыми функциями на стороне C кода.
Пакет пришел в Lua инстанс. Функция имеет 2 [параметра](#прототип-lua-функции) - ctx и desync. ctx - это контекст для связи с некоторыми функциями на стороне C кода.
[desync](#структура-таблицы-desync) - таблица, содержащая множество параметров обрабатываемого пакета. Прежде всего это [диссект](#структура-диссекта) - подтаблица `dis`.
Информация из записи conntrack - [подтаблица track](#структура-track). Еще целый ряд параметров, который можно увидеть, выполнив [var_debug(desync)](#var_debug) или просто вызвав готовый инстанс [pktdebug](#pktdebug).
Если идет перепроигрывание задержанных пакетов ([replay](#особенности-приема-многопакетных-пейлоадов)), LUA инстанс получает информацию о номере части, количестве частей исходного сообщения, позиции текущей части, [reasm](#особенности-приема-многопакетных-пейлоадов) или [decrypt](#особенности-приема-многопакетных-пейлоадов) при наличии.
Если идет перепроигрывание задержанных пакетов ([replay](#особенности-приема-многопакетных-пейлоадов)), Lua инстанс получает информацию о номере части, количестве частей исходного сообщения, позиции текущей части, [reasm](#особенности-приема-многопакетных-пейлоадов) или [decrypt](#особенности-приема-многопакетных-пейлоадов) при наличии.
LUA код может использовать глобальное пространство переменных для хранения данных, не относящихся к конкретному обрабатываемому пакету. Ему доступна таблица [desync.track.lua_state](#структура-track),
в которой он может хранить любую информацию, связанную с записью conntrack. При каждом новом пакете потока в LUA выдается одна и та же таблица.
Lua код может использовать глобальное пространство переменных для хранения данных, не относящихся к конкретному обрабатываемому пакету. Ему доступна таблица [desync.track.lua_state](#структура-track),
в которой он может хранить любую информацию, связанную с записью conntrack. При каждом новом пакете потока в Lua выдается одна и та же таблица.
Таблицу desync можно использовать для генерации и хранения временных данных, актуальных в цепочке обработки текущего пакета.
Следующие LUA инстансы получают ту же таблицу desync и тем самым могут принимать данные от предыдущих инстансов.
Следующие Lua инстансы получают ту же таблицу desync и тем самым могут принимать данные от предыдущих инстансов.
LUA инстанс может создавать копии текущего диссекта, вносить в них изменения, генерировать собственные диссекты, [отправлять](#прием-и-отсылка-пакетов) их через вызовы C кода.
Lua инстанс может создавать копии текущего диссекта, вносить в них изменения, генерировать собственные диссекты, [отправлять](#прием-и-отсылка-пакетов) их через вызовы C кода.
Итогом работы каждого инстанса является вердикт - VERDICT_PASS - не делать ничего с текущим диссектом, VERDICT_MODIFY - в конце всей цепочки отослать модифицированное содержимое диссекта,
VERDICT_DROP - дропнуть текущий диссект. Вердикты всех инстансов аггрегируются - MODIFY замещает PASS, а DROP замещает и PASS, и MODIFY.
LUA инстанс может сам себя отключить от получения дальнейших пакетов потока по направлению in/out - это назвается [instance cutoff](#instance_cutoff).
Может отключить направление in/out текущего потока от всей LUA обработки - [lua cutoff](#lua_cutoff).
Может запросить [отмену](#execution-plan-cancel) всей дальнейшей цепочки вызовов LUA инстансов по текущему диссекту. Инстанс, принимающий такое решение, берет на себя функцию координации дальнейших действий.
Lua инстанс может сам себя отключить от получения дальнейших пакетов потока по направлению in/out - это назвается [instance cutoff](#instance_cutoff).
Может отключить направление in/out текущего потока от всей Lua обработки - [lua cutoff](#lua_cutoff).
Может запросить [отмену](#execution-plan-cancel) всей дальнейшей цепочки вызовов Lua инстансов по текущему диссекту. Инстанс, принимающий такое решение, берет на себя функцию координации дальнейших действий.
Такой инстанс называется оркестратором. Он получает от C кода [план](#execution_plan) дальнейшего выполнения со всеми фильтрами профиля и параметрами вызова всех оставшихся инстансов
и сам принимает решения когда и при каких условиях их вызывать или не вызывать, менять их параметры. Так реализуются динамические сценарии без модификации основных составлящих кода стратегии.
Например, [определение](#детекция-удач-и-неудач) блокировки ресурса и [смена стратегии](#circular), если предыдущая не сработала.
Если все инстансы текущего профиля вошли в состояние cutoff по текущему потоку, либо текущая позиция потока находится за верхней границей range фильтров, значит по этому потоку больше не будет LUA
вызовов. C код помечает такие потоки специальным признаком "lua cutoff", который проверяется максимально быстро без вызовов кода LUA. Тем самым экономятся ресурсы процессора.
Если все инстансы текущего профиля вошли в состояние cutoff по текущему потоку, либо текущая позиция потока находится за верхней границей range фильтров, значит по этому потоку больше не будет Lua
вызовов. C код помечает такие потоки специальным признаком "lua cutoff", который проверяется максимально быстро без вызовов кода Lua. Тем самым экономятся ресурсы процессора.
После выполнения всей цепочки инстансов профиля C код получает итоговый вердикт - что делать с текущим диссектом. Отправить как есть, отправить модифицированный вариант или дропнуть.
@@ -652,7 +652,7 @@ nfqws2 использует стандартный парсер getopt_long_only
--debug=0|1|syslog|android|@<filename> ; писать дебаг лог. 0 - нет , 1 - на консоль, syslog - в unix syslog, android - системный log android, @<filename> - в файл
--version ; вывести версию и выйти
--dry-run ; проверить валидность параметров командной строки и наличие файлов. не проверяет корректность скриптов LUA !
--dry-run ; проверить валидность параметров командной строки и наличие файлов. не проверяет корректность скриптов Lua !
--comment=any_text ; любой текст. игнорируется
--daemon ; отключиться от консоли (демонизироваться)
--pidfile=<filename> ; запись PID в файл
@@ -664,17 +664,17 @@ nfqws2 использует стандартный парсер getopt_long_only
--reasm-disable=[proto[,proto]] ; отключить сборку фрагментов для списка пейлоадов : tls_client_hello quic_initial . без аргумента - отключить reasm для всего.
DESYNC ENGINE INIT:
--writeable[=<dir_name>] ; создать директорию для LUA с разрешением записи и поместить путь к ней в переменную env "WRITEABLE" (только одна директория)
--blob=<item_name>:[+ofs]@<filename>|0xHEX ; загрузить бинарный файл или hex строку в переменную LUA <item_name>. +ofs задает смещение от начала файла
--lua-init=@<filename>|<lua_text> ; однократно при старте выполнить LUA код из строки или из файла
--lua-gc=<int> ; интервал вызова сборщика мусора LUA в секундах. 0 отключает периодический вызов.
--writeable[=<dir_name>] ; создать директорию для Lua с разрешением записи и поместить путь к ней в переменную env "WRITEABLE" (только одна директория)
--blob=<item_name>:[+ofs]@<filename>|0xHEX ; загрузить бинарный файл или hex строку в переменную Lua <item_name>. +ofs задает смещение от начала файла
--lua-init=@<filename>|<lua_text> ; однократно при старте выполнить Lua код из строки или из файла
--lua-gc=<int> ; интервал вызова сборщика мусора Lua в секундах. 0 отключает периодический вызов.
MULTI-STRATEGY:
--new ; начало нового профиля
--skip ; игнорировать профиль
--name=<name> ; установить имя профиля
--template[=<name>] ; использовать профиль как шаблон, задать имя
--cookie[=<string>] ; установить значение LUA переменной "desync.cookie", передаваемое каждому инстансу данного профиля
--cookie[=<string>] ; установить значение Lua переменной "desync.cookie", передаваемое каждому инстансу данного профиля
--import=<name> ; копировать настройки из шаблона в текущий профиль с полным замещением
--filter-l3=ipv4|ipv6 ; фильтр профиля : версия ip протокола
--filter-tcp=[~]port1[-port2]|* ; фильтр профиля : порты tcp или диапазоны портов через запятую
@@ -917,7 +917,7 @@ udp не предполагает понятия соединения, поэт
в серверном (`--server`) - от сервера. Входящим считается противоположное направление.
При указании `--server` направления инвертируются.
[`--in-range`, `--out-range`](#внутрипрофильные-фильтры), а так же признак `desync.outgoing` в LUA функциях
[`--in-range`, `--out-range`](#внутрипрофильные-фильтры), а так же признак `desync.outgoing` в Lua функциях
меняются местами, чтобы соответствовать фактически отсылаемым или принимаемым данным
со стороны сервера. Клиент шлет запросы (http_req) и принимает ответы (http_reply).
Сервер шлет ответы (http_reply) и принимает запросы (http_req).
@@ -960,9 +960,9 @@ Linux conntrack имеет похожий способ определения н
ipcache представляет собой структуру в памяти процесса, позволяющую по ключу IP адреса и имени интерфейса запоминать некоторую информацию,
которую впоследствии можно извлечь и использовать как недостающие данные. На текущий момент это применяются в следующих ситуациях :
1. IP,interface => incoming ttl . Кэшируется TTL/HL первого входящего пакета для последующего применения в LUA функциях (autottl) прямо с первого пакета, когда еще ответа не было.
1. IP,interface => incoming ttl . Кэшируется TTL/HL первого входящего пакета для последующего применения в Lua функциях (autottl) прямо с первого пакета, когда еще ответа не было.
2. IP => hostname . Кэшируется имя хоста, вне привязки к интерфейсу, для последующего поиска профиля с фильтрами по хостлистам и передачи в LUA функции, когда имя хоста еще неизвестно.
2. IP => hostname . Кэшируется имя хоста, вне привязки к интерфейсу, для последующего поиска профиля с фильтрами по хостлистам и передачи в Lua функции, когда имя хоста еще неизвестно.
Режим отключен по умолчанию и включается через параметр `ipcache-hostname`.
Данная техника является экспериментальной. Ее проблема в том, что как такового нет однозначного соответствия между доменом и IP. Множество доменов могут ссылаться на тот же IP адрес.
При коллизии происходит замещение имени хоста на последний вариант.
@@ -985,13 +985,13 @@ ipcache представляет собой структуру в памяти
- `--debug=syslog` вывод в syslog. чтение зависит от syslog daemon. rsyslog пишет файлы в /var/log. busybox logd читается через logread.
- `--debug=android` вывод в android log. чтение через logcat. доступно только в версиях, собранных в Android NDK
Умение обращаться с `--debug` логом совершенно необходимо для отладки настроек и тем более для написания собственного LUA кода.
Умение обращаться с `--debug` логом совершенно необходимо для отладки настроек и тем более для написания собственного Lua кода.
Все сообщения об ошибках (DLOG_ERR) и особо важные сообщения (DLOG_CONDUP) дублируются на консоли вне зависимости от log target.
Сообщения об ошибках выводятся в stderr.
Параметр `--dry-run` позволяет протестировать корректность опций командной строки и доступность используемых файлов под сброшенными привилегиями.
`--dry-run` не инициализирует движок LUA, и поэтому не может обнаружить синтаксические ошибки LUA.
`--dry-run` не инициализирует движок Lua, и поэтому не может обнаружить синтаксические ошибки Lua.
## Виртуальные машины
@@ -1000,7 +1000,7 @@ ipcache представляет собой структуру в памяти
## Песочница
В целях безопасности nfqws2 после инициализации сбрасывает свои привилегии.
Весь LUA код выполняется только после сброса привилегий. Он никогда не получает исходные права.
Весь Lua код выполняется только после сброса привилегий. Он никогда не получает исходные права.
BSD :
@@ -1019,23 +1019,23 @@ Windows :
- Хотя драйвер windivert требует привилегий администратора, после его инициализации процесс winws2 ставит себе low mandatory level.
Это предотвращает доступ на запись практически ко всем файлам и обьектам, защищенным security descriptor.
Процесс больше не может управлять службами и осуществлять привилегированные действия. Однако, группа Administrators остается в токене процесса,
поэтому ничто не предотвращает чтение большинства файлов, если на них есть доступ для Administrators. LUA не имеет встроенных средств
поэтому ничто не предотвращает чтение большинства файлов, если на них есть доступ для Administrators. Lua не имеет встроенных средств
чтения содержимого каталогов, поэтому обнаружение интересующих файлов для злоумышленника затруднено.
- Безвозвратно убираются все Se* привилегии из токена, кроме SeChangeNotifyPrivilege.
- С помощью Job запрещается создание дочерних процессов и ограничивается взаимодействие с десктопом - clipboard, change desktop, change dispay settings и тд
Есть простой способ передать LUA коду каталог, доступный на запись - параметр `--writeable[=<dirname>]`.
nfqws2 создает каталог, назначает на него такие права, чтобы LUA код смог писать туда файлы, передает имя директории в переменной env `WRITEABLE`.
Есть простой способ передать Lua коду каталог, доступный на запись - параметр `--writeable[=<dirname>]`.
nfqws2 создает каталог, назначает на него такие права, чтобы Lua код смог писать туда файлы, передает имя директории в переменной env `WRITEABLE`.
Если dirname не задан, на Windows создается каталог внутри `%USERPROFILE%/AppData/LocalLow`
Со стороны LUA убираются опасные функции - os.execute, io.popen, package.loadlib и модуль debug.
Со стороны Lua убираются опасные функции - os.execute, io.popen, package.loadlib и модуль debug.
На github исполняемые файлы nfqws2 собираются с вариантом luajit без FFI.
## Вызов LUA кода
## Вызов Lua кода
LUA код вызывается в 2 этапа.
Lua код вызывается в 2 этапа.
1. Однократно при запуске программы через `--lua-init=code|@file`. Если значение параметра начинается с `@`, выполняется файл, иначе значение параметра является LUA кодом.
1. Однократно при запуске программы через `--lua-init=code|@file`. Если значение параметра начинается с `@`, выполняется файл, иначе значение параметра является Lua кодом.
2. При обработке профиля через `--lua-desync=function_name:arg1[=val1]:arg2[=val2]:argN[=valN]`.
Сначала идет имя функции, затем через двоеточия аргументы и их значения.
Все значения являются строками. Если значение не задано, оно равно пустой строке.
@@ -1048,16 +1048,16 @@ LUA код вызывается в 2 этапа.
### Передача блобов
Блоб - это двоичный блок данных любого размера, который может быть загружен в переменную LUA средствами C кода при старте программы.
Блоб - это двоичный блок данных любого размера, который может быть загружен в переменную Lua средствами C кода при старте программы.
`--blob=<item_name>:[+ofs]@<filename>|0xHEX`
- `item_name` - имя переменной LUA.
- `item_name` - имя переменной Lua.
- `[+ofs]@<filename>` - загрузка из файла со смещения ofs.
- `0xHEX` - загрузка из HEX строки
Прямые операции с файлами из кода LUA не рекомендованы без необходимости.
LUA код выполняется с ограниченными правами, задуманное может не получиться или не работать на разных ОС в разных условиях.
Прямые операции с файлами из кода Lua не рекомендованы без необходимости.
Lua код выполняется с ограниченными правами, задуманное может не получиться или не работать на разных ОС в разных условиях.
Загрузка blob происходит до вхождения в песочницу, поэтому шансов на успех больше.
### Внутрипрофильные фильтры
@@ -1084,9 +1084,9 @@ LUA код выполняется с ограниченными правами,
> [!CAUTION]
> В winws2 по умолчанию включен параметр `--wf-tcp-empty=0`. Он блокирует перехват пустых пакетов с ACK, что позволяет примерно в 2 раза сэкономить на процессоре при интенсивных скачиваниях. Пустые ACK в большинстве стратегий не нужны. Но это же и ломает счетчик "n" - он не будет показывать реальное количество пакетов по соединению. Если вам нужно точное значение, укажите параметр `--wf-tcp-empty=1`. В других системах точность счетчиков напрямую зависит от фильтров перехвата. Счетчик не может и не будет считать то, что не перехватывается.
nfqws2 следит за превышением верхней границы счетчиков для всех LUA инстансов.
nfqws2 следит за превышением верхней границы счетчиков для всех Lua инстансов.
Если во всех инстансах превышена верхняя граница по направлению или инстансы вошли по направлению в состояние cutoff добровольно,
происходит lua cutoff - выключение процессинга LUA в текущем потоке. Это нужно для экономии ресурсов процессора,
происходит lua cutoff - выключение процессинга Lua в текущем потоке. Это нужно для экономии ресурсов процессора,
поскольку проверка единственного bool признака практически не требует никаких ресурсов.
### Типичная схема вызова инстансов внутри профиля
@@ -1108,11 +1108,11 @@ nfqws2 следит за превышением верхней границы с
--lua-desync=multisplit:strategy=2
```
Не суть важно как работают конкретные функции, сейчас важно понять как работают внутрипрофильные фильтры и как передаются параметры LUA инстансам.
Не суть важно как работают конкретные функции, сейчас важно понять как работают внутрипрофильные фильтры и как передаются параметры Lua инстансам.
- Профильный фильтр по tcp портам и типу протокола потока позволяет избежать вызовов LUA на другом трафике.
- Профильный фильтр по tcp портам и типу протокола потока позволяет избежать вызовов Lua на другом трафике.
Профиль вообще не будет задействован, если условия фильтра не выполнятся.
- `--out-range` указан, чтобы отсечь поток от LUA по исходящему направлению после relative sequence (32768+1460) - для экономии процессора.
- `--out-range` указан, чтобы отсечь поток от Lua по исходящему направлению после relative sequence (32768+1460) - для экономии процессора.
Такое значение выбрано из-за специфики функции circular - значение s32768 используется в детекторе успеха как порог срабатывания по умолчанию,
1460 - максимально возможная длина данных в tcp пакете. На Linux может быть не нужно, если используется фильтр connbytes.
- сircular для своей работы требует начальные входящие пакеты потока, а по умолчанию они отключены.
@@ -1122,9 +1122,9 @@ nfqws2 следит за превышением верхней границы с
- Строчка `--lua-desync=fake:blob=fake_default_tls:badsum:strategy=1` вызывает функцию `fake` с 3 аргументами : `blob`, `badsum`, `strategy`.
Значением аргумента `badsum` является пустая строка.
## Прототип LUA функции
## Прототип Lua функции
Стандартная LUA функция имеет прототип
Стандартная Lua функция имеет прототип
`function desync_f(ctx,desync)`
@@ -1514,7 +1514,7 @@ ipv6 extension headers и tcp options представляются в форме
Для quic_initial отдельные пакеты накапливается во внутреннем буфере, после чего происходит их дешифровка, обьединение и дефрагментация разбросанных по пакетам и разным смещениям частей пейлоада (так делает chrome, чтобы заставить всех не упрощать свои алгоритмы, следовать стандартам и уметь корректно собирать пейлоад по частям).
Пока сборка не финализирована, выполняется накопление пакетов во внутреннем буфере без вызовов LUA. Как только она финализирована, происходит перепроигрывание отдельных частей ([replay](#особенности-приема-многопакетных-пейлоадов)). В LUA инстансы приходит диссект каждого задержанного пакета, но при этом устанавливаются поля desync.replay=true, desync.replay_piece, desync.replay_count и desync.replay_piece_last.
Пока сборка не финализирована, выполняется накопление пакетов во внутреннем буфере без вызовов Lua. Как только она финализирована, происходит перепроигрывание отдельных частей ([replay](#особенности-приема-многопакетных-пейлоадов)). В Lua инстансы приходит диссект каждого задержанного пакета, но при этом устанавливаются поля desync.replay=true, desync.replay_piece, desync.replay_count и desync.replay_piece_last.
В случае стандартной tcp сборки выставляется поле desync.reasm_data, содержащее полный блок собранных данных. В desync.dis.payload по-прежнему возвращаются пейлоады отдельных перепроигрываемых пакетов. Для tcp, если нет [replay](#особенности-приема-многопакетных-пейлоадов), desync.reasm_data содержит копию desync.dis.payload.
@@ -1538,8 +1538,8 @@ ipv6 extension headers и tcp options представляются в форме
| hostname | string | имя хоста. определяется на основе анализа L6/L7 протоколов | появляется только после определения |
| hostname_is_ip | bool | является ли hostname ip адресом | только если есть hostname |
| lua_state | table | таблица для хранения состояния, привязанного к потоку | есть всегда, передается с каждым пакетом потока |
| lua_in_cutoff | bool | отсечение LUA от входящего направления | только для чтения |
| lua_out_cutoff | bool | отсечение LUA от исходящего направления | только для чтения |
| lua_in_cutoff | bool | отсечение Lua от входящего направления | только для чтения |
| lua_out_cutoff | bool | отсечение Lua от исходящего направления | только для чтения |
| t_start | number | unix time первого пакета потока | включает дробную часть с высокой точностью |
| pos | table | счетчики по различным направлениям | содержит таблицы client, server, direct, reverse |
@@ -1581,7 +1581,7 @@ mss дублируется в поле `desync.tcp_mss` независимо о
При работе с sequence нужно учитывать их 32-битную беззнаковую природу.
Если к 4294967280 (0xFFFFFFF0) прибавить 100, будет не 4294967380 (0x100000054), а 84 (0x54).
Если вы сложите в LUA эти числа - вы получите 4294967380, потому что там используется представление чисел с разрядностью более 32 и со знаком.
Если вы сложите в Lua эти числа - вы получите 4294967380, потому что там используется представление чисел с разрядностью более 32 и со знаком.
Для операций с sequence и их сравнения рекомендуется использовать C функции u32add и bitand.
Например, выражение `0==bitand(u32add(seq1, -seq2), 0x80000000)` соответствует `seq1>=seq2`.
Но последний простой вариант не будет работать корректно, а первый - будет, если seq1 ушел от seq2 не более, чем на 2 GB.
@@ -1641,7 +1641,7 @@ mss дублируется в поле `desync.tcp_mss` независимо о
| env | Назначение |
| :-------- |:---------- |
| WRITEABLE | Директория, доступная на запись LUA. Результат опции `--writeable` |
| WRITEABLE | Директория, доступная на запись Lua. Результат опции `--writeable` |
| APPDATALOW | (только Windows) Расположение AppData для low mandatory level. Сюда тоже можно записывать, но предпочтительно использовать `--writeable` для кросс-платформенности. |
## C функции
@@ -1672,8 +1672,8 @@ function pton(string_ip)
### Битовые операции
LUA 5.1, на котором основан luajit, не имеет встроенных битовых операций. Luajit имеет встроенный модуль bitop.
LUA 5.3 имеет встроенные битовые операции, но не имеет встроенного модуля bitop. Он может быть подгружен,
Lua 5.1, на котором основан luajit, не имеет встроенных битовых операций. Luajit имеет встроенный модуль bitop.
Lua 5.3 имеет встроенные битовые операции, но не имеет встроенного модуля bitop. Он может быть подгружен,
но только если не использована статическая компиляция и если модуль установлен. nfqws2 на github собирается статически.
При работе с полями сетевых пакетов без битовых операций никуда.
@@ -1682,10 +1682,10 @@ LUA 5.3 имеет встроенные битовые операции, но н
особенно в условиях частого отсутствия FPU на роутерах и других embedded устройствах.
Чтобы не зависеть от всей этой неразберихи, в nfqws2 выставляется свой собственный набор битовых функций и функций сдвига,
который не зависит от типа движка LUA и его версии. Все типы битовых операций работают с беззнаковыми числами от 8 до 32 бит.
который не зависит от типа движка Lua и его версии. Все типы битовых операций работают с беззнаковыми числами от 8 до 32 бит.
При передаче отрицательных чисел они интерпретируются в дополнительном коде. Например, в 32 битах -2 становится 0xFFFFFFFE, в 8 битах - 0xFE.
Большая разрядность не поддерживается, поскольку возникают несовместимости между LUA 5.3+ и более старыми версиями.
Только в LUA 5.3 реализован тип integer 64 bit. В более старых используется формат плавающей точки double с мантиссой 53 бит.
Большая разрядность не поддерживается, поскольку возникают несовместимости между Lua 5.3+ и более старыми версиями.
Только в Lua 5.3 реализован тип integer 64 bit. В более старых используется формат плавающей точки double с мантиссой 53 бит.
Стандартные операции сдвига и побитовые логические операции :
@@ -1726,7 +1726,7 @@ function u32(raw_string, offset)
Эти функции используются для извлечения числовых полей в формате big endian из raw строки.
offset - номер байта от начала raw строки, начиная с 1.
Аналогичные встроенные средства (string.unpack) есть только в LUA 5.3.
Аналогичные встроенные средства (string.unpack) есть только в Lua 5.3.
#### buX
@@ -1767,7 +1767,7 @@ function u32add(u32_1, u32_2, ...., u32_N)
#### divint
Встроенное целочисленное деление есть только в LUA 5.3+, где есть тип данных integer.
Встроенное целочисленное деление есть только в Lua 5.3+, где есть тип данных integer.
Чтобы не возиться с округлением, целочисленное деление реализовано C функцией :
```
@@ -1775,7 +1775,7 @@ function divint(dividend, divisor)
```
В этой функции нет ограничения на разрядность. Внутри используется тип int64_t.
В LUA 5.3+ потерь разрядности нет, в более старых будут искажения чисел, если разрядность операндов или результата превышает размер мантиссы типа double.
В Lua 5.3+ потерь разрядности нет, в более старых будут искажения чисел, если разрядность операндов или результата превышает размер мантиссы типа double.
### Генерация случайных данных
@@ -1807,12 +1807,12 @@ function parse_hex(hex_string)
### Криптография
В LUA есть стандартный модуль биндинга к openssl, откуда можно взять широкий набор криптографических функций.
Но завязываться на внешние модули нельзя - LUA обычно линкуется статически без возможности загрузки внешних модулей.
В Lua есть стандартный модуль биндинга к openssl, откуда можно взять широкий набор криптографических функций.
Но завязываться на внешние модули нельзя - Lua обычно линкуется статически без возможности загрузки внешних модулей.
Не должно быть лишних зависимостей и дополнительных файлов. openssl имеет размер несколько Mb, что критично для embedded систем.
nfqws2 не использует никакие криптобиблиотеки, но имеет минимальный набор криптографических операций для работы с некоторыми протоколами (QUIC).
Эти функции выставляются в LUA и могут использоваться для любых целей.
Эти функции выставляются в Lua и могут использоваться для любых целей.
#### bcryptorandom
@@ -1996,15 +1996,15 @@ function reconstruct_dissect(dissect, reconstruct_opts)
Возвращает raw_ip. Все чексуммы считаются автоматически. L4 чексуммы портятся, если задан badsum в reconstruct_opts.
Реконструкция диссектов с IP фрагментацией происходит особым образом - с участием как LUA, так и C кода.
LUA код должен подготовить диссект полного пакета, подлежащего фрагментации, но заполнить некоторые поля такими, какими они должны быть во фрагменте.
Реконструкция диссектов с IP фрагментацией происходит особым образом - с участием как Lua, так и C кода.
Lua код должен подготовить диссект полного пакета, подлежащего фрагментации, но заполнить некоторые поля такими, какими они должны быть во фрагменте.
- ipv4 : ip.ip_len должен быть рассчитан таким, каким он должен быть во фрагменте.
По ip.ip_len С код определяет размер фрагментированной части.
Поле ip.ip_off должно содержать offset фрагмента и признак IP_MF, если это не последний фрагмент. ip.ip_id должен быть не 0.
- ipv6 : нужно вставить в ip6.exthdr fragment header, в котором заполнить ident, offset и бит IP6F_MORE_FRAG, если это не последний фрагмент.
ip6.ip6_len должен быть рассчитан таким, каким он должен быть во фрагменте. По этой длине C код определяет размер фрагмента.
Позицию fragment header выбирает LUA код. Все, что после fragment header, считается fragmentable part.
Позицию fragment header выбирает Lua код. Все, что после fragment header, считается fragmentable part.
Если C код видит признаки необходимости фрагментации, он проверяет корректность рассчитанных длин и смещений,
и если они корректны, после реконструкции сдвигает содержимое raw пакета в буфере реконструкции, чтобы получился фрагмент с нужными данными.
@@ -2032,7 +2032,7 @@ function csum_tcp_fix(raw_ip_header, raw_tcp_header, payload)
function csum_udp_fix(raw_ip_header, raw_udp_header, payload)
```
Функции для выправления чексумм. Поскольку строки в LUA immutable, они возвращают копию соответствующего заголовка
Функции для выправления чексумм. Поскольку строки в Lua immutable, они возвращают копию соответствующего заголовка
с исправленной чексуммой.
- с csum_ipv4_fix все просто. на входе ip заголовок, на выходе ip заголовок с исправленной суммой
@@ -2061,7 +2061,7 @@ function rawsend_dissect(dissect, rawsend_opts, reconstruct_opts)
function raw_packet(ctx)
```
LUA функции получают готовый диссект текущего пакета при вызове. raw представление требуется редко, поэтому
Lua функции получают готовый диссект текущего пакета при вызове. raw представление требуется редко, поэтому
в целях экономии ресурсов оно не выдается в desync.
Его можно получить по запросу через функцию raw_packet.
@@ -2101,7 +2101,7 @@ function resolve_range(blob,l7payload_type,marker_list[,strict,zero_based_pos])
- resolve_pos работает с единственным маркером. если маркер не ресолвится, возвращается nil.
- resolve_multi_pos работает со списком маркеров через запятую. возвращает массив уникальных абсолютных позиций. если некоторые маркеры не ресолвятся - их не будет в результате.
- resolve_range ресолвит список из ровно 2 маркеров, представляющих собой диапазон внутри пейлоада. Если strict = true, и любой маркер не ресолвится, возвращается nil. Иначе если первый маркер не ресолвится - он заменяется на 0. Если не ресолвится второй маркер - он заменяется на длину пейлоада. Если не ресолвятся оба - возвращается nil.
- если задано zero_based_pos=true, все позиции начинаются с 0, иначе с 1, как это принято в LUA.
- если задано zero_based_pos=true, все позиции начинаются с 0, иначе с 1, как это принято в Lua.
- при невалидных значениях l7payload_type, marker, marker_list, если количество маркеров не равно 2 для resolve_range - вызывается error
### Управление выполнением инстансов
@@ -2178,7 +2178,7 @@ function execution_plan_cancel(ctx)
# Библиотека базовых функций zapret-lib.lua
Почти каждая функция имеет подробные комментарии о своем предназначении и параметрах.
Чтение LUA кода и комментариев позволит лучше понять для чего нужна конкретная функция и как ее вызывать.
Чтение Lua кода и комментариев позволит лучше понять для чего нужна конкретная функция и как ее вызывать.
## Базовые desync функции
@@ -2190,7 +2190,7 @@ function execution_plan_cancel(ctx)
function luaexec(ctx, desync)
```
Выполнить произвольный LUA код, заданный в аргументе "code".
Выполнить произвольный Lua код, заданный в аргументе "code".
Код может адресовать таблицу desync - она временно присваивается глобальной переменной desync,
а по завершению кода глобальная переменная убирается.
@@ -2269,12 +2269,12 @@ function deepcopy(orig)
Копирует переменную orig.
Основная цель - создать копию таблицы со всеми подтаблицами рекурсивно.
Таблицы в LUA передаются по ссылке. Через какую бы переменную вы не изменяли таблицу, таблица существует только одна.
Таблицы в Lua передаются по ссылке. Через какую бы переменную вы не изменяли таблицу, таблица существует только одна.
Изменения будут видны через любые переменные, на нее ссылающиеся.
Чтобы сделать реальную копию, нужно создать новую таблицу и присвоить ей все поля исходной таблицы,
кроме подтаблиц. Подтаблицы надо точно так же копировать рекурсивно. Этим и занимается функция deepcopy.
Простые типы в LUA присваиваются по значению. Все строки хранятся в едином пуле, где исключено дублирование по содержимому.
Простые типы в Lua присваиваются по значению. Все строки хранятся в едином пуле, где исключено дублирование по содержимому.
Строковые переменные ссылаются на пул. Строки менять невозможно, они - immutable, можно только присваивать другие строки.
Если новая строка будет иной по значению, и ее нет в пуле, будет создан новый элемент пула. Иначе будет присвоена ссылка
на существующий элемент.
@@ -2957,11 +2957,11 @@ function replay_execution_plan(desync)
Дополнительные фильтры по направлению и пейлоаду внутри функций anti-dpi сделаны в основном на случай не слишком грамотного написания опций командной строки как дополнительный предохранитель и защита от дурака, чтобы сделать флуд как это было в winws1 с `--dpi-desync-any-protocol` непреднамеренно было непросто.
Другая цель - дать возможность фильтрации по протоколам, о которых C код не знает и которые обнаруживаются LUA детекторами, такими как [detect_payload_str](#detect_payload_str).
Другая цель - дать возможность фильтрации по протоколам, о которых C код не знает и которые обнаруживаются Lua детекторами, такими как [detect_payload_str](#detect_payload_str).
В nfqws2 по умолчанию стоит запрет на передачу входящих (`--in-range=x`), неограниченная передача исходящих (`--out-range=a` ) и пропуск любых пейлоадов (`--payload=all`), что соответствуют поведению nfqws1 с опцией `--dpi-desync-any-protocol`. В nfqws1 все атаки были зашиты в C код, поэтому было известно какие техники работают с какими пейлоадами. Каким-то нужны были любые пакеты, в том числе пустые, а другим - только tls hello или http request.
nfqws2 ничего не знает о том, что нужно `--lua-desync` функциям. Поэтому фильтрация направления и типа пейлоадов ложится целиком на вас. По умолчанию стоит запрет только на входящие, потому что они используются редко, а пользователь может не написать ограничение, и все это пойдет на LUA функции и будет напрасно грузить процессор гигабайтами скачиваемого трафика.
nfqws2 ничего не знает о том, что нужно `--lua-desync` функциям. Поэтому фильтрация направления и типа пейлоадов ложится целиком на вас. По умолчанию стоит запрет только на входящие, потому что они используются редко, а пользователь может не написать ограничение, и все это пойдет на Lua функции и будет напрасно грузить процессор гигабайтами скачиваемого трафика.
### standard direction
@@ -3472,11 +3472,11 @@ function synack_split(ctx, desync)
Стандартный порядок применения инстансов линеен - слева направо с учетом [внутрипрофильных фильтров](#внутрипрофильные-фильтры) и [instance cutoff](#instance_cutoff). nfqws2 никаких других вариантов не предоставляет.
Конечно, вы можете написать свою LUA функцию, которая сделает что нужно и когда нужно. Но вам придется при этом изобрести какое-то количество велосипедов, дублировать код или того хуже - патчить стандартные функции antidpi, добавляя туда ваши хотелки, а потом это самостоятельно поддерживать.
Конечно, вы можете написать свою Lua функцию, которая сделает что нужно и когда нужно. Но вам придется при этом изобрести какое-то количество велосипедов, дублировать код или того хуже - патчить стандартные функции antidpi, добавляя туда ваши хотелки, а потом это самостоятельно поддерживать.
Суть механизмов оркестрации в отделении управляющей логики от логики непосредственных действий, чтобы не надо было ничего патчить, а если и писать свои функции, то писать в них только сам алгоритм управления, не мешая его с алгоритмами действий.
Оркестрация неразрывно связана с понятием [плана выполнения (execution plan)](#execution_plan). Он включает в себя список инстансов, которые нужно вызвать последовательно с их параметрами и [фильтрами](#внутрипрофильные-фильтры). Базовый линейный оркестратор заложен в C код. Но эту роль может взять на себя и LUA функция, в которой можно запрограммировать любую логику.
Оркестрация неразрывно связана с понятием [плана выполнения (execution plan)](#execution_plan). Он включает в себя список инстансов, которые нужно вызвать последовательно с их параметрами и [фильтрами](#внутрипрофильные-фильтры). Базовый линейный оркестратор заложен в C код. Но эту роль может взять на себя и Lua функция, в которой можно запрограммировать любую логику.
Например, можно сделать автоматические стратегии - если одна не работает, использовать другую. C код имеет подобную логику только в механизме [автоматических хостлистов](#фильтрация-по-листам). Но она не реализует динамическую смену стратегий.
@@ -3682,7 +3682,7 @@ stopif может быть полезен как вложенный оркест
### iff функции
Они используются в нескольких оркестраторах. Берут desync в качестве параметра.
Могут содержать любую логику, которую можно запрограммировать на LUA. В базовом комплекте есть несколько iff функций для демонстрации возможностей и тестирования.
Могут содержать любую логику, которую можно запрограммировать на Lua. В базовом комплекте есть несколько iff функций для демонстрации возможностей и тестирования.
#### cond_true
@@ -3819,7 +3819,7 @@ blockcheck2 по умолчанию работает в интерактивно
`/opt/zapret2/blockcheck2.sh | tee /tmp/blockcheck2.log`
В [win bundle](https://github.com/bol-van/zapret-win-bundle) можно пользоваться cygwin prompt (`cygwin/cygwin-admin.cmd`). Там уже созданы alias-ы для запуска blockcheck из первой версии zapret, blockcheck2, winws, winws2 с подключенными стандартными LUA скриптами. Это удобно, потому что не нужно думать о путях и каждый раз писать или вставлять откуда-то огромный текст, тем боллее при наличии национальных символов и пробелов в путях, путаясь в экранировании символов и кодировках.
В [win bundle](https://github.com/bol-van/zapret-win-bundle) можно пользоваться cygwin prompt (`cygwin/cygwin-admin.cmd`). Там уже созданы alias-ы для запуска blockcheck из первой версии zapret, blockcheck2, winws, winws2 с подключенными стандартными Lua скриптами. Это удобно, потому что не нужно думать о путях и каждый раз писать или вставлять откуда-то огромный текст, тем боллее при наличии национальных символов и пробелов в путях, путаясь в экранировании символов и кодировках.
Возможно последовательное тестирование нескольких доменов. Для этого нужно задать их через пробел.
@@ -4134,7 +4134,7 @@ nfqws2 может работать и самостоятельно без скр
- По стандартным режимом nfqws2 понимается то, что запускается с параметрами `NFQWS2_OPT` при включении `NFQWS2_ENABLE`. В противовес [custom скриптам](#custom-скрипты), откуда могут запускаться нестандартные, кастомные, инстансы nfqws2.
- netifd интерфейсы - это то, что видно в `/etc/config/network` или в Luci, и что берет команда ifstatus. Не являются интерфейсами Linux. Интерфейсы Linux указываются в параметре device в определении интерфейса и видны по команде `ip link`. Например, интерфейс netifd - "lan", интерфейс Linux - "br-lan". В OPENWRT_LAN надо вписывать "lan", а не "br-lan", иначе это работать не будет.
- Указание LAN интерфейсов нужно только для flow offloading в nftables, больше ни для чего не используется.
- Параметры командной строки `NFQWS2_OPT` включают только стратегию. Стандартные LUA файлы, служебные параметры типа `--qnum` или `--user` добавляются автоматически. Можно добавлять свои `--blob` или `--lua-init`.
- Параметры командной строки `NFQWS2_OPT` включают только стратегию. Стандартные Lua файлы, служебные параметры типа `--qnum` или `--user` добавляются автоматически. Можно добавлять свои `--blob` или `--lua-init`.
- `NFQWS2_OPT` берет маркеры `<HOSTLIST>` и `<HOSTLIST_NOAUTO>`. Это подстановка стандартных листов. Маркеры замещаются на параметры `--hostlist` и `--hostlist-auto` в зависимости от режима `MODE_FILTER`. `<HOSTLIST_NOAUTO>` добавляет автохослист как обычный лист без авто. В параметры вписываются только те файлы стандартных листов, которые по факту есть. Маркеры могут вписываться в разные профили, и только вы можете знать куда их вписывать , а куда нет, исходя из логики ваших стратегий.
- Прямое указание параметров в `NFQWS2_OPT` типа `--hostlist=/opt/zapret2/ipset/zapret-hosts-user.txt` крайне не приветствуется, поскольку ломает логику `MODE_FILTER` и скриптов получения листов - их результат может не быть учтен.
- Класть свои файлы в `/opt/zapret2` чревато тем, что их снесет инсталятор при обновлении zapret2. Используете расположение вне каталога zapret2.
@@ -4325,7 +4325,7 @@ do_nfqws()
# $3 - параметры nfqws2
```
Запуск или останов инстанса nfqws2. Базовые параметры приписываются автоматически. К базовым параметрам относится выбор user, fwmark и подключение стандартных скриптов LUA - [zapret-lib.lua](#библиотека-базовых-функций-zapret-liblua), [zapret-antidpi.lua](#библиотека-программ-атаки-на-dpi-zapret-antidpilua), [zapret-auto.lua](#библиотека-программ-автоматизации-и-оркестрации-zapret-autolua).
Запуск или останов инстанса nfqws2. Базовые параметры приписываются автоматически. К базовым параметрам относится выбор user, fwmark и подключение стандартных скриптов Lua - [zapret-lib.lua](#библиотека-базовых-функций-zapret-liblua), [zapret-antidpi.lua](#библиотека-программ-атаки-на-dpi-zapret-antidpilua), [zapret-auto.lua](#библиотека-программ-автоматизации-и-оркестрации-zapret-autolua).
Номер очереди вы должны указать сами в `--qnum`.

View File

@@ -36,12 +36,12 @@ zapret2 является дальнейшим развитием проекта
или хотя бы область , в которой их можно искать, плюс владеющий базовыми навыками программирования.
*nfqws2* оставляет в себе практически тот же функционал - распознавание протоколов, реассемблинг, дешифровка, управление профилями, хостлисты, ipset-ы, базовая фильтрация.
Но он полностью лишается возможностей самостоятельно воздействовать на трафик. Часть "дурения" переносится в скриптовой язык программирования LUA.
Но он полностью лишается возможностей самостоятельно воздействовать на трафик. Часть "дурения" переносится в скриптовой язык программирования Lua.
LUA код получает от C кода структурированное представление приходящих пакетов в виде дерева (диссекты), подобного тем, что вы видите в wireshark.
Lua код получает от C кода структурированное представление приходящих пакетов в виде дерева (диссекты), подобного тем, что вы видите в wireshark.
Туда же приходят результаты сборки или дешифровки частей некоторых протоколов (tls, quic).
С код предоставляет функции-хелперы, позволяющие отсылать пакеты, работать с двоичными данными, разбирать TLS, искать маркер-позции и т.д.
Имеется библиотека хелперов, написанных на LUA, а так же готовая библиотека программ атаки на DPI (стратегий), реализующая функции *nfqws1* в расширенном варианте
Имеется библиотека хелперов, написанных на Lua, а так же готовая библиотека программ атаки на DPI (стратегий), реализующая функции *nfqws1* в расширенном варианте
и с большей гибкостью.
Вы всегда сможете взять и дописать что-то свое. В этом и есть смысл, чтобы борьбой с DPI смог заняться любой, кто разбирается в пакетах.
@@ -53,7 +53,7 @@ zapret2 - инструмент для таких энтузиастов. Но э
## С чего начать
Хотелось бы избежать [талмуда](manual.md) на главной странице. Поэтому начнем со способа запуска *nfqws2* и описания способов портирования стратегий *nfqws1* - как в *nfqws2* сделать то же самое, что можно было в *nfqws1*.
Когда вы поймете как это работает, вы можете посмотреть LUA код, находящийся "под капотом". Разобрать как он работает, попробовать написать что-то свое.
Когда вы поймете как это работает, вы можете посмотреть Lua код, находящийся "под капотом". Разобрать как он работает, попробовать написать что-то свое.
"талмуд" обязательно будет, как он есть у любых более-менее сложных проектов. Он нужен как справочник.
### Механика обработки трафика
@@ -102,11 +102,11 @@ nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-antidpi.
--payload=tls_client_hello,http_req --lua-desync=multisplit:pos=1:seqovl=5:seqovl_pattern=0x1603030000
```
Данный пример предполагает, что в той же директории находятся файлы `zapret-lib.lua` - библиотека хелперов на LUA и `zapret-antidpi.lua` - библиотека базовых стратегий.
`--lua-init` может содержать LUA код в виде строки. Так удобно писать простой код, например присвоить константу переменной, чтобы не создавать файлы ради этой мелочи.
Данный пример предполагает, что в той же директории находятся файлы `zapret-lib.lua` - библиотека хелперов на Lua и `zapret-antidpi.lua` - библиотека базовых стратегий.
`--lua-init` может содержать Lua код в виде строки. Так удобно писать простой код, например присвоить константу переменной, чтобы не создавать файлы ради этой мелочи.
Либо подцепляется файл, если значение параметра начинается с `@`. Код из `--lua-init` выполняется 1 раз при старте.
Далее указаны параметры `--lua-desync`. Они содержат имя LUA функции, вызываемой при обработке каждого пакета, проходящего через профиль мультистратегии.
Далее указаны параметры `--lua-desync`. Они содержат имя Lua функции, вызываемой при обработке каждого пакета, проходящего через профиль мультистратегии.
После двоеточия и через двоеточия следуют параметры для данной функции в формате `param[=value]`. В примере реализована стратегия
```
@@ -122,7 +122,7 @@ nfqws --qnum 200 --debug \
Тип пейлоада - тип данных, содержащихся в пакете или группе пакетов. Например, протокол соединения может быть tls, а пейлоады - tls_client_hello, tls_server_hello, unknown.
Другое важное отличие - отсутствие жестко определенных фаз десинхронизации. То, что вы раньше писали как `fake,multisplit` реализуется двумя
последовательно вызываемыми LUA функциями. Их может быть столько, сколько нужно, учитывая логику прохождения пакетов и операций с ними, и у каждой могут быть свои параметры.
последовательно вызываемыми Lua функциями. Их может быть столько, сколько нужно, учитывая логику прохождения пакетов и операций с ними, и у каждой могут быть свои параметры.
Может даже несколько раз вызываться одна и так же функция с разными параметрами. Так, например, можно послать несколько фейков, причем с разными фулингами.
Конкретный вызов `--lua-desync` функции называется инстансом. Инстанс - это связка имени функции, номера вызова внутри профиля и номера самого профиля.
Это похоже на одну программу, которую можно запустить много раз с разными параметрами.
@@ -130,11 +130,11 @@ nfqws --qnum 200 --debug \
Другое немаловажное отличие - поддержка автоматической tcp сегментации средствами `zapret-lib.lua`. Вам больше не нужно думать о размерах отсылаемых tcp пакетов.
По каждому соединению отслеживается MSS. Если пакет не влезает в MSS, выполняется сегментация.
Например, это может случиться при отправке tls фейка с kyber. Или если вы режете kyber tls так, что одна из частей получается размером 1600 байт,
что, очевидно, не влезает в MTU. Или если вы задали seqovl=10000. В *nfqws1* такое значение вызвало бы ошибку. Функция LUA `rawsend_dissect_segmented` отправит
что, очевидно, не влезает в MTU. Или если вы задали seqovl=10000. В *nfqws1* такое значение вызвало бы ошибку. Функция Lua `rawsend_dissect_segmented` отправит
несколько tcp сегментов с начальным sequence -10000 общим размером 10000 байт, в последнем из которых будет кусок оригинального сообщения.
В *nfqws2* нет жестко зашитых параметров кастомных фейков типа `--dpi-desync-fake-tls`, `dpi-desync-fake-http` и тд.
Вместо них есть блобы. Блоб (blob) - это переменная LUA типа *string*, содержащая блок двоичных данных произвольной длины. От 1 байта до гигабайтов.
Вместо них есть блобы. Блоб (blob) - это переменная Lua типа *string*, содержащая блок двоичных данных произвольной длины. От 1 байта до гигабайтов.
*nfqws2* автоматически инициализирует блобы со стандартными фейками tls, http, quic, как это и было в *nfqws1*.
Блобы могут быть заданы как hex-строка прямо в параметре desync функции, либо пред-загружены при старте с помощью параметра `--blob=name:0xHEX|[+ofs]@filename`
@@ -169,13 +169,13 @@ range задается как `mX-mY`, `mX<mY`, `-mY`, `<mY`, `mX-`.
Что будет, если вы не напишите фильтр `--payload` для fake или multisplit ? В *nfqws1* без `--dpi-desync-any-protocol` они работали только по известным пейлоадам.
В *nfqws2* "any protocol" - режим по умолчанию. Однако, функции из библиотеки `zapret-antidpi.lua` написаны так, что по умолчанию работают только по известным пейлоадам
и не работают по пустым пакетам или unknown - точно так же, как это было в *nfqws1*.
Но лучше все-же писать фильтры `--payload`, потому что они работают на уровне C кода, который выполняется существенно быстрее, чем LUA.
Но лучше все-же писать фильтры `--payload`, потому что они работают на уровне C кода, который выполняется существенно быстрее, чем Lua.
Диссект пакета проходит поочередно по всем `--lua-desync` инстансам профиля, для которых не выполняется условие отсечения (cutoff).
Отсечение может быть по range, payload или добровольное отсечение. Последний вариант - когда инстанс сам отказывается обрабатывать пакеты
по входящему, исходящему или обоим направлениям. Например, задача стратегии wsize - отреагировать только на пакет с tcp флагами SYN,ACK. После этого он не нужен, в коде вызывается функция отсечения.
Это сделано для экономии ресурсов процессора.
Если все инстансы в профиле точно никогда больше не будут вызваны по соединению + направлению - вошли в превышение верхней границы range или выполнили добровольный cutoff, то движок LUA не вызывается вообще.
Если все инстансы в профиле точно никогда больше не будут вызваны по соединению + направлению - вошли в превышение верхней границы range или выполнили добровольный cutoff, то движок Lua не вызывается вообще.
От инстанса к инстансу содержимое диссекта может ими меняться. Следующий инстанс видит изменения предыдущего.
Каждый инстанс выносит свой вердикт - что делать с текущим диссектом. VERDICT_PASS - означает отправить как есть,
@@ -301,21 +301,21 @@ nfqws2 --lua-desync=send:ipfrag:ipfrag_pos_udp=8 --lua-desync=drop
Но это решаемо. А что не решаемо - это перехват вторых частей kyber tls hello. Их невозможно опознать без связи с предыдущими фрагментами. Поэтому перехватывается весь порт.
Для HTTP вопрос решаемый, поскольку там нет реассемблирования запросов, но http сейчас стал настолько редким, что и смысла нет заморачиваться.
Везде расставлены фильтры профиля мультистратегии `--filter-l7`, фильтры по `--out-range` и по `--payload`. Зачем ? В основном для сокращения вызовов LUA кода, который заведомо медленнее C кода.
Если пакет не попадет в профили с LUA - ни о каком вызове кода LUA речи быть не может. Если пакет попал в профиль с LUA, то после первых 10 пакетов с данными наступает отсечение по верхней границе range. Все LUA инстансы входят в состояние instance cutoff, соединение входит в состояние "lua cutoff" по направлению "out". Значит вызовов LUA не будет вообще. Не просто вызовов, а даже обращения к движку LUA с какой-либо целью. Будет только C код, который посмотрит на признак "cutoff" и сразу же отпустит пакет.
Везде расставлены фильтры профиля мультистратегии `--filter-l7`, фильтры по `--out-range` и по `--payload`. Зачем ? В основном для сокращения вызовов Lua кода, который заведомо медленнее C кода.
Если пакет не попадет в профили с Lua - ни о каком вызове кода Lua речи быть не может. Если пакет попал в профиль с Lua, то после первых 10 пакетов с данными наступает отсечение по верхней границе range. Все Lua инстансы входят в состояние instance cutoff, соединение входит в состояние "lua cutoff" по направлению "out". Значит вызовов Lua не будет вообще. Не просто вызовов, а даже обращения к движку Lua с какой-либо целью. Будет только C код, который посмотрит на признак "cutoff" и сразу же отпустит пакет.
Почему именно `-d10` ? Чтобы хватило для отработки большинства вариантов стратегий, учитывая возможные ретрансмиссии и плохую связь. В winws2 по умолчанию включен параметр `--wf-tcp-empty=0`. Он блокирует перехват пустых пакетов с ACK, что позволяет примерно в 2 раза сэкономить на процессоре при интенсивных скачиваниях. Пустые ACK в большинстве стратегий не нужны. Но это же и ломает счетчик "n" - он не будет показывать реальное количество пакетов по соединению. Счетчик "d" работать будет как надо.
Почему нет "-d10" на udp ? Потому что используется windivert фильтр на пейлоад. Счетчики будут считать не реальное количество пакетов в потоке, а количество перехваченных с отфильтрованными пейлоадами. Причем если интервал между ними будет более 1 минуты, то счет будет начинаться заново, поскольку таймаут udp по умолчанию - 60 сек. После таймаута запись conntrack будет удалена. Следующий пакет пойдет как новый поток.
Так же везде расставлены фильтры по payload type. Отчасти так же с целью сократить вызовы LUA даже в пределах первых 10 пакетов с данными.
Так же везде расставлены фильтры по payload type. Отчасти так же с целью сократить вызовы Lua даже в пределах первых 10 пакетов с данными.
С другой стороны, даже при совпадении протокола соединения (`--filter-l7`) может пробежать не интересующий нас пейлоад.
По умолчанию многие функции из `zapret-antidpi.lua` реагируют только на известные типы пейлоада, но не на конкретные, а на любые известные.
Если допустить малореальный, но гипотетически возможный сценарий, что в рамках протокола http будет отправлен блок данных с tls или фраза, похожая на сообщение из xmpp, то тип пейлоада выскочит tls_client_hello или xmpp_stream, например. Лучше от этого сразу уберечься. Тем более что в других видах протоколов - xmpp, например, -
пейлоады могут проскакивать нескольких типов вполне ожидаемо. Но работать надо не по всем.
В фейке для TLS по умолчанию - fake_default_tls - однократно при старте меняется SNI с "www.microsoft.com" на случайный и рандомизируется поле "random" в TLS handshake.
Это делается простой строчкой LUA кода. Больше нет никаких специальных параметров *nfqws2* для модификации пейлоадов.
Это делается простой строчкой Lua кода. Больше нет никаких специальных параметров *nfqws2* для модификации пейлоадов.
В профиле для youtube на лету меняется SNI на "www.google.com", копируется поле TLS "session id" с обрабатываемого в данный момент TLS handshake.
```
@@ -380,9 +380,9 @@ start "zapret: http,https,quic" /min "%~dp0winws2.exe" ^
Надо послать исходный запрос с известным пейлоадом с seqovl случайного размера от 5 до 10 символов со случайным содержимым, состоящим из букв от a до z.
Здесь раскрывается не декларативный характер стратегий, а алгоритмический. Стратегия - это программа, и пишите ее вы на языке программирования.
Для облегчения простых или стандартных действий есть готовые средства, так что далеко не всегда надо писать свою функцию.
Частенько можно обойтись простенькими кусками LUA кода в дополнение к имеющимся.
Частенько можно обойтись простенькими кусками Lua кода в дополнение к имеющимся.
Здесь используется функция `luaexec`, предназначенная для динамического выполнения LUA кода в процессе обработки текущего диссекта.
Здесь используется функция `luaexec`, предназначенная для динамического выполнения Lua кода в процессе обработки текущего диссекта.
Она инициализирует требуемый blob, записывая его в таблицу desync, которая передается от инстанса к инстансу.
Следующий инстанс `tcpseg` использует `rnd` как blob - источник seqovl паттерна.
@@ -413,4 +413,4 @@ nfqws2 \
### Очень важный совет
Научитесь пользоваться `--debug` логом. Без него будет очень сложно понять *nfqws2* на начальном этапе и приспособиться к новой схеме.
Ошибок будет много. Особенно, когда вы начнете писать свой LUA код. Их надо читать.
Ошибок будет много. Особенно, когда вы начнете писать свой Lua код. Их надо читать.