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:
164
docs/manual.md
164
docs/manual.md
@@ -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`.
|
||||
|
||||
|
||||
@@ -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 код. Их надо читать.
|
||||
|
||||
Reference in New Issue
Block a user