From 502e34a96d84c689de42beb2c8236d3a21a66c4e Mon Sep 17 00:00:00 2001 From: Evgeny <36511477+chymaboy@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:35:03 +0300 Subject: [PATCH 1/7] Update readme.md OpenWrt change all repeats in text to correct registr --- docs/readme.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/readme.md b/docs/readme.md index 0927481e..4f452388 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -74,7 +74,7 @@ zapret является свободным и open source. обойти блокировки или замедление сайтов HTTP(S), сигнатурный анализ TCP и UDP протоколов, например, с целью блокировки VPN. -Проект нацелен прежде всего на маломощные embedded устройства - роутеры, работающие под OpenWRT. Поддерживаются +Проект нацелен прежде всего на маломощные embedded устройства - роутеры, работающие под OpenWrt. Поддерживаются традиционные Linux-системы, FreeBSD, OpenBSD, частично macOS. В некоторых случаях возможна самостоятельная прикрутка решения к различным прошивкам. @@ -263,7 +263,7 @@ dvtws, собираемый из тех же исходников (см. [док `net.netfilter.nf_conntrack_checksum=1` заставляет conntrack проверять tcp и udp чексуммы входящих пакетов и выставлять state INVALID для пакетов с инвалидной суммой. Обычно в правилах iptables вставляется правило для дропа пакетов с состоянием INVALID в цепочке FORWARD. Совместное сочетание этих факторов приводит к непрохождению badsum - через такой роутер. В openwrt из коробки `net.netfilter.nf_conntrack_checksum=0`, в других роутерах часто нет, и не + через такой роутер. В OpenWrt из коробки `net.netfilter.nf_conntrack_checksum=0`, в других роутерах часто нет, и не всегда это можно изменить. Чтобы nfqws мог работать через роутер, нужно на нем выставить указанное значение sysctl в 0. nfqws на самом роутере будет работать и без этой настройки, потому что чексумма локально созданных пакетов не проверяется никогда. Если роутер за другим NAT, например провайдерским, и он не пропускает invalid packets вы ничего @@ -566,7 +566,7 @@ ipv6 : Нет способа для приложения гарантирова Чтобы не загромождать описание, смотрите пример решения этой проблемы в `blockcheck.sh`. Иногда требуется подгружать модуль `ip6table_raw` с параметром `raw_before_defrag=1`. -В openwrt параметры модулей указываются через пробел после их названий в файлах `/etc/modules.d`. +В OpenWrt параметры модулей указываются через пробел после их названий в файлах `/etc/modules.d`. В традиционных системах посмотрите используется ли `iptables-legacy` или `iptables-nft`. Если legacy, то нужно создать файл `/etc/modprobe.d/ip6table_raw.conf` с содержимым : ``` @@ -740,10 +740,10 @@ iptables могут не работать. При включенном offloadin DNAT/REDIRECT (tpws). Эти соединения исключаются из offloading. Однако, остальные соединения идут через SFO, потому NFQUEUE будет срабатывать только до помещения соединения в flowtable. Практически это означает, что почти весь функционал nfqws работать не будет. Offload включается через специальный target в iptables `FLOWOFFLOAD`. Не обязательно пропускать весь трафик через offload. Можно исключить из -offload соединения, которые должны попасть на tpws или nfqws. openwrt не предусматривает выборочного управления offload. -Поэтому скрипты zapret поддерживают свою систему выборочного управления offload в openwrt. +offload соединения, которые должны попасть на tpws или nfqws. OpenWrt не предусматривает выборочного управления offload. +Поэтому скрипты zapret поддерживают свою систему выборочного управления offload в OpenWrt. -iptables target `FLOWOFFLOAD` - это проприетарное изобретение openwrt. +iptables target `FLOWOFFLOAD` - это проприетарное изобретение OpenWrt. Управление offload в nftables реализовано в базовом ядре linux без патчей. @@ -1457,7 +1457,7 @@ UNBLOCKED_DOM - незаблокированный домен, который и `SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 CURL=/tmp/curl ./blockcheck.sh` **СКАН ПОРТОВ**\ -Если в системе присутствует совместимый `netcat` (ncat от nmap или openbsd ncat. в openwrt по умолчанию нет), +Если в системе присутствует совместимый `netcat` (ncat от nmap или openbsd ncat. в OpenWrt по умолчанию нет), то выполняется сканирование портов http или https всех IP адресов домена. Если ни один IP не отвечает, то результат очевиден. Можно останавливать сканирование. Автоматически оно не остановится, потому что netcat-ы недостаточно подробно информируют о причинах ошибки. @@ -1564,7 +1564,7 @@ curl: (28) Connection timed out after 2002 milliseconds На linux системах можно выбрать использовать `iptables` или `nftables`. По умолчанию на традиционных linux выбирается `nftables`, если установлен nft. -На openwrt по умолчанию выбирается `nftables` на новых версиях с firewall4. +На OpenWrt по умолчанию выбирается `nftables` на новых версиях с firewall4. `FWTYPE=iptables` @@ -1775,11 +1775,11 @@ LISTS_RELOAD="pfctl -f /etc/pf.conf" LISTS_RELOAD=- ``` -В openwrt существует сеть по умолчанию 'lan'. Только трафик с этой сети будет перенаправлен на tpws. +В OpenWrt существует сеть по умолчанию 'lan'. Только трафик с этой сети будет перенаправлен на tpws. Но возможно задать другие сети или список сетей:\ `OPENWRT_LAN="lan lan2 lan3"` -В openwrt в качестве wan берутся интерфейсы, имеющие default route. Отдельно для ipv4 и ipv6. +В OpenWrt в качестве wan берутся интерфейсы, имеющие default route. Отдельно для ipv4 и ipv6. Это можно переопределить: ``` OPENWRT_WAN4="wan4 vpn" @@ -1789,7 +1789,7 @@ OPENWRT_WAN6="wan6 vpn6" Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.\ При иных значениях или если параметр закомментирован, правила применены не будут.\ Это полезно, если у вас есть система управления фаерволом, в настройки которой и следует прикрутить правила.\ -На openwrt неприменимо при использовании firewall3+iptables. +На OpenWrt неприменимо при использовании firewall3+iptables. ***Следующие настройки не актуальны для openwrt:*** @@ -1843,7 +1843,7 @@ _Для `nftables` предусмотрено несколько дополни Обновить set-ы интерфейсов, относящихся к lan, wan и wan6. Для традиционных linux список интерфейсов берется из переменных конфига IFACE_LAN, IFACE_WAN. -Для openwrt определяется автоматически. Множество lanif может быть расширено параметром OPENWRT_LAN. +Для openwrt определяется автоматически. Множество lanif может быть расширено параметром OpenWrt_LAN. Все интерфейсы lan и wan так же добавляются в ingress hook от flow table.\ `/opt/zapret/init.d/sysv/zapret reload_ifsets` @@ -1895,7 +1895,7 @@ zapret_custom_firewall_v6 zapret_custom_daemons поднимает демоны **nfqws**/**tpws** в нужном вам количестве и с нужными вам параметрами. В первом параметре передается код операции: 1 = запуск, 0 = останов. -Схема запуска демонов в openwrt отличается - используется procd. +Схема запуска демонов в OpenWrt отличается - используется procd. Поэтому логика останова отсутствует за ненадобностью, останов никогда не вызывается. zapret_custom_firewall поднимает и убирает правила `iptables`. @@ -1937,7 +1937,7 @@ zapret_custom_firewall_nft поднимает правила nftables. ## Простая установка `install_easy.sh` автоматизирует ручные варианты процедур установки. -Он поддерживает OpenWRT, linux системы на базе systemd или openrc и MacOS. +Он поддерживает OpenWrt, linux системы на базе systemd или openrc и MacOS. Для более гибкой настройки перед запуском инсталлятора следует выполнить раздел "Выбор параметров". @@ -1954,7 +1954,7 @@ zapret_custom_firewall_nft поднимает правила nftables. `install_easy.sh make` -Под openwrt все уже сразу готово для использования системы в качестве роутера. +Под OpenWrt все уже сразу готово для использования системы в качестве роутера. Имена интерфейсов WAN и LAN известны из настроек системы. Под другими системами роутер вы настраиваете самостоятельно. Инсталлятор в это не вмешивается. инсталлятор в зависимости от выбранного режима может спросить LAN и WAN интерфейсы. @@ -2087,7 +2087,7 @@ chcon u:object_r:system_file:s0 /data/local/tmp/zapret/tpws Работа blockcheck в android shell не поддерживается, но имея рута можно развернуть rootfs какого-нибудь дистрибутива linux. Это лучше всего делать с компа через adb shell. Если компа нет, то развертка chroot - единственный вариант, хотя и неудобный. -Подойдет что-то легковесное, например, alpine или даже openwrt. +Подойдет что-то легковесное, например, alpine или даже OpenWrt. Если это не эмулятор android, то универсальная архитектура - arm (любой вариант). Если вы точно знаете, что ОС у вас 64-разрядная, то лучше вместо arm - aarch64. Выяснить архитектуру можно командой `uname -a`. @@ -2231,10 +2231,10 @@ entware содержит репозиторий user-mode компонент, к _Подробное описание настроек для других прошивок выходит за рамки данного проекта._ -Openwrt является одной из немногих относительно полноценных linux систем для embedded devices. +OpenWrt является одной из немногих относительно полноценных linux систем для embedded devices. Она характеризуется следующими вещами, которые и послужили основой выбора именно этой прошивк: * полный root доступ к девайсу через shell. на заводских прошивках чаще всего отсутствует, на многих альтернативных есть -* корень r/w. это практически уникальная особенность openwrt. заводские и большинство альтернативных прошивок +* корень r/w. это практически уникальная особенность OpenWrt. заводские и большинство альтернативных прошивок построены на базе squashfs root (r/o), а конфигурация хранится в специально отформатированной области встроенной памяти, называемой nvram. не имеющие r/w корня системы сильно кастрированы. они не имеют возможности доустановки ПО из репозитория без специальных вывертов и заточены в основном @@ -2255,7 +2255,7 @@ Openwrt является одной из немногих относительн Если не работает автономный обход, приходится перенаправлять трафик через сторонний хост. Предлагается использовать прозрачный редирект через socks5 посредством `iptables+redsocks`, либо `iptables+iproute+vpn`. -Настройка варианта с redsocks на openwrt описана в [redsocks.txt](./redsocks.txt). +Настройка варианта с redsocks на OpenWrt описана в [redsocks.txt](./redsocks.txt). Настройка варианта с `iproute+wireguard` - в [wireguard_iproute_openwrt.txt](./wireguard_iproute_openwrt.txt). From 31cf1067280c5f5761c2d099a0a7d27691271394 Mon Sep 17 00:00:00 2001 From: Evgeny <36511477+chymaboy@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:37:36 +0300 Subject: [PATCH 2/7] Update readme.md fix parameter --- docs/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/readme.md b/docs/readme.md index 4f452388..1b0bf396 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1843,7 +1843,7 @@ _Для `nftables` предусмотрено несколько дополни Обновить set-ы интерфейсов, относящихся к lan, wan и wan6. Для традиционных linux список интерфейсов берется из переменных конфига IFACE_LAN, IFACE_WAN. -Для openwrt определяется автоматически. Множество lanif может быть расширено параметром OpenWrt_LAN. +Для OpenWrt определяется автоматически. Множество lanif может быть расширено параметром OPENWRT_LAN. Все интерфейсы lan и wan так же добавляются в ingress hook от flow table.\ `/opt/zapret/init.d/sysv/zapret reload_ifsets` From 2ff6ec03aa116866c08cfd32b84ff375fed22449 Mon Sep 17 00:00:00 2001 From: bol-van Date: Fri, 24 Jan 2025 11:12:56 +0300 Subject: [PATCH 3/7] tpws,nfqws: return lists reload on HUP --- nfq/hostlist.h | 2 ++ nfq/ipset.h | 2 ++ nfq/nfqws.c | 29 +++++++++++++++++++++++++++-- nfq/pools.c | 15 ++++++++++++++- nfq/pools.h | 2 ++ tpws/hostlist.h | 2 ++ tpws/ipset.h | 2 ++ tpws/pools.c | 14 ++++++++++++++ tpws/pools.h | 2 ++ tpws/tpws.c | 23 ++++++++++++++++++++++- tpws/tpws.h | 2 +- tpws/tpws_conn.c | 2 ++ 12 files changed, 92 insertions(+), 5 deletions(-) diff --git a/nfq/hostlist.h b/nfq/hostlist.h index deedc5c2..96766135 100644 --- a/nfq/hostlist.h +++ b/nfq/hostlist.h @@ -13,3 +13,5 @@ bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *exclu struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); bool HostlistsReloadCheckForProfile(const struct desync_profile *dp); void HostlistsDebug(); + +#define ResetAllHostlistsModTime() hostlist_files_reset_modtime(¶ms.hostlists) diff --git a/nfq/ipset.h b/nfq/ipset.h index f283c2f0..b711ac50 100644 --- a/nfq/ipset.h +++ b/nfq/ipset.h @@ -10,3 +10,5 @@ bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, con struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename); void IpsetsDebug(); bool AppendIpsetItem(ipset *ips, char *ip); + +#define ResetAllIpsetModTime() ipset_files_reset_modtime(¶ms.ipsets) diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 965893f0..fdd47120 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -49,14 +49,34 @@ #define MAX_CONFIG_FILE_SIZE 16384 struct params_s params; +static bool bReload=false; #ifdef __CYGWIN__ bool bQuit=false; #endif static void onhup(int sig) { - printf("HUP received !\n"); - // do not do anything. lists auto reload themselves based on file time. + printf("HUP received ! Lists will be reloaded.\n"); + bReload=true; +} +static void ReloadCheck() +{ + if (bReload) + { + ResetAllHostlistsModTime(); + if (!LoadAllHostLists()) + { + DLOG_ERR("hostlists load failed. this is fatal.\n"); + exit(1); + } + ResetAllIpsetModTime(); + if (!LoadAllIpsets()) + { + DLOG_ERR("ipset load failed. this is fatal.\n"); + exit(1); + } + bReload=false; + } } static void onusr1(int sig) @@ -251,6 +271,7 @@ static int nfq_main(void) { while ((rd = recv(fd, buf, sizeof(buf), 0)) >= 0) { + ReloadCheck(); if (rd) { int r = nfq_handle_packet(h, (char *)buf, (int)rd); @@ -371,6 +392,8 @@ static int dvt_main(void) uint8_t verdict; size_t len = rd; + ReloadCheck(); + DLOG("packet: id=%u len=%zu\n", id, len); verdict = processPacketData(&mark, NULL, buf, &len); switch (verdict & VERDICT_MASK) @@ -489,6 +512,8 @@ static int win_main(const char *windivert_filter) return w_win32_error; } + ReloadCheck(); + *ifout=0; if (wa.Outbound) snprintf(ifout,sizeof(ifout),"%u.%u", wa.Network.IfIdx, wa.Network.SubIfIdx); DLOG("packet: id=%u len=%zu %s IPv6=%u IPChecksum=%u TCPChecksum=%u UDPChecksum=%u IfIdx=%u.%u\n", id, len, wa.Outbound ? "outbound" : "inbound", wa.IPv6, wa.IPChecksum, wa.TCPChecksum, wa.UDPChecksum, wa.Network.IfIdx, wa.Network.SubIfIdx); diff --git a/nfq/pools.c b/nfq/pools.c index abb82d83..ac9cb14f 100644 --- a/nfq/pools.c +++ b/nfq/pools.c @@ -154,7 +154,6 @@ void strlist_destroy(struct str_list_head *head) - struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename) { struct hostlist_file *entry = malloc(sizeof(struct hostlist_file)); @@ -202,6 +201,13 @@ struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, co } return NULL; } +void hostlist_files_reset_modtime(struct hostlist_files_head *list) +{ + struct hostlist_file *hfile; + + LIST_FOREACH(hfile, list, next) + hfile->mod_time=0; +} struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile) { @@ -416,6 +422,13 @@ struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char } return NULL; } +void ipset_files_reset_modtime(struct ipset_files_head *list) +{ + struct ipset_file *hfile; + + LIST_FOREACH(hfile, list, next) + hfile->mod_time=0; +} struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile) { diff --git a/nfq/pools.h b/nfq/pools.h index cd37bdd8..41bf1d62 100644 --- a/nfq/pools.h +++ b/nfq/pools.h @@ -59,6 +59,7 @@ LIST_HEAD(hostlist_files_head, hostlist_file); struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename); void hostlist_files_destroy(struct hostlist_files_head *head); struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, const char *filename); +void hostlist_files_reset_modtime(struct hostlist_files_head *list); struct hostlist_item { struct hostlist_file *hfile; @@ -120,6 +121,7 @@ LIST_HEAD(ipset_files_head, ipset_file); struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *filename); void ipset_files_destroy(struct ipset_files_head *head); struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char *filename); +void ipset_files_reset_modtime(struct ipset_files_head *list); struct ipset_item { struct ipset_file *hfile; diff --git a/tpws/hostlist.h b/tpws/hostlist.h index deedc5c2..96766135 100644 --- a/tpws/hostlist.h +++ b/tpws/hostlist.h @@ -13,3 +13,5 @@ bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *exclu struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); bool HostlistsReloadCheckForProfile(const struct desync_profile *dp); void HostlistsDebug(); + +#define ResetAllHostlistsModTime() hostlist_files_reset_modtime(¶ms.hostlists) diff --git a/tpws/ipset.h b/tpws/ipset.h index f283c2f0..b711ac50 100644 --- a/tpws/ipset.h +++ b/tpws/ipset.h @@ -10,3 +10,5 @@ bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, con struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename); void IpsetsDebug(); bool AppendIpsetItem(ipset *ips, char *ip); + +#define ResetAllIpsetModTime() ipset_files_reset_modtime(¶ms.ipsets) diff --git a/tpws/pools.c b/tpws/pools.c index 631a2514..ac9cb14f 100644 --- a/tpws/pools.c +++ b/tpws/pools.c @@ -201,6 +201,13 @@ struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, co } return NULL; } +void hostlist_files_reset_modtime(struct hostlist_files_head *list) +{ + struct hostlist_file *hfile; + + LIST_FOREACH(hfile, list, next) + hfile->mod_time=0; +} struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile) { @@ -415,6 +422,13 @@ struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char } return NULL; } +void ipset_files_reset_modtime(struct ipset_files_head *list) +{ + struct ipset_file *hfile; + + LIST_FOREACH(hfile, list, next) + hfile->mod_time=0; +} struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile) { diff --git a/tpws/pools.h b/tpws/pools.h index cd37bdd8..41bf1d62 100644 --- a/tpws/pools.h +++ b/tpws/pools.h @@ -59,6 +59,7 @@ LIST_HEAD(hostlist_files_head, hostlist_file); struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename); void hostlist_files_destroy(struct hostlist_files_head *head); struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, const char *filename); +void hostlist_files_reset_modtime(struct hostlist_files_head *list); struct hostlist_item { struct hostlist_file *hfile; @@ -120,6 +121,7 @@ LIST_HEAD(ipset_files_head, ipset_file); struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *filename); void ipset_files_destroy(struct ipset_files_head *head); struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char *filename); +void ipset_files_reset_modtime(struct ipset_files_head *list); struct ipset_item { struct ipset_file *hfile; diff --git a/tpws/tpws.c b/tpws/tpws.c index d261ebfb..c52a2759 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -50,10 +50,31 @@ #define MAX_CONFIG_FILE_SIZE 16384 struct params_s params; +static bool bReload=false; static void onhup(int sig) { - printf("HUP received !\n"); + printf("HUP received ! Lists will be reloaded.\n"); + bReload=true; +} +void ReloadCheck() +{ + if (bReload) + { + ResetAllHostlistsModTime(); + if (!LoadAllHostLists()) + { + DLOG_ERR("hostlists load failed. this is fatal.\n"); + exit(1); + } + ResetAllIpsetModTime(); + if (!LoadAllIpsets()) + { + DLOG_ERR("ipset load failed. this is fatal.\n"); + exit(1); + } + bReload=false; + } } static void onusr2(int sig) diff --git a/tpws/tpws.h b/tpws/tpws.h index fa4eb307..baa7d60e 100644 --- a/tpws/tpws.h +++ b/tpws/tpws.h @@ -6,4 +6,4 @@ #include -void dohup(void); +void ReloadCheck(); diff --git a/tpws/tpws_conn.c b/tpws/tpws_conn.c index e30bd1a7..1294e74f 100644 --- a/tpws/tpws_conn.c +++ b/tpws/tpws_conn.c @@ -1544,6 +1544,8 @@ int event_loop(const int *listen_fd, size_t listen_fd_ct) for(;;) { + ReloadCheck(); + DBGPRINT("epoll_wait\n"); if ((num_events = epoll_wait(efd, events, MAX_EPOLL_EVENTS, -1)) == -1) From 02c76a4fb60a2c0442d954aa23577b87850cc7c4 Mon Sep 17 00:00:00 2001 From: bol-van Date: Fri, 24 Jan 2025 11:39:13 +0300 Subject: [PATCH 4/7] ipset: return HUP reload --- ipset/def.sh | 12 ++++++++++++ ipset/get_antizapret_domains.sh | 2 ++ ipset/get_reestr_hostlist.sh | 2 ++ ipset/get_reestr_resolvable_domains.sh | 2 ++ ipset/get_refilter_domains.sh | 2 ++ 5 files changed, 20 insertions(+) diff --git a/ipset/def.sh b/ipset/def.sh index 078c0971..aa55ca3a 100644 --- a/ipset/def.sh +++ b/ipset/def.sh @@ -267,3 +267,15 @@ getipban() _get_ipban return 0 } + +hup_zapret_daemons() +{ + echo forcing zapret daemons to reload their hostlist + if exists killall; then + killall -HUP tpws nfqws dvtws 2>/dev/null + elif exists pkill; then + pkill -HUP ^tpws$ ^nfqws$ ^dvtws$ + else + echo no mass killer available ! cant HUP zapret daemons + fi +} diff --git a/ipset/get_antizapret_domains.sh b/ipset/get_antizapret_domains.sh index 1bbbdc49..12583a8c 100755 --- a/ipset/get_antizapret_domains.sh +++ b/ipset/get_antizapret_domains.sh @@ -31,4 +31,6 @@ sort -u "$ZDOM" | zz "$ZHOSTLIST" rm -f "$ZDOM" +hup_zapret_daemons + exit 0 diff --git a/ipset/get_reestr_hostlist.sh b/ipset/get_reestr_hostlist.sh index 9c3ee957..0054cbca 100755 --- a/ipset/get_reestr_hostlist.sh +++ b/ipset/get_reestr_hostlist.sh @@ -58,6 +58,8 @@ rm -f "$ZREESTR" [ "$DISABLE_IPV6" != "1" ] && $AWK '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}($|(\/[0-9]{2,3}$))/' "$IPB" | cut_local6 | ip2net6 | zz "$ZIPLIST_IPBAN6" rm -f "$IPB" +hup_zapret_daemons + ipban_fin exit 0 diff --git a/ipset/get_reestr_resolvable_domains.sh b/ipset/get_reestr_resolvable_domains.sh index 67859162..fa008692 100755 --- a/ipset/get_reestr_resolvable_domains.sh +++ b/ipset/get_reestr_resolvable_domains.sh @@ -34,6 +34,8 @@ dl() dl "$URL" "$ZHOSTLIST" 65536 67108864 +hup_zapret_daemons + [ "$DISABLE_IPV4" != "1" ] && dl "$IPB4" "$ZIPLIST_IPBAN" 8192 1048576 [ "$DISABLE_IPV6" != "1" ] && dl "$IPB6" "$ZIPLIST_IPBAN6" 128 1048576 diff --git a/ipset/get_refilter_domains.sh b/ipset/get_refilter_domains.sh index f329ad6c..b11d26d3 100755 --- a/ipset/get_refilter_domains.sh +++ b/ipset/get_refilter_domains.sh @@ -37,4 +37,6 @@ getipban || FAIL=1 dl "$URL" "$ZHOSTLIST" 32768 4194304 +hup_zapret_daemons + exit 0 From aba1fdeb04a6981613082fdc65791bbd10abf76d Mon Sep 17 00:00:00 2001 From: bol-van Date: Fri, 24 Jan 2025 12:50:17 +0300 Subject: [PATCH 5/7] tpws,nfqws: track file size in addition to mod time --- nfq/desync.c | 3 ++- nfq/helpers.c | 8 ++++++++ nfq/helpers.h | 8 ++++++++ nfq/hostlist.c | 8 ++++---- nfq/ipset.c | 8 ++++---- nfq/pools.c | 8 ++++---- nfq/pools.h | 4 ++-- tpws/helpers.c | 8 ++++++++ tpws/helpers.h | 8 ++++++++ tpws/hostlist.c | 8 ++++---- tpws/ipset.c | 8 ++++---- tpws/pools.c | 8 ++++---- tpws/pools.h | 4 ++-- tpws/tamper.c | 3 ++- 14 files changed, 64 insertions(+), 30 deletions(-) diff --git a/nfq/desync.c b/nfq/desync.c index 06196b71..f61d9822 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -367,7 +367,8 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname DLOG_PERROR("write to auto hostlist:"); return; } - dp->hostlist_auto->mod_time = file_mod_time(dp->hostlist_auto->filename); + if (!file_mod_signature(dp->hostlist_auto->filename, &dp->hostlist_auto->mod_sig)) + DLOG_PERROR("file_mod_signature"); } else { diff --git a/nfq/helpers.c b/nfq/helpers.c index aba018c2..03f130c8 100644 --- a/nfq/helpers.c +++ b/nfq/helpers.c @@ -300,6 +300,14 @@ time_t file_mod_time(const char *filename) struct stat st; return stat(filename,&st)==-1 ? 0 : st.st_mtime; } +bool file_mod_signature(const char *filename, file_mod_sig *ms) +{ + struct stat st; + if (stat(filename,&st)==-1) return false; + ms->mod_time=st.st_mtime; + ms->size=st.st_size; + return true; +} bool pf_in_range(uint16_t port, const port_filter *pf) { diff --git a/nfq/helpers.h b/nfq/helpers.h index 756bab6e..5e8e80c2 100644 --- a/nfq/helpers.h +++ b/nfq/helpers.h @@ -60,6 +60,14 @@ void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize int fprint_localtime(FILE *F); +typedef struct +{ + time_t mod_time; + off_t size; +} file_mod_sig; +#define FILE_MOD_COMPARE(ms1,ms2) (((ms1)->mod_time==(ms2)->mod_time) && ((ms1)->size==(ms2)->size)) +#define FILE_MOD_RESET(ms) memset(ms,0,sizeof(file_mod_sig)) +bool file_mod_signature(const char *filename, file_mod_sig *ms); time_t file_mod_time(const char *filename); typedef struct diff --git a/nfq/hostlist.c b/nfq/hostlist.c index 9b757588..34e25cf5 100644 --- a/nfq/hostlist.c +++ b/nfq/hostlist.c @@ -105,21 +105,21 @@ static bool LoadHostList(struct hostlist_file *hfile) { if (hfile->filename) { - time_t t = file_mod_time(hfile->filename); - if (!t) + file_mod_sig fsig; + if (!file_mod_signature(hfile->filename, &fsig)) { // stat() error DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename); return true; } - if (t==hfile->mod_time) return true; // up to date + if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date StrPoolDestroy(&hfile->hostlist); if (!AppendHostList(&hfile->hostlist, hfile->filename)) { StrPoolDestroy(&hfile->hostlist); return false; } - hfile->mod_time=t; + hfile->mod_sig=fsig; } return true; } diff --git a/nfq/ipset.c b/nfq/ipset.c index 86970b05..a4d1ebef 100644 --- a/nfq/ipset.c +++ b/nfq/ipset.c @@ -126,21 +126,21 @@ static bool LoadIpset(struct ipset_file *hfile) { if (hfile->filename) { - time_t t = file_mod_time(hfile->filename); - if (!t) + file_mod_sig fsig; + if (!file_mod_signature(hfile->filename, &fsig)) { // stat() error DLOG_ERR("cannot access ipset file '%s'. in-memory content remains unchanged.\n",hfile->filename); return true; } - if (t==hfile->mod_time) return true; // up to date + if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date ipsetDestroy(&hfile->ipset); if (!AppendIpset(&hfile->ipset, hfile->filename)) { ipsetDestroy(&hfile->ipset); return false; } - hfile->mod_time=t; + hfile->mod_sig=fsig; } return true; } diff --git a/nfq/pools.c b/nfq/pools.c index ac9cb14f..4cce2f68 100644 --- a/nfq/pools.c +++ b/nfq/pools.c @@ -169,7 +169,7 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const } else entry->filename = NULL; - entry->mod_time = 0; + FILE_MOD_RESET(&entry->mod_sig); entry->hostlist = NULL; LIST_INSERT_HEAD(head, entry, next); } @@ -206,7 +206,7 @@ void hostlist_files_reset_modtime(struct hostlist_files_head *list) struct hostlist_file *hfile; LIST_FOREACH(hfile, list, next) - hfile->mod_time=0; + FILE_MOD_RESET(&hfile->mod_sig); } struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile) @@ -390,7 +390,7 @@ struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *fi } else entry->filename = NULL; - entry->mod_time = 0; + FILE_MOD_RESET(&entry->mod_sig); memset(&entry->ipset,0,sizeof(entry->ipset)); LIST_INSERT_HEAD(head, entry, next); } @@ -427,7 +427,7 @@ void ipset_files_reset_modtime(struct ipset_files_head *list) struct ipset_file *hfile; LIST_FOREACH(hfile, list, next) - hfile->mod_time=0; + FILE_MOD_RESET(&hfile->mod_sig); } struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile) diff --git a/nfq/pools.h b/nfq/pools.h index 41bf1d62..aeda63f7 100644 --- a/nfq/pools.h +++ b/nfq/pools.h @@ -50,7 +50,7 @@ void strlist_destroy(struct str_list_head *head); struct hostlist_file { char *filename; - time_t mod_time; + file_mod_sig mod_sig; strpool *hostlist; LIST_ENTRY(hostlist_file) next; }; @@ -112,7 +112,7 @@ void ipsetPrint(ipset *ipset); struct ipset_file { char *filename; - time_t mod_time; + file_mod_sig mod_sig; ipset ipset; LIST_ENTRY(ipset_file) next; }; diff --git a/tpws/helpers.c b/tpws/helpers.c index 8d714033..b4f4ba33 100644 --- a/tpws/helpers.c +++ b/tpws/helpers.c @@ -314,6 +314,14 @@ time_t file_mod_time(const char *filename) struct stat st; return stat(filename, &st) == -1 ? 0 : st.st_mtime; } +bool file_mod_signature(const char *filename, file_mod_sig *ms) +{ + struct stat st; + if (stat(filename,&st)==-1) return false; + ms->mod_time=st.st_mtime; + ms->size=st.st_size; + return true; +} bool pf_in_range(uint16_t port, const port_filter *pf) { diff --git a/tpws/helpers.h b/tpws/helpers.h index 3c8a3723..1b744306 100644 --- a/tpws/helpers.h +++ b/tpws/helpers.h @@ -62,6 +62,14 @@ static inline void phton16(uint8_t *p, uint16_t v) { int fprint_localtime(FILE *F); +typedef struct +{ + time_t mod_time; + off_t size; +} file_mod_sig; +#define FILE_MOD_COMPARE(ms1,ms2) (((ms1)->mod_time==(ms2)->mod_time) && ((ms1)->size==(ms2)->size)) +#define FILE_MOD_RESET(ms) memset(ms,0,sizeof(file_mod_sig)) +bool file_mod_signature(const char *filename, file_mod_sig *ms); time_t file_mod_time(const char *filename); typedef struct diff --git a/tpws/hostlist.c b/tpws/hostlist.c index 6fbbd7d9..c10aca63 100644 --- a/tpws/hostlist.c +++ b/tpws/hostlist.c @@ -105,21 +105,21 @@ static bool LoadHostList(struct hostlist_file *hfile) { if (hfile->filename) { - time_t t = file_mod_time(hfile->filename); - if (!t) + file_mod_sig fsig; + if (!file_mod_signature(hfile->filename, &fsig)) { // stat() error DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename); return true; } - if (t==hfile->mod_time) return true; // up to date + if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date StrPoolDestroy(&hfile->hostlist); if (!AppendHostList(&hfile->hostlist, hfile->filename)) { StrPoolDestroy(&hfile->hostlist); return false; } - hfile->mod_time=t; + hfile->mod_sig=fsig; } return true; } diff --git a/tpws/ipset.c b/tpws/ipset.c index b803205d..b486eb45 100644 --- a/tpws/ipset.c +++ b/tpws/ipset.c @@ -126,21 +126,21 @@ static bool LoadIpset(struct ipset_file *hfile) { if (hfile->filename) { - time_t t = file_mod_time(hfile->filename); - if (!t) + file_mod_sig fsig; + if (!file_mod_signature(hfile->filename, &fsig)) { // stat() error DLOG_ERR("cannot access ipset file '%s'. in-memory content remains unchanged.\n",hfile->filename); return true; } - if (t==hfile->mod_time) return true; // up to date + if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date ipsetDestroy(&hfile->ipset); if (!AppendIpset(&hfile->ipset, hfile->filename)) { ipsetDestroy(&hfile->ipset); return false; } - hfile->mod_time=t; + hfile->mod_sig=fsig; } return true; } diff --git a/tpws/pools.c b/tpws/pools.c index ac9cb14f..4cce2f68 100644 --- a/tpws/pools.c +++ b/tpws/pools.c @@ -169,7 +169,7 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const } else entry->filename = NULL; - entry->mod_time = 0; + FILE_MOD_RESET(&entry->mod_sig); entry->hostlist = NULL; LIST_INSERT_HEAD(head, entry, next); } @@ -206,7 +206,7 @@ void hostlist_files_reset_modtime(struct hostlist_files_head *list) struct hostlist_file *hfile; LIST_FOREACH(hfile, list, next) - hfile->mod_time=0; + FILE_MOD_RESET(&hfile->mod_sig); } struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile) @@ -390,7 +390,7 @@ struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *fi } else entry->filename = NULL; - entry->mod_time = 0; + FILE_MOD_RESET(&entry->mod_sig); memset(&entry->ipset,0,sizeof(entry->ipset)); LIST_INSERT_HEAD(head, entry, next); } @@ -427,7 +427,7 @@ void ipset_files_reset_modtime(struct ipset_files_head *list) struct ipset_file *hfile; LIST_FOREACH(hfile, list, next) - hfile->mod_time=0; + FILE_MOD_RESET(&hfile->mod_sig); } struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile) diff --git a/tpws/pools.h b/tpws/pools.h index 41bf1d62..aeda63f7 100644 --- a/tpws/pools.h +++ b/tpws/pools.h @@ -50,7 +50,7 @@ void strlist_destroy(struct str_list_head *head); struct hostlist_file { char *filename; - time_t mod_time; + file_mod_sig mod_sig; strpool *hostlist; LIST_ENTRY(hostlist_file) next; }; @@ -112,7 +112,7 @@ void ipsetPrint(ipset *ipset); struct ipset_file { char *filename; - time_t mod_time; + file_mod_sig mod_sig; ipset ipset; LIST_ENTRY(ipset_file) next; }; diff --git a/tpws/tamper.c b/tpws/tamper.c index 74927286..c06613e2 100644 --- a/tpws/tamper.c +++ b/tpws/tamper.c @@ -443,7 +443,8 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname DLOG_PERROR("write to auto hostlist:"); return; } - dp->hostlist_auto->mod_time = file_mod_time(dp->hostlist_auto->filename); + if (!file_mod_signature(dp->hostlist_auto->filename, &dp->hostlist_auto->mod_sig)) + DLOG_PERROR("file_mod_signature"); } else { From c69a92f9015a5d144d12b29e83482dd11f1262d1 Mon Sep 17 00:00:00 2001 From: bol-van Date: Fri, 24 Jan 2025 12:55:16 +0300 Subject: [PATCH 6/7] update readme --- docs/changes.txt | 3 +++ docs/readme.en.md | 3 ++- docs/readme.md | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 7a84887e..01efa34e 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -448,3 +448,6 @@ blockcheck: override all dialog questions and enable batch mode blockcheck: parallel attempts nfqws: weaken wireguard initiation recognition. use len=148 and data[0]=1 signature nfqws: apply split+seqovl only to the first reasm fragment +install_easy: dnf packager support +nfqws,tpws: hostlist/ipset track not only file mod time but also file size +nfqws,tpws,ipset: return lists reload on HUP diff --git a/docs/readme.en.md b/docs/readme.en.md index fada4567..82f5209e 100644 --- a/docs/readme.en.md +++ b/docs/readme.en.md @@ -965,7 +965,8 @@ If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Ju Subdomains auto apply. For example, "ru" in the list affects "*.ru" . -**tpws** and **nfqws** automatically reload lists if their modification date is changed. +**tpws** and **nfqws** automatically reload lists if their modification time or file size is changed. +HUP signal forcibly reloads all lists. When filtering by domain name, daemons should run without filtering by ipset. When using large regulator lists estimate the amount of RAM on the router ! diff --git a/docs/readme.md b/docs/readme.md index 0927481e..03c5ea58 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1303,7 +1303,8 @@ ipset/get_refilter_domains.sh ``` Он кладется в `ipset/zapret-hosts.txt.gz`. -При изменении времени модификации файлов списки перечитываются автоматически. +При изменении времени модификации или размера файлов списки перечитываются автоматически. +После неатомарных операций изменения можно послать tpws/nfqws сигнал HUP для принудительной перечитки всех листов. При фильтрации по именам доменов демон должен запускаться без фильтрации по ipset. tpws и nfqws решают нужно ли применять дурение в зависимости от хоста, полученного из протокола прикладного уровня (http, tls, quic). From f5cf7917fb78e7414bc2bd164777cf1309c68ccf Mon Sep 17 00:00:00 2001 From: bol-van Date: Fri, 24 Jan 2025 20:57:12 +0300 Subject: [PATCH 7/7] nfqws,tpws: file_mod_signature zero struct if unsuccessful --- nfq/helpers.c | 6 +++++- tpws/helpers.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/nfq/helpers.c b/nfq/helpers.c index 03f130c8..2e4727d2 100644 --- a/nfq/helpers.c +++ b/nfq/helpers.c @@ -303,7 +303,11 @@ time_t file_mod_time(const char *filename) bool file_mod_signature(const char *filename, file_mod_sig *ms) { struct stat st; - if (stat(filename,&st)==-1) return false; + if (stat(filename,&st)==-1) + { + FILE_MOD_RESET(ms); + return false; + } ms->mod_time=st.st_mtime; ms->size=st.st_size; return true; diff --git a/tpws/helpers.c b/tpws/helpers.c index b4f4ba33..7db6aac0 100644 --- a/tpws/helpers.c +++ b/tpws/helpers.c @@ -317,7 +317,11 @@ time_t file_mod_time(const char *filename) bool file_mod_signature(const char *filename, file_mod_sig *ms) { struct stat st; - if (stat(filename,&st)==-1) return false; + if (stat(filename,&st)==-1) + { + FILE_MOD_RESET(ms); + return false; + } ms->mod_time=st.st_mtime; ms->size=st.st_size; return true;