Skip to content

Commit 4347cce

Browse files
author
bol-van
committed
launch system: support separate and multiple hostlists
1 parent 895af0f commit 4347cce

File tree

9 files changed

+97
-86
lines changed

9 files changed

+97
-86
lines changed

common/list.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
find_hostlists()
2+
{
3+
[ -n "$HOSTLIST_BASE" ] || HOSTLIST_BASE="$ZAPRET_BASE/ipset"
4+
5+
HOSTLIST="$HOSTLIST_BASE/zapret-hosts.txt.gz"
6+
[ -f "$HOSTLIST" ] || HOSTLIST="$HOSTLIST_BASE/zapret-hosts.txt"
7+
[ -f "$HOSTLIST" ] || HOSTLIST=
8+
9+
HOSTLIST_USER="$HOSTLIST_BASE/zapret-hosts-user.txt.gz"
10+
[ -f "$HOSTLIST_USER" ] || HOSTLIST_USER="$HOSTLIST_BASE/zapret-hosts-user.txt"
11+
[ -f "$HOSTLIST_USER" ] || HOSTLIST_USER=
12+
13+
HOSTLIST_EXCLUDE="$HOSTLIST_BASE/zapret-hosts-user-exclude.txt.gz"
14+
[ -f "$HOSTLIST_EXCLUDE" ] || HOSTLIST_EXCLUDE="$HOSTLIST_BASE/zapret-hosts-user-exclude.txt"
15+
[ -f "$HOSTLIST_EXCLUDE" ] || HOSTLIST_EXCLUDE=
16+
}
17+
18+
filter_apply_hostlist_target()
19+
{
20+
# $1 - var name of tpws or nfqws params
21+
22+
[ "$MODE_FILTER" = "hostlist" ] || return
23+
24+
local HOSTLIST_BASE HOSTLIST HOSTLIST_USER HOSTLIST_EXCLUDE
25+
26+
find_hostlists
27+
28+
[ -n "$HOSTLIST" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
29+
[ -n "$HOSTLIST_USER" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST_USER\""
30+
[ -n "$HOSTLIST_EXCLUDE" ] && eval $1="\"\$$1 --hostlist-exclude=$HOSTLIST_EXCLUDE\""
31+
}

docs/changes.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,9 @@ v47
227227

228228
nfqws: QUIC initial decryption
229229
nfqws: udplen, fakeknown dpi desync modes
230+
231+
v48
232+
233+
nfqws, tpws : multiple --hostlist and --hostlist-exclude support
234+
launch system, ipset : no more list merging. all lists are passed separately to nfqws and tpws
235+
nfqws : udplen fooling supports packet shrinking (negative increment value)

docs/readme.eng.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ nfqws takes the following parameters:
174174
--dpi-desync-fake-quic=<filename> ; file containing fake QUIC Initial
175175
--dpi-desync-fake-unknown-udp=<filename> ; file containing unknown udp protocol fake payload
176176
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
177-
--hostlist=<filename> ; apply fooling only to the listed hosts (one host per line, subdomains auto apply)
177+
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
178+
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
178179
```
179180

180181
The manipulation parameters can be combined in any way.
@@ -523,7 +524,8 @@ tpws is transparent proxy.
523524
; its worth to make a reserve with 1.5 multiplier. by default maxfiles is (X*connections)*1.5+16
524525
--max-orphan-time=<sec> ; if local leg sends something and closes and remote leg is still connecting then cancel connection attempt after N seconds
525526
526-
--hostlist=<filename> ; only act on host in the list (one host per line, subdomains auto apply, gzip lists supported)
527+
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
528+
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
527529
--split-http-req=method|host ; split http request at specified logical position.
528530
--split-pos=<numeric_offset> ; split at specified pos. split-http-req takes precedence over split-pos for http reqs.
529531
--split-any-protocol ; split not only http and https
@@ -662,13 +664,25 @@ LISTS_RELOAD=- disables reloading ip list backend.
662664

663665
## Domain name filtering
664666

665-
An alternative to ipset is to use tpws or nfqws with a list of domains. Only one list is supported.
667+
An alternative to ipset is to use tpws or nfqws with a list(s) of domains.
668+
Both `tpws` and `nfqws` take any number of include (`--hostlist`) and exclude (`--hostlist-exclude`) domain lists.
669+
All lists of the same type are combined internally leaving only 2 lists : include and exclude.
666670

667-
Enter the blocked domains to `ipset/zapret-hosts-users.txt`. Remove `ipset/zapret-hosts.txt.gz`.
668-
Then the init script will run tpws with the `zapret-hosts-users.txt` list.
671+
Exclude list is checked first. Fooling is cancelled if domain belongs to exclude list.
672+
If include list is present and domain does not belong to that list fooling is also cancelled.
673+
Empty list means absent list. Otherwise fooling goes on.
669674

670-
Other option ( Roskomnadzor list - `get_hostlist.sh` ) is russian specific.
671-
You can write your own replacement for `get_hostlist.sh`.
675+
Launch system looks for 2 include lists :
676+
`ipset/zapret-hosts-users.txt.gz` or `ipset/zapret-hosts-users.txt`
677+
`ipset/zapret-hosts.txt.gz` or `ipset/zapret-hosts.txt`
678+
and 1 exclude list
679+
`ipset/zapret-hosts-users-exclude.txt.gz` or `ipset/zapret-hosts-users-exclude.txt`
680+
681+
If `MODE_FILTER=hostlist` all present lists are passed to `nfqws` or `tpws`.
682+
If all include lists are empty it works like no include lists exist at all.
683+
If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Just make it empty.
684+
685+
Subdomains auto apply. For example, "ru" in the list affects "*.ru" .
672686

673687
When filtering by domain name, daemons should run without filtering by ipset.
674688
When using large regulator lists estimate the amount of RAM on the router !
@@ -943,10 +957,6 @@ Example : `--uid 1:3003`
943957

944958
In iptables use : `! --uid-owner 1` instead of `! --uid-owner tpws`.
945959

946-
Nfqws should be executed with `--uid 1`. Otherwise on some devices and newer androids
947-
kernel may partially hang. Looks like processes with certain uids can be suspended.
948-
With buggy chineese cellular interface driver this can lead to device hang.
949-
950960
Write your own shell script with iptables and tpws, run it using your root manager.
951961
Autorun scripts are here :
952962

docs/readme.txt

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
zapret v.47
1+
zapret v.48
22

33
English
44
-------
@@ -226,7 +226,8 @@ nfqws
226226
--dpi-desync-fake-unknown-udp=<filename> ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
227227
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
228228
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
229-
--hostlist=<filename> ; применять дурение только к хостам из листа
229+
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие
230+
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются
230231

231232
Параметры манипуляции могут сочетаться в любых комбинациях.
232233

@@ -586,11 +587,12 @@ tpws - это transparent proxy.
586587
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
587588
; в файле должен быть хост на каждой строке.
588589
; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
589-
; для списка РКН может потребоваться система с 128 Mb памяти !
590-
; расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка.
591590
; по сигналу HUP список будет перечитан при следующем принятом соединении
592591
; список может быть запакован в gzip. формат автоматически распознается и разжимается
592+
; списков может быть множество, они обьединяются. пустой общий лист = его отсутствие
593593
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
594+
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов, они обьединяются
595+
594596

595597
Параметры манипуляции могут сочетаться в любых комбинациях.
596598

@@ -828,19 +830,36 @@ ip2net фильтрует входные данные, выкидывая неп
828830
----------------------------
829831

830832
Альтернативой ipset является использование tpws или nfqws со списком доменов.
831-
Может быть только один hostlist.
832-
833-
Поддерживаются следующие варианты :
834-
1) Внесите домены для дурения в ipset/zapret-hosts-users.txt. Удалите ipset/zapret-hosts.txt.gz.
835-
Тогда init скрипт будет запускать tpws/nfqws с листом zapret-hosts-users.txt.
836-
837-
2) Список доменов РКН может быть получен скриптами ipset/get_reestr_hostlist.sh или ipset/get_antizapret_domains.sh
833+
Оба демона принимают неограниченное количество листов include (--hostlist) и exclude (--hostlist-exclude).
834+
Все листы одного типа обьединяются, и таким образом остаются только 2 листа.
835+
Прежде всего проверяется exclude list. При вхождении в него происходит отказ от дурения.
836+
Далее при наличии include list проверяется домен на вхождение в него. При невхождении в список отказ от дурения.
837+
Пустой список приравнивается к его отсутствию.
838+
В иных случаях происходит дурение.
839+
Нет ни одного списка - дурение всегда.
840+
Есть только exclude список - дурение всех, кроме.
841+
Есть только include список - дурение только их.
842+
Есть оба - дурение только include, кроме exclude.
843+
844+
В системе запуска это обыграно следующим образом.
845+
Присутствуют 2 include списка :
846+
ipset/zapret-hosts-users.txt.gz или ipset/zapret-hosts-users.txt
847+
ipset/zapret-hosts.txt.gz или ipset/zapret-hosts.txt
848+
и 1 exclude список
849+
ipset/zapret-hosts-users-exclude.txt.gz или ipset/zapret-hosts-users-exclude.txt
850+
851+
При режиме фильтрации MODE_FILTER=hostlist система запуска передает nfqws или tpws все листы, файлы которых присутствуют.
852+
Если вдруг листы include присутствуют, но все они пустые, то работа аналогична отсутствию include листа.
853+
Файл есть, но не смотря на это дурится все, кроме exclude.
854+
Если вам нужен именно такой режим - не обязательно удалять zapret-hosts-users.txt. Достаточно сделать его пустым.
855+
856+
Поддомены учитываются автоматически. Например, строчка "ru" вносит в список "*.ru". Строчка "*.ru" в списке не сработает.
857+
858+
Список доменов РКН может быть получен скриптами ipset/get_reestr_hostlist.sh или ipset/get_antizapret_domains.sh
838859
- кладется в ipset/zapret-hosts.txt.gz.
839-
Этот скрипт автоматически добавляет к списку РКН домены из zapret-hosts-user.txt и исключает zapret-hosts-exclude.txt.
840-
init скрипт будет запускать tpws/nfqws с листом zapret-hosts.txt.gz.
841860

842861
При фильтрации по именам доменов демон должен запускаться без фильтрации по ipset.
843-
tpws и nfqws решают нужно ли применять дурение в зависимости от поля Host: в http запросе или SNI в TLS ClientHello.
862+
tpws и nfqws решают нужно ли применять дурение в зависимости от хоста, полученного из протокола прикладного уровня (http, tls, quic).
844863
При использовании больших списков, в том числе списка РКН, оцените объем RAM на роутере !
845864
Если после запуска демона RAM под завязку или случаются oom, значит нужно отказаться от таких больших списков.
846865

@@ -1190,15 +1209,8 @@ tpws будет работать в любом случае, он не треб
11901209
magisk : /data/adb/service.d
11911210
supersu : /system/su.d
11921211

1193-
nfqws может иметь такой глюк. При запуске с uid по умолчанию (0x7FFFFFFF) при условии работы на сотовом интерфейсе
1194-
и отключенном кабеле внешнего питания система может частично виснуть. Перестает работать тач и кнопки,
1195-
но анимация на экране может продолжаться. Если экран был погашен, то включить его кнопкой power невозможно.
1196-
Это, видимо, связано с переводом в suspend процессов с определенным UID. UID соответствует приложению или
1197-
системному сервису. По UID android определяет политику power saving.
1198-
Так же возможно, что глюк связан с кривым драйвером сотового интерфейса от китайцев, поскольку при использовании
1199-
wifi такого не наблюдается. suspend обработчика nfqueue на обычном linux не вызывает подобных фатальных последствий.
1200-
Изменение UID на низкий (--uid 1 подойдет) позволяет решить эту проблему.
1201-
Глюк был замечен на android 8.1 на девайсе , основанном на платформе mediatek.
1212+
Я не проверял не прибивают ли новые андроиды iptables по своей прихоти в процессе работы
1213+
или при подключении/отключении wifi, mobile data, ...
12021214

12031215
Ответ на вопрос куда поместить tpws на android без рута, чтобы потом его запускать из приложений.
12041216
Файл заливаем через adb shell в /data/local/tmp/, лучше всего в субфолдер.

init.d/macos/functions

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@
44
. "$ZAPRET_BASE/config"
55
. "$ZAPRET_BASE/common/base.sh"
66
. "$ZAPRET_BASE/common/pf.sh"
7+
. "$ZAPRET_BASE/common/list.sh"
78

89
IPSET_DIR=$ZAPRET_BASE/ipset
910
. "$IPSET_DIR/def.sh"
1011

11-
HOSTLIST="$ZHOSTLIST.gz"
12-
[ -f "$HOSTLIST" ] || HOSTLIST="$ZHOSTLIST"
13-
[ -f "$HOSTLIST" ] || HOSTLIST="$ZUSERLIST"
14-
1512
PIDDIR=/var/run
1613
[ -n "$TPPORT" ] || TPPORT=988
1714
[ -n "$WS_USER" ] || WS_USER=daemon
@@ -61,12 +58,6 @@ do_daemon()
6158
on_off_function run_daemon stop_daemon "$@"
6259
}
6360

64-
filter_apply_hostlist_target()
65-
{
66-
# $1 - var name of tpws or nfqws params
67-
[ "$MODE_FILTER" = "hostlist" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
68-
}
69-
7061
tpws_apply_binds()
7162
{
7263
local o

init.d/openwrt/zapret

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ PIDDIR=/var/run
4343
NFQWS_OPT_BASE="--user=$WS_USER --dpi-desync-fwmark=$DESYNC_MARK"
4444

4545
[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
46-
HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt.gz"
47-
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt"
48-
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts-user.txt"
4946
TPWS_OPT_BASE="--user=$WS_USER"
5047
TPWS_OPT_BASE4="--bind-addr=$TPWS_LOCALHOST4"
5148
TPWS_OPT_BASE6="--bind-addr=::1"
@@ -100,12 +97,6 @@ stop_tpws()
10097
}
10198

10299

103-
filter_apply_hostlist_target()
104-
{
105-
# $1 - var name of tpws or nfqws params
106-
[ "$MODE_FILTER" = "hostlist" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
107-
}
108-
109100
tpws_apply_socks_binds()
110101
{
111102
local o

init.d/sysv/functions

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
. "$ZAPRET_BASE/common/ipt.sh"
1010
. "$ZAPRET_BASE/common/nft.sh"
1111
. "$ZAPRET_BASE/common/linux_fw.sh"
12+
. "$ZAPRET_BASE/common/list.sh"
1213

1314

1415
user_exists()
@@ -74,9 +75,6 @@ NFQWS_OPT_DESYNC_HTTPS6="${NFQWS_OPT_DESYNC_HTTPS6:-$NFQWS_OPT_DESYNC_HTTPS}"
7475
[ -n "$TPPORT" ] || TPPORT=988
7576
[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
7677
TPWS_LOCALHOST4=127.0.0.127
77-
HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt.gz"
78-
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt"
79-
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts-user.txt"
8078

8179
TPWS_OPT_BASE="$USEROPT"
8280
TPWS_OPT_BASE4="--bind-addr=$TPWS_LOCALHOST4"
@@ -145,12 +143,6 @@ nft_fill_ifsets_overload()
145143
}
146144

147145

148-
filter_apply_hostlist_target()
149-
{
150-
# $1 - var name of tpws or nfqws params
151-
[ "$MODE_FILTER" = "hostlist" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
152-
}
153-
154146
run_daemon()
155147
{
156148
# $1 - daemon number : 1,2,3,...

ipset/get_antizapret_domains.sh

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,13 @@ curl -H "Accept-Encoding: gzip" -k --fail --max-time 600 --connect-timeout 5 --r
2121
exit 2
2222
}
2323

24-
composite_list()
25-
{
26-
# combine reestr and user list
27-
if [ -f "$ZUSERLIST_EXCLUDE" ]; then
28-
nice -n 5 $GREP -xvFf "$ZUSERLIST_EXCLUDE" "$ZDOM"
29-
else
30-
cat "$ZDOM"
31-
fi
32-
[ -f "$ZUSERLIST" ] && $AWK '{ print tolower($0) }' <"$ZUSERLIST"
33-
}
34-
3524
dlsize=$(LANG=C wc -c "$ZDOM" | xargs | cut -f 1 -d ' ')
3625
if test $dlsize -lt 102400; then
3726
echo list file is too small. can be bad.
3827
exit 2
3928
fi
4029

41-
composite_list | sort -u | zz "$ZHOSTLIST"
30+
sort -u "$ZDOM" | zz "$ZHOSTLIST"
4231

4332
rm -f "$ZDOM"
4433

ipset/get_reestr_hostlist.sh

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,13 @@ reestr_list()
2626
LANG=C cut -s -f2 -d';' "$ZREESTR" | LANG=C nice -n 5 sed -Ee 's/^\*\.(.+)$/\1/' -ne 's/^[a-z0-9A-Z._-]+$/&/p' | $AWK '{ print tolower($0) }'
2727
}
2828

29-
composite_list()
30-
{
31-
# combine reestr and user list
32-
if [ -f "$ZUSERLIST_EXCLUDE" ]; then
33-
reestr_list | nice -n 5 $GREP -xvFf "$ZUSERLIST_EXCLUDE"
34-
else
35-
reestr_list
36-
fi
37-
[ -f "$ZUSERLIST" ] && $AWK '{ print tolower($0) }' <"$ZUSERLIST"
38-
}
39-
4029
dlsize=$(LANG=C wc -c "$ZREESTR" | xargs | cut -f 1 -d ' ')
4130
if test $dlsize -lt 204800; then
4231
echo list file is too small. can be bad.
4332
exit 2
4433
fi
4534

46-
composite_list | sort -u | zz "$ZHOSTLIST"
35+
reestr_list | sort -u | zz "$ZHOSTLIST"
4736

4837
rm -f "$ZREESTR"
4938

0 commit comments

Comments
 (0)