diff --git a/docs/manual.md b/docs/manual.md index 9925586..468a5b2 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -3779,6 +3779,8 @@ nfqws2 может работать и самостоятельно без скр | GZIP_LISTS | применять ли сжатие gzip для генерируемых хост и ip листов | | DESYNC_MARK | марк-бит для предотвращения зацикливания | | DESYNC_MARK_POSTNAT | марк-бит для пометки соединений, идущих по схеме POSTNAT | +| FILTER_MARK | если задан, перехватывает пакеты только с этим битом mark. Полезно для организации особых фильтров, например, по ip источника локальной сети. | +| POSTNAT | использовать режим перехвата после NAT на nftables. По умолчанию - 1. На iptables перехват всегда до NAT. | | NFQWS2_ENABLE | включение стандартного режима nfqws2 | | NFQWS2_PORTS_TCP
NFQWS2_PORTS_UDP | порты перехвата для стандартного режима nfqws2 | | NFQWS2_TCP_PKT_OUT
NFQWS2_TCP_PKT_IN
NFQWS2_UDP_PKT_OUT
NFQWS2_UDP_PKT_IN | ограничители connbytes по tcp/udp и направлению для стандартного режима nfqws2 | @@ -3786,7 +3788,7 @@ nfqws2 может работать и самостоятельно без скр | NFQWS2_OPT | параметры командной строки стандартного режима nfqws2 | | MODE_FILTER | режим фильтрации : none,ipset,hostlist,autohostlist | | FLOWOFFLOAD | режим offload : donttouch,none,software,hardware | -| OPENWRT_LAN
OPENWRT_WAN4
OPENWRT_WAN6 | список через пробел lan и wan интерфейсов для ipv4 и ipv6 в OpenWRT. НЕ ИНТЕРФЕЙСЫ Linux, ИНТЕРФЕЙСЫ netifd ! по умолчанию "lan" и "wan"| +| OPENWRT_LAN
OPENWRT_WAN4
OPENWRT_WAN6 | список через пробел lan и wan интерфейсов для ipv4 и ipv6 в OpenWRT. НЕ ИНТЕРФЕЙСЫ Linux, ИНТЕРФЕЙСЫ netifd ! по умолчанию "lan" и "wan" | | IFACE_LAN
IFACE_WAN
IFACE_WAN6 | список через проблем lan и wan интерфейсов для ipv4 и ipv6 в классическом Linux. ИНТЕРФЕЙСЫ Linux ! | | INIT_APPLY_FW | должны ли применять [стартовые скрипты](#стартовые-скрипты) правила firewall | | INIT_FW_PRE_UP_HOOK
INIT_FW_POST_UP_HOOK
INIT_FW_PRE_DOWN_HOOK
INIT_FW_POST_DOWN_HOOK | хук-скрипты, вызываемые до, после поднятия и до, после опускания firewall | @@ -3802,8 +3804,6 @@ nfqws2 может работать и самостоятельно без скр * Прямое указание параметров в `NFQWS2_OPT` типа `--hostlist=/opt/zapret2/ipset/zapret-hosts-user.txt` крайне не приветствуется, поскольку ломает логику `MODE_FILTER` и скриптов получения листов - их результат может не быть учтен. * Класть свои файлы в `/opt/zapret2` чревато тем, что их снесет инсталятор при обновлении zapret2. Используете расположение вне каталога zapret2. - - ## Система ведения листов Располагается в директории ipset и состоит из shell скриптов, которые обслуживают файлы с фиксированными именами внутри этой же директории. @@ -3843,6 +3843,14 @@ ip листы разделяются на ipv4 и ipv6. ipv6 листы имею Берет 1 параметр командной строки. Им может быть "clear" - очистить ipset-ы или "no-update" - загонять только если ipset еще не созданы, не выполнять обновление. +Имена ipset-ов : + +* nozapret, nozapret6 - исключение IP адресов +* zapret, zapret6 - включение IP адресов +* ipban, ipban6 - отдельный включающий список для стороннего перенаправления или проксирования + +ipfw использует set-ы, включающие как ipv4, так и ipv6 адреса, поэтому варианты "6" не применяются. + #### get_config.sh Выполняет скрипт из ipset, заданный в переменной config [GETLIST](#файл-config). Если переменная не задана, выполняет `get_ipban.sh`. @@ -3895,7 +3903,261 @@ IP листы содержат как ipv4, так и ipv6. ## Стартовые скрипты +Имеются только для Linux и OpenWRT. Вариант для Linux - в `init.d/sysv`, для OpenWRT - в `init.d/openwrt`. Основной исполняемый файл - `zapret2`. Требуемое действие передается в аргументе `$1`. Процедура запуска разделена на запуск демонов - процессов nfqws2, и запуск firewall - выставление правил ip/nf tables. + +| Команда ($1) | Действие | +|:-------------|:---------| +| start
stop
restart | запуск/останов/перезапуск демонов и firewall. firewall не запускается, если [INIT_APPLY_FW](#файл-config) не равно 1. На openwrt с fw3 (iptables) firewall запускается отдельно, команды работают только с демонами и не трогают firewall | +| start_daemons
stop_daemons
restart_daemons | запуск/останов/перезапуск демонов | +| start_fw
stop_fw
restart_fw | запуск/останов/перезапуск firewall. На openwrt с fw3 (iptables) команды работают, но firewall запускается отдельно через firewall include в `/etc/config/firewall`. Отдельные операции не рекомендованы. | +| reload_ifsets | (только для nftables) перезагрузка сетов wanif и wanif6 | +| list_ifsets | (только для nftables) показ wanif, wanif6 и flowtable | +| list_table | (только для nftables) показ таблицы zapret2 | + +sysv вариант предназначен для любых Linux, не являющихся OpenWRT. На системах с различными системами запуска все равно работает sysv скрипт, а прикрутка к системам запуска представляет собой лишь адаптер, его запускающий. На системах с неподдерживаемыми системами запуска и на прошивках вы сами должны знать куда прикрутить "zapret2 start" и "zapret2 stop", чтобы работал автостарт и останов в рамках вашей системы запуска. + +### Интеграция с firewall + +Если в ОС используется система управления firewall, между ней и zapret могут произойти конфликты. Чаще всего бывают гоночные состояния - соревнование кто первый заполнит правила или снесет чужие. Это приводит к хаосу - то работает, то не работает, то работает что-то одно, то вообще непонятно что происходит. Гоночные состояния обычно случаются на iptables, потому что там одни таблицы на всех. С nftables проблем обычно не возникает, поскольку каждый использует свою таблицу. Но если вдруг система управления firewall решит снести весь ruleset, это будет тоже гоночное состояние. + +Если случаются гонки или конфликты, то лучший способ решения - синхронизация. Вы отключаете в config [INIT_APPLY_FW](#файл-config), после чего скрипты запуска по команде start перестают запускать firewall и создавать конфликт. Далее вы разбираетесь в своей системе firewall как после поднятия ее правил запустить сторонний скрипт, поднимающий дополнительные правила. Этим скриптом должен быть "zapret2 start_fw". Так же можно прикрутить stop и restart. Либо можно пойти обратным путем - использовать как основу поднятие firewall от zapret и использовать [firewall хуки](#файл-config), в которых дергаются команды по управлению системой управления firewall. Нужно проследить, чтобы система управления firewall не сносила правила zapret. + +Если система управления firewall работает только со своими правилами и крайне плохо уживается со сторонними, можно попробовать отказаться от скриптов запуска и выяснить как прикрутить правила NFQUEUE согласно ее правилам, а демоны запускать отдельно через систему запуска вашего дистрибутива. Если это нежелательно или невозможно, стоит задуматься о смене системы управления firewall на что-то другое или полном отказе от нее. + +#### Интеграция с OpenWRT + +Готовая интеграция с firewall имеется для OpenWRT. Скрипты запуска автоматически определяют fw3 и отключат управление firewall через start/stop/restart. Вместо этого в `/etc/config/firewall` прописывается firewall include `firewall.zapret2`, который и запускает правила zapret синхронно после поднятия fw3. Дополнительно вешается хук `90-zapret2` в `/etc/hotplug.d/iface` на поднятие/опускание интерфейсов. В варианте fw3 происходит рестарт fw3, чтобы правила применились к новым интерфейсам или наоборот - были удалены для более несуществующих интерфейсов. В варианте nftables происходит лишь перезагрузка сетов wanif, wanif6 и flowtable. + ### custom скрипты +Стандартный инстанс [NFQWS2_OPT](#файл-config) не всегда может решить специфические задачи. Перехват осуществляется только по портам. Нет возможности вписать дополнительные условия - например, перехватить особый пейлоад на любом порту, задать особый фильтр connbytes или использовать специальный kernel ipset и применять особые стратегии к этому перехваченному трафику. + +Все это очень частно и не годится для реализации в основном функционале. Поэтому и создана система custom скриптов, которые представляют собой shell includes и располагаются в `init.d/sysv/custom.d` или `init.d/openwrt/custom.d`. Их основная задача - поднять нужные вам правила firewall и запустить инстансы nfqws2 с нужными параметрами. Возможны и другие вспомогательные действия. + +custom скрипт может иметь следующие shell функции, которые вызываются системой запуска : + +* zapret_custom_daemons - поднятие и останов демонов. $1 = 1 - поднятие, 0 - останов. +* zapret_custom_firewall - поднятие и снятие правил iptables. $1 - поднятие, 0 - снятие. +* zapret_custom_firewall_nft - поднятие правил nftables. останов не требуется, поскольку основной код при останове очищает цепочки nft вместе с custom правилами. +* zapret_custom_firewall_nft_flush - вызывается при останове nftables, чтобы можно было удалить обьекты, выходящие за рамки стандартных цепочек - такие, как собственные set-ы или собственные цепочки. + +Если вам не нужны iptables или nftables, функции для соответствующего типа firewall можно не писать. В функциях крайне желательно пользоваться хелперами основного кода - так вы будете следовать идеологии скриптов запуска без необходимости сосредотачиваться на частностях. Можно свободно адресовать переменные [config](#файл-config) и добавлять туда свои. + +Лучший способ начать писать свои скрипты - изучить готовые в `init.d/custom.d.examples.linux`. + +#### custom хелперы + +Это функции из основного кода скриптов запуска, которые будут полезны при написании custom скриптов. + +##### Получение динамических номеров + +``` +alloc_dnum() +# $1 - имя переменной, которой присваивается номер демона +alloc_qnum() +# $1 - имя переменной, которой присваивается номер очереди +``` + +Функции получения динамических номеров из пула необходимы, чтобы между разными скриптами запуска не возникло конфликтов. Номер очереди - уникальное значение, 2 инстанса не могут висеть на одной очереди. Второй вылетит с ошибкой. Номер демона нужен для отслеживания PID. При пересечении не будет корректно работать start/stop/restart. + +Следует вызывать не из функции, а из основного кода скрипта - вне функции. custom скрипты всегда выполняются в алфавитном порядке - это стандартная схема ".d" директорий в unix. При одинаковом наборе скриптов всегда для каждого скрипта будут возвращаться одни и те же значения qnum и dnum как при старте, так и при останове, поэтому можно их использовать в качестве уникальных номеров и не попасть на чужие номера. Если после старта был изменен состав custom скриптов - правило нарушится, и будут проблемы. Поэтому лучше не менять состав custom скриптов , пока zapret2 запущен. + +##### Работа с демонами + +``` +do_nfqws() +# $1 - 1 - старт , 0 - останов +# $2 - номер демона +# $3 - параметры nfqws2 +``` + +Запуск или останов инстанса nfqws2. Базовые параметры приписываются автоматически. К базовым параметрам относится выбор user, fwmark и подключение стандартных скриптов LUA - [zapret-lib.lua](#библиотека-базовых-функций-zapret-liblua), [zapret-antidpi.lua](#библиотека-программ-атаки-на-dpi-zapret-antidpilua), [zapret-auto.lua](#библиотека-программ-автоматизации-и-оркестрации-zapret-autolua). + +Номер очереди вы должны указать сами в `--qnum`. + +``` +filter_apply_hostlist_target() +# $1 - имя переменной с опциями nfqws2 +``` + +Осуществляет замену маркеров `` и `` в $1 зависимости от режима фильтрации [MODE_FILTER](#файл-config) и наличия файлов листов в ipset. + +``` +standard_mode_daemons() +# $1 - 1 - старт , 0 - останов +``` + +Запуск или останов [стандартного инстанса](#файл-config) nfqws2. +Можно локально переопределить любые переменные config. + +##### Работа с iptables + +``` +fw_nfqws_post() +fw_nfqws_pre() +# $1 - 1 - поднятие, 0 - опускание +# $2 - фильтр iptables для ipv4 +# $3 - фильтр iptables для ipv6 +# $4 - номер очереди +``` + +Поднятие и опускание правил перенаправления в очередь для nfqws2. Фильтры пишутся отдельно для ipv4 и ipv6, поскольку могут содержать специфические элементы для одной версии ip протокола, которые вызовут ошибку для другой версии. + +"post" означает цепочку для выходного трафика, "pre" - для входного. + +К правилам приписывается слева $FW_EXTRA_PRE, справа $FW_EXTRA_POST. + +Что не следует писать в фильтр : + +* Проверку стандарных exclude ipset - nozapret, nozapret6. +* Проверку по [DESYNC_FWMARK](#файл-config). + +Будут ли применены правила для каждой версии ip зависит от настроек [config](#файл-config). + +``` +zapret_do_firewall_standard_tpws_rules_ipt() +# $1 - 1 - поднятие, 0 - опускание +``` + +Применить или снять правила iptables для [стандартного](#файл-config) инстанса nfqws2. +Можно локально переопределять переменные [config](#файл-config) и применять FW_EXTRA_POST и FW_EXTRA_PRE. + +``` +filter_apply_ipset_target() +# $1 - имя переменной с правилами фильтра iptables +# $2 - имя переменной с правилами фильтра ip6tables +``` + +Добавляет в переменные $1 и $2 проверку на стандартные set-ы zapret/zapret6 в исходящем направлении (dst). + +``` +reverse_nfqws_rule_stream() +# stdin - правила фильтра iptables или ip6tables +reverse_nfqws_rule() +# $@ правила фильтра iptables или ip6tables +``` + +Замена элементов iptables фильтра с прямого на обратное направление - меняется dst на src. Результат выводится в stdout. + +``` +ipt() +ipta() +ipt_del() +ipt6() +ipt6a() +ipt6_del() +# $@ - правило iptables +ipt_add_del() +ipta_add_del() +ipt6_add_del() +ipt6a_add_del() +# $1 - 1 - добавление, 0 - удаление +# $2+ - все остальные аргументы определяют правило iptables +``` + +Набор функций для управления правилами iptables. Все функции, добавляющие правила, проверяют сначала наличие правила, и если оно уже есть - не добавляют. Это необходимо для предотвращения дублирования правил. Ко всем правилам добавляется слева $FW_EXTRA_PRE, справа - $FW_EXTRA_POST. Буква "6" означает работу с ipv6, ее отсутствие - работу с ipv4. + +Все правила начинаются с имени цепочки без команды iptables '-A', '-D', '-I' и т.д. + +* ipt - iptables -I - добавление в начало +* ipta - iptables -A - добавление в конец +* ipt_del - iptables -D - удаление +* ipt_add_del - добавление через -I или удаление. в $1 - 1 - добавление, 0 - удаление. Само правило идет начиная с $2. +* ipta_add_del - как в предыдущем варианте, только -A вместо -I + +``` +ipt_first_packets() +# $1 - количество пакетов или строка "keepalive" +``` + +Выдает в stdout "-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes $RANGE". RANGE определяется как "1:$1". Если $1 = "keepalive", не выдается ничего (нет фильтра по connbytes). + +##### Работа с nftables + +``` +nft_fw_nfqws_post() +nft_fw_nfqws_pre() +# $1 - фильтр nftables для ipv4 +# $2 - фильтр nftables для ipv6 +# $3 - номер очереди +``` + +Поднятие и опускание правил перенаправления в очередь для nfqws2. Фильтры пишутся отдельно для ipv4 и ipv6, поскольку могут содержать специфические элементы для одной версии ip протокола, которые вызовут ошибку для другой версии. + +"post" означает цепочку для выходного трафика, "pre" - для входного. Тип цепочки выбирается в зависимости от переменной [POSTNAT](#файл-config). Если вам нужна конкретная цепочка - можно переопределить POSTNAT на один вызов или как локальную переменную в функции. + +К правилам приписывается слева $FW_EXTRA_PRE, справа $FW_EXTRA_POST. + +Что не следует писать в фильтр : + +* Проверку стандарных exclude ipset - nozapret, nozapret6. +* Проверку по [DESYNC_FWMARK](#файл-config). + +Будут ли применены правила для каждой версии ip зависит от настроек [config](#файл-config). + +``` +zapret_do_firewall_standard_tpws_rules_nft() +``` + +Применить правила nftables для [стандартного](#файл-config) инстанса nfqws2. +Можно локально переопределять переменные [config](#файл-config) и применять FW_EXTRA_POST и FW_EXTRA_PRE. + +``` +nft_filter_apply_ipset_target() +# $1 - имя переменной с правилами фильтра nftables для ipv4 +# $2 - имя переменной с правилами фильтра nftables для ipv6 +``` + +Добавляет в переменные $1 и $2 проверку на стандартные set-ы zapret/zapret6 в исходящем направлении (dst). + +``` +nft_reverse_nfqws_rule() +# $@ - правило фильтра nftables +``` + +Замена элементов nftables фильтра с прямого на обратное направление - меняется dst на src. Результат выводится в stdout. + +``` +nft_create_set() +# $1 - имя сета +# $2 - параметры внутри { } +nft_del_set() +# $1 - имя сета +nft_flush_set() +# $1 - имя сета +nft_set_exists() +# $1 - имя сета +nft_add_set_element() +# $1 - имя сета или map +# $2 - элемент +nft_add_set_elements() +# $1 - имя сета или map +# $2,$3,... - элементы + +nft_flush_chain() +# $1 - имя цепочки + +nft_add_rule() +# $1 - имя цепочки +# $2+ - правило nftables +nft_insert_rule() +# $1 - имя цепочки +# $2+ - правило nftables +``` + +Функции работают с таблицей zapret2 и позволяют избавиться от прямого вызова nft с указанием жестко заданного имени таблицы. Названия говорят сами за себя. + +``` +nft_first_packets() +# $1 - количество пакетов или "keepalive" +``` + +Выдает в stdout "ct original packets $RANGE". RANGE определяется как "1-$1", если $1 > 1, "1", если $1 = 1. Если $1 = "keepalive", не выдается ничего (нет фильтра по connbytes). + +##### Дополнительные функции + +Множество полезных хелперов расположены в `common/base.sh`. Их назначение несложно понять по коду. + + ## Инсталлятор