mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
Compare commits
111 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8b4b8c3fb0 | ||
|
228572afb5 | ||
|
ebb89c48e0 | ||
|
067be122b3 | ||
|
a4632ef6d7 | ||
|
c964677913 | ||
|
e0f8ff06b9 | ||
|
34e632a1f8 | ||
|
4adeb9499b | ||
|
149a7ed927 | ||
|
f22dcb2487 | ||
|
794336a509 | ||
|
d8082fbaec | ||
|
abb3cd3316 | ||
|
7f0eccb39c | ||
|
f8bf9bbb38 | ||
|
1548c86f87 | ||
|
bb74fa765a | ||
|
ee5d4c5017 | ||
|
d04eb28c7f | ||
|
ce2a51a137 | ||
|
4f37c19771 | ||
|
9d43dfdc71 | ||
|
b176af43a4 | ||
|
a6ef91124e | ||
|
1a722c1b78 | ||
|
2452a529eb | ||
|
daac1d2127 | ||
|
acfd844a49 | ||
|
2464d27550 | ||
|
1fdf5477b4 | ||
|
6686c4a190 | ||
|
e979f88963 | ||
|
840292e7d9 | ||
|
43cd263cff | ||
|
d8c07baab7 | ||
|
6e8dbb045a | ||
|
8446470de3 | ||
|
552ddee0da | ||
|
6be62d775b | ||
|
d59c77a899 | ||
|
37b5651976 | ||
|
5572bf7c2b | ||
|
3c7f7c3831 | ||
|
906e67af55 | ||
|
d86aa42f48 | ||
|
8bc5e16ec1 | ||
|
086f15c29f | ||
|
d548d76c1b | ||
|
f649743d70 | ||
|
629e0c5835 | ||
|
2dc7332533 | ||
|
c645e17b0b | ||
|
00e0b28616 | ||
|
de095dd2f2 | ||
|
c6645a0c53 | ||
|
e31a13a158 | ||
|
b058f9f128 | ||
|
d9e539f217 | ||
|
8dc7ebaec4 | ||
|
7f8803afe4 | ||
|
7e4d084c41 | ||
|
7190b00849 | ||
|
ea1545b45c | ||
|
076397eb99 | ||
|
2cbb497cb7 | ||
|
2286996223 | ||
|
d5516dac8a | ||
|
7b07074ad7 | ||
|
a5b68959f3 | ||
|
8e336b746c | ||
|
47578bf891 | ||
|
d596d311e9 | ||
|
cc0de2aa8b | ||
|
852b7bb717 | ||
|
5aa90185b4 | ||
|
438e8a98b3 | ||
|
6b2ce5410a | ||
|
4a81603d05 | ||
|
af6a01f56d | ||
|
a371ca6ea2 | ||
|
83a629b832 | ||
|
5963ba617a | ||
|
ebecc423c7 | ||
|
89ccf0bbc0 | ||
|
1099f248e5 | ||
|
6be111f7b7 | ||
|
33caf4fd4a | ||
|
84fe7817e0 | ||
|
d80e415c63 | ||
|
4d66496cc3 | ||
|
6773370a87 | ||
|
47c08d0ab5 | ||
|
ea97e9ade2 | ||
|
01b3f4d3cf | ||
|
390c9419e8 | ||
|
94cd2212b8 | ||
|
5d4c81d3a5 | ||
|
05978d9b35 | ||
|
e23f61ed7d | ||
|
7171c776db | ||
|
baca5a184d | ||
|
f32df7d701 | ||
|
2fa48f48ea | ||
|
db14cee73b | ||
|
f8ccb564ca | ||
|
20e6ba721a | ||
|
5a5d9f7f31 | ||
|
fbc5b8e491 | ||
|
f1392a3cf1 | ||
|
8ff0b9bab9 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,4 +1,5 @@
|
||||
* text=auto eol=lf
|
||||
binaries/win64/readme.txt eol=crlf
|
||||
binaries/win32/readme.txt eol=crlf
|
||||
*.cmd eol=crlf
|
||||
*.bat eol=crlf
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,10 +1,9 @@
|
||||
config
|
||||
/config
|
||||
ip2net/ip2net
|
||||
mdig/mdig
|
||||
nfq/nfqws
|
||||
tpws/tpws
|
||||
binaries/my/
|
||||
binaries/win64/zapret-winws/autohostlist.txt
|
||||
init.d/**/custom
|
||||
ipset/zapret-ip*.txt
|
||||
ipset/zapret-ip*.gz
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
binaries/win32/WinDivert.dll
Normal file
BIN
binaries/win32/WinDivert.dll
Normal file
Binary file not shown.
BIN
binaries/win32/WinDivert32.sys
Normal file
BIN
binaries/win32/WinDivert32.sys
Normal file
Binary file not shown.
BIN
binaries/win32/cygwin1.dll
Normal file
BIN
binaries/win32/cygwin1.dll
Normal file
Binary file not shown.
BIN
binaries/win32/ip2net.exe
Normal file
BIN
binaries/win32/ip2net.exe
Normal file
Binary file not shown.
BIN
binaries/win32/killall.exe
Normal file
BIN
binaries/win32/killall.exe
Normal file
Binary file not shown.
BIN
binaries/win32/mdig.exe
Normal file
BIN
binaries/win32/mdig.exe
Normal file
Binary file not shown.
8
binaries/win32/readme.txt
Normal file
8
binaries/win32/readme.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
From this folder winws can be started only standalone.
|
||||
To run from cygwin shell delete, rename or move cygwin1.dll.
|
||||
Cygwin refuses to start winws if a copy of cygwin1.dll is present !
|
||||
|
||||
How to get win7 and winws compatible version of cygwin :
|
||||
|
||||
curl -O https://www.cygwin.com/setup-x86_64.exe
|
||||
setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215
|
BIN
binaries/win32/winws.exe
Normal file
BIN
binaries/win32/winws.exe
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,5 @@
|
||||
Standalone version in zapret-winws folder !!
|
||||
From this folder winws can be started only from cygwin shell.
|
||||
|
||||
From this folder winws can be started only standalone.
|
||||
To run from cygwin shell delete, rename or move cygwin1.dll.
|
||||
Cygwin refuses to start winws if a copy of cygwin1.dll is present !
|
||||
|
||||
How to get win7 and winws compatible version of cygwin :
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
googlevideo.com
|
||||
youtubei.googleapis.com
|
||||
i.ytimg.com
|
@@ -1,7 +0,0 @@
|
||||
start "zapret: http,https,quic" /min "%~dp0winws.exe" ^
|
||||
--wf-tcp=80,443 --wf-udp=443 ^
|
||||
--filter-udp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="%~dp0quic_initial_www_google_com.bin" --new ^
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=11 --new ^
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --new ^
|
||||
--filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^
|
||||
--dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig
|
@@ -1,7 +0,0 @@
|
||||
start "zapret: http,https,quic" /min "%~dp0winws.exe" ^
|
||||
--wf-tcp=80,443 --wf-udp=443 ^
|
||||
--filter-udp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="%~dp0quic_initial_www_google_com.bin" --new ^
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=11 --new ^
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --hostlist-auto="%~dp0autohostlist.txt" --new ^
|
||||
--filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^
|
||||
--dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --hostlist-auto="%~dp0autohostlist.txt"
|
Binary file not shown.
@@ -1,12 +0,0 @@
|
||||
set ARGS=--wf-l3=ipv4,ipv6 --wf-tcp=80,443 --dpi-desync=fake,split --dpi-desync-ttl=7 --dpi-desync-fooling=md5sig
|
||||
call :srvinst winws1
|
||||
rem set ARGS=--wf-l3=ipv4,ipv6 --wf-udp=443 --dpi-desync=fake
|
||||
rem call :srvinst winws2
|
||||
goto :eof
|
||||
|
||||
:srvinst
|
||||
net stop %1
|
||||
sc delete %1
|
||||
sc create %1 binPath= "\"%~dp0winws.exe\" %ARGS%" DisplayName= "zapret DPI bypass : %1" start= auto
|
||||
sc description %1 "zapret DPI bypass software"
|
||||
sc start %1
|
@@ -1,7 +0,0 @@
|
||||
call :srvdel winws1
|
||||
rem call :srvdel winws2
|
||||
goto :eof
|
||||
|
||||
:srvdel
|
||||
net stop %1
|
||||
sc delete %1
|
@@ -1,2 +0,0 @@
|
||||
sc start winws1
|
||||
rem sc start winws2
|
@@ -1,2 +0,0 @@
|
||||
net stop winws1
|
||||
rem net stop winws2
|
@@ -1,4 +0,0 @@
|
||||
set WINWS1=--wf-l3=ipv4,ipv6 --wf-tcp=80,443 --dpi-desync=fake,split --dpi-desync-ttl=7 --dpi-desync-fooling=md5sig
|
||||
schtasks /Create /F /TN winws1 /NP /RU "" /SC onstart /TR "\"%~dp0winws.exe\" %WINWS1%"
|
||||
rem set WINWS2=--wf-l3=ipv4,ipv6 --wf-udp=443 --dpi-desync=fake
|
||||
rem schtasks /Create /F /TN winws2 /NP /RU "" /SC onstart /TR "\"%~dp0winws.exe\" %WINWS2%"
|
@@ -1,4 +0,0 @@
|
||||
schtasks /End /TN winws1
|
||||
schtasks /Delete /TN winws1 /F
|
||||
rem schtasks /End /TN winws2
|
||||
rem schtasks /Delete /TN winws2 /F
|
@@ -1,2 +0,0 @@
|
||||
schtasks /Run /TN winws1
|
||||
rem schtasks /Run /TN winws2
|
@@ -1,2 +0,0 @@
|
||||
schtasks /End /TN winws1
|
||||
rem schtasks /End /TN winws2
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
316
blockcheck.sh
316
blockcheck.sh
@@ -53,10 +53,13 @@ NFT_TABLE=blockcheck
|
||||
|
||||
DNSCHECK_DNS=${DNSCHECK_DNS:-8.8.8.8 1.1.1.1 77.88.8.1}
|
||||
DNSCHECK_DOM=${DNSCHECK_DOM:-pornhub.com ntc.party rutracker.org www.torproject.org bbc.com}
|
||||
DOH_SERVERS=${DOH_SERVERS:-"https://cloudflare-dns.com/dns-query https://dns.google/dns-query https://dns.quad9.net/dns-query https://dns.adguard.com/dns-query https://common.dot.dns.yandex.net/dns-query"}
|
||||
DNSCHECK_DIG1=/tmp/dig1.txt
|
||||
DNSCHECK_DIG2=/tmp/dig2.txt
|
||||
DNSCHECK_DIGS=/tmp/digs.txt
|
||||
|
||||
IPSET_FILE=/tmp/blockcheck_ipset.txt
|
||||
|
||||
unset PF_STATUS
|
||||
PF_RULES_SAVE=/tmp/pf-zapret-save.conf
|
||||
|
||||
@@ -129,19 +132,22 @@ opf_dvtws_anchor()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
local family=inet
|
||||
# $3 - ip list
|
||||
local iplist family=inet
|
||||
[ "$IPV" = 6 ] && family=inet6
|
||||
make_comma_list iplist "$3"
|
||||
echo "set reassemble no"
|
||||
[ "$1" = tcp ] && echo "pass in quick $family proto $1 from port $2 flags SA/SA divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
echo "pass in quick $family proto $1 from port $2 no state"
|
||||
echo "pass out quick $family proto $1 to port $2 divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
[ "$1" = tcp ] && echo "pass in quick $family proto $1 from {$iplist} port $2 flags SA/SA divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
echo "pass in quick $family proto $1 from {$iplist} port $2 no state"
|
||||
echo "pass out quick $family proto $1 to {$iplist} port $2 divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
echo "pass"
|
||||
}
|
||||
opf_prepare_dvtws()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
opf_dvtws_anchor $1 $2 | pfctl -qf -
|
||||
# $3 - ip list
|
||||
opf_dvtws_anchor $1 $2 "$3" | pfctl -qf -
|
||||
pfctl -qe
|
||||
}
|
||||
|
||||
@@ -201,6 +207,35 @@ nft_has_nfq()
|
||||
}
|
||||
return $res
|
||||
}
|
||||
|
||||
doh_resolve()
|
||||
{
|
||||
# $1 - ip version 4/6
|
||||
# $2 - hostname
|
||||
# $3 - doh server URL. use $DOH_SERVER if empty
|
||||
$MDIG --family=$1 --dns-make-query=$2 | curl -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | $MDIG --dns-parse-query
|
||||
}
|
||||
doh_find_working()
|
||||
{
|
||||
local doh
|
||||
|
||||
[ -n "$DOH_SERVER" ] && return 0
|
||||
echo "* searching working DoH server"
|
||||
DOH_SERVER=
|
||||
for doh in $DOH_SERVERS; do
|
||||
echo -n "$doh : "
|
||||
if doh_resolve 4 iana.org $doh >/dev/null 2>/dev/null; then
|
||||
echo OK
|
||||
DOH_SERVER="$doh"
|
||||
return 0
|
||||
else
|
||||
echo FAIL
|
||||
fi
|
||||
done
|
||||
echo all DoH servers failed
|
||||
return 1
|
||||
}
|
||||
|
||||
mdig_vars()
|
||||
{
|
||||
# $1 - ip version 4/6
|
||||
@@ -219,7 +254,11 @@ mdig_cache()
|
||||
mdig_vars "$@"
|
||||
[ -n "$count" ] || {
|
||||
# windows version of mdig outputs 0D0A line ending. remove 0D.
|
||||
ips="$(echo $2 | "$MDIG" --family=$1 | tr -d '\r' | xargs)"
|
||||
if [ "$SECURE_DNS" = 1 ]; then
|
||||
ips="$(echo $2 | doh_resolve $1 $2 | tr -d '\r' | xargs)"
|
||||
else
|
||||
ips="$(echo $2 | "$MDIG" --family=$1 | tr -d '\r' | xargs)"
|
||||
fi
|
||||
[ -n "$ips" ] || return 1
|
||||
count=0
|
||||
for ip in $ips; do
|
||||
@@ -360,7 +399,7 @@ zp_already_running()
|
||||
}
|
||||
check_already()
|
||||
{
|
||||
echo \* checking already running zapret processes
|
||||
echo \* checking already running DPI bypass processes
|
||||
if zp_already_running; then
|
||||
echo "!!! WARNING. some dpi bypass processes already running !!!"
|
||||
echo "!!! WARNING. blockcheck requires all DPI bypass methods disabled !!!"
|
||||
@@ -387,7 +426,7 @@ check_prerequisites()
|
||||
{
|
||||
echo \* checking prerequisites
|
||||
|
||||
[ "$UNAME" = Darwin -o -x "$PKTWS" ] && [ "$UNAME" = CYGWIN -o -x "$TPWS" ] && [ -x "$MDIG" ] || {
|
||||
[ "$SKIP_PKTWS" = 1 -o "$UNAME" = Darwin -o -x "$PKTWS" ] && [ "$SKIP_TPWS" = 1 -o "$UNAME" = CYGWIN -o -x "$TPWS" ] && [ -x "$MDIG" ] || {
|
||||
local target
|
||||
case $UNAME in
|
||||
Darwin)
|
||||
@@ -402,58 +441,62 @@ check_prerequisites()
|
||||
}
|
||||
|
||||
local prog progs='curl'
|
||||
case "$UNAME" in
|
||||
Linux)
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
progs="$progs iptables ip6tables"
|
||||
ipt_has_nfq || {
|
||||
echo NFQUEUE iptables or ip6tables target is missing. pls install modules.
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
case "$UNAME" in
|
||||
Linux)
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
ipt_has_nfq || {
|
||||
echo NFQUEUE iptables or ip6tables target is missing. pls install modules.
|
||||
exitp 6
|
||||
}
|
||||
progs="$progs iptables ip6tables"
|
||||
;;
|
||||
nftables)
|
||||
nft_has_nfq || {
|
||||
echo nftables queue support is not available. pls install modules.
|
||||
exitp 6
|
||||
}
|
||||
progs="$progs nft"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
FreeBSD)
|
||||
freebsd_modules_loaded ipfw ipdivert || {
|
||||
echo ipfw or ipdivert kernel module not loaded
|
||||
exitp 6
|
||||
}
|
||||
;;
|
||||
nftables)
|
||||
nft_has_nfq || {
|
||||
echo nftables queue support is not available. pls install modules.
|
||||
exitp 6
|
||||
}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
FreeBSD)
|
||||
progs="$progs ipfw"
|
||||
freebsd_modules_loaded ipfw ipdivert || {
|
||||
echo ipfw or ipdivert kernel module not loaded
|
||||
exitp 6
|
||||
}
|
||||
[ "$(sysctl -qn net.inet.ip.fw.enable)" = 0 -o "$(sysctl -qn net.inet6.ip6.fw.enable)" = 0 ] && {
|
||||
echo ipfw is disabled. use : ipfw enable firewall
|
||||
exitp 6
|
||||
}
|
||||
pf_is_avail && {
|
||||
pf_save
|
||||
[ "$SUBSYS" = "pfSense" ] && {
|
||||
# pfsense's ipfw may not work without these workarounds
|
||||
sysctl net.inet.ip.pfil.outbound=ipfw,pf 2>/dev/null
|
||||
sysctl net.inet.ip.pfil.inbound=ipfw,pf 2>/dev/null
|
||||
sysctl net.inet6.ip6.pfil.outbound=ipfw,pf 2>/dev/null
|
||||
sysctl net.inet6.ip6.pfil.inbound=ipfw,pf 2>/dev/null
|
||||
pfctl -qd
|
||||
pfctl -qe
|
||||
pf_restore
|
||||
}
|
||||
}
|
||||
;;
|
||||
OpenBSD|Darwin)
|
||||
progs="$progs pfctl"
|
||||
pf_is_avail || {
|
||||
echo pf is not available
|
||||
exitp 6
|
||||
}
|
||||
# no divert sockets in MacOS
|
||||
[ "$UNAME" = "Darwin" ] && SKIP_PKTWS=1
|
||||
pf_save
|
||||
;;
|
||||
[ "$(sysctl -qn net.inet.ip.fw.enable)" = 0 -o "$(sysctl -qn net.inet6.ip6.fw.enable)" = 0 ] && {
|
||||
echo ipfw is disabled. use : ipfw enable firewall
|
||||
exitp 6
|
||||
}
|
||||
pf_is_avail && {
|
||||
pf_save
|
||||
[ "$SUBSYS" = "pfSense" ] && {
|
||||
# pfsense's ipfw may not work without these workarounds
|
||||
sysctl net.inet.ip.pfil.outbound=ipfw,pf 2>/dev/null
|
||||
sysctl net.inet.ip.pfil.inbound=ipfw,pf 2>/dev/null
|
||||
sysctl net.inet6.ip6.pfil.outbound=ipfw,pf 2>/dev/null
|
||||
sysctl net.inet6.ip6.pfil.inbound=ipfw,pf 2>/dev/null
|
||||
pfctl -qd
|
||||
pfctl -qe
|
||||
pf_restore
|
||||
}
|
||||
}
|
||||
progs="$progs ipfw"
|
||||
;;
|
||||
OpenBSD|Darwin)
|
||||
pf_is_avail || {
|
||||
echo pf is not available
|
||||
exitp 6
|
||||
}
|
||||
pf_save
|
||||
progs="$progs pfctl"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "$UNAME" in
|
||||
CYGWIN)
|
||||
SKIP_TPWS=1
|
||||
;;
|
||||
@@ -518,7 +561,7 @@ curl_supports_tls13()
|
||||
[ $? = 2 ] && return 1
|
||||
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
||||
# this is online test because there's no other way to trigger library incompatibility case
|
||||
$CURL --tlsv1.3 --max-time $CURL_MAX_TIME -Is -o /dev/null https://w3.org 2>/dev/null
|
||||
$CURL --tlsv1.3 --max-time $CURL_MAX_TIME -Is -o /dev/null https://iana.org 2>/dev/null
|
||||
r=$?
|
||||
[ $r != 4 -a $r != 35 ]
|
||||
}
|
||||
@@ -666,13 +709,12 @@ curl_test_http3()
|
||||
curl_with_dig $1 $2 $QUIC_PORT -ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME_QUIC --http3-only $CURL_OPT "https://$2" -o /dev/null 2>&1
|
||||
}
|
||||
|
||||
ipt_scheme()
|
||||
ipt_aux_scheme()
|
||||
{
|
||||
# $1 - 1 - add , 0 - del
|
||||
# $2 - tcp/udp
|
||||
# $3 - port
|
||||
|
||||
IPT_ADD_DEL $1 OUTPUT -t mangle -p $2 --dport $3 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
|
||||
# to avoid possible INVALID state drop
|
||||
[ "$2" = tcp ] && IPT_ADD_DEL $1 INPUT -p $2 --sport $3 ! --syn -j ACCEPT
|
||||
# for strategies with incoming packets involved (autottl)
|
||||
@@ -688,13 +730,42 @@ ipt_scheme()
|
||||
# raw table may not be present
|
||||
IPT_ADD_DEL $1 OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack
|
||||
}
|
||||
ipt_scheme()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
# $3 - ip list
|
||||
|
||||
local ip
|
||||
|
||||
$IPTABLES -t mangle -N blockcheck_output 2>/dev/null
|
||||
$IPTABLES -t mangle -F blockcheck_output
|
||||
IPT OUTPUT -t mangle -j blockcheck_output
|
||||
|
||||
# prevent loop
|
||||
$IPTABLES -t mangle -A blockcheck_output -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_output ! -p $1 -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_output -p $1 ! --dport $2 -j RETURN
|
||||
|
||||
for ip in $3; do
|
||||
$IPTABLES -t mangle -A blockcheck_output -d $ip -j NFQUEUE --queue-num $QNUM
|
||||
done
|
||||
|
||||
ipt_aux_scheme 1 $1 $2
|
||||
}
|
||||
nft_scheme()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
# $3 - ip list
|
||||
|
||||
local iplist ipver=$IPV
|
||||
[ "$IPV" = 6 ] || ipver=
|
||||
make_comma_list iplist $3
|
||||
|
||||
nft add table inet $NFT_TABLE
|
||||
nft "add chain inet $NFT_TABLE postnat { type filter hook output priority 102; }"
|
||||
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK != $DESYNC_MARK queue num $QNUM"
|
||||
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK != $DESYNC_MARK ip${ipver} daddr {$iplist} queue num $QNUM"
|
||||
# for strategies with incoming packets involved (autottl)
|
||||
nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }"
|
||||
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
|
||||
@@ -706,23 +777,33 @@ pktws_ipt_prepare()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
# $3 - ip list
|
||||
|
||||
local ip
|
||||
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
ipt_scheme 1 $1 $2
|
||||
ipt_scheme $1 $2 "$3"
|
||||
;;
|
||||
nftables)
|
||||
nft_scheme $1 $2
|
||||
nft_scheme $1 $2 "$3"
|
||||
;;
|
||||
ipfw)
|
||||
# disable PF to avoid interferences
|
||||
pf_is_avail && pfctl -qd
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to any $2 proto ip${IPV} out not diverted not sockarg
|
||||
for ip in $3; do
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted not sockarg
|
||||
done
|
||||
;;
|
||||
opf)
|
||||
opf_prepare_dvtws $1 $2
|
||||
opf_prepare_dvtws $1 $2 "$3"
|
||||
;;
|
||||
windivert)
|
||||
WF="--wf-l3=ipv${IPV} --wf-${1}=$2"
|
||||
rm -f "$IPSET_FILE"
|
||||
for ip in $3; do
|
||||
echo $ip >>"$IPSET_FILE"
|
||||
done
|
||||
;;
|
||||
|
||||
esac
|
||||
@@ -731,9 +812,13 @@ pktws_ipt_unprepare()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
ipt_scheme 0 $1 $2
|
||||
ipt_aux_scheme 0 $1 $2
|
||||
IPT_DEL OUTPUT -t mangle -j blockcheck_output
|
||||
$IPTABLES -t mangle -F blockcheck_output 2>/dev/null
|
||||
$IPTABLES -t mangle -X blockcheck_output 2>/dev/null
|
||||
;;
|
||||
nftables)
|
||||
nft delete table inet $NFT_TABLE 2>/dev/null
|
||||
@@ -747,6 +832,7 @@ pktws_ipt_unprepare()
|
||||
;;
|
||||
windivert)
|
||||
unset WF
|
||||
rm -f "$IPSET_FILE"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -754,21 +840,35 @@ pktws_ipt_unprepare()
|
||||
pktws_ipt_prepare_tcp()
|
||||
{
|
||||
# $1 - port
|
||||
# $2 - ip list
|
||||
|
||||
pktws_ipt_prepare tcp $1
|
||||
local ip iplist ipver
|
||||
|
||||
pktws_ipt_prepare tcp $1 "$2"
|
||||
|
||||
# for autottl mode
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
# for autottl
|
||||
IPT INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
|
||||
$IPTABLES -N blockcheck_input -t mangle 2>/dev/null
|
||||
$IPTABLES -F blockcheck_input -t mangle 2>/dev/null
|
||||
IPT INPUT -t mangle -j blockcheck_input
|
||||
$IPTABLES -t mangle -A blockcheck_input ! -p tcp -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_input -p tcp ! --sport $1 -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_input -p tcp ! --tcp-flags SYN,ACK SYN,ACK -j RETURN
|
||||
for ip in $2; do
|
||||
$IPTABLES -A blockcheck_input -t mangle -s $ip -j NFQUEUE --queue-num $QNUM
|
||||
done
|
||||
;;
|
||||
nftables)
|
||||
# for autottl
|
||||
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 ct original packets 1 queue num $QNUM"
|
||||
ipver=$IPV
|
||||
[ "$IPV" = 6 ] || ipver=
|
||||
make_comma_list iplist $2
|
||||
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 tcp flags & (syn | ack) == (syn | ack) ip${ipver} saddr {$iplist} queue num $QNUM"
|
||||
;;
|
||||
ipfw)
|
||||
# for autottl mode
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from any $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg
|
||||
for ip in $2; do
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg
|
||||
done
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -780,15 +880,18 @@ pktws_ipt_unprepare_tcp()
|
||||
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
IPT_DEL INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
|
||||
IPT_DEL INPUT -t mangle -j blockcheck_input
|
||||
$IPTABLES -t mangle -F blockcheck_input 2>/dev/null
|
||||
$IPTABLES -t mangle -X blockcheck_input 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
}
|
||||
pktws_ipt_prepare_udp()
|
||||
{
|
||||
# $1 - port
|
||||
# $2 - ip list
|
||||
|
||||
pktws_ipt_prepare udp $1
|
||||
pktws_ipt_prepare udp $1 "$2"
|
||||
}
|
||||
pktws_ipt_unprepare_udp()
|
||||
{
|
||||
@@ -807,7 +910,7 @@ pktws_start()
|
||||
"$DVTWS" --port=$IPFW_DIVERT_PORT "$@" >/dev/null &
|
||||
;;
|
||||
CYGWIN)
|
||||
"$WINWS" $WF "$@" >/dev/null &
|
||||
"$WINWS" $WF --ipset="$IPSET_FILE" "$@" >/dev/null &
|
||||
;;
|
||||
esac
|
||||
PID=$!
|
||||
@@ -816,7 +919,9 @@ pktws_start()
|
||||
}
|
||||
tpws_start()
|
||||
{
|
||||
"$TPWS" --uid $TPWS_UID:$TPWS_GID --socks --bind-addr=127.0.0.1 --port=$SOCKS_PORT "$@" >/dev/null &
|
||||
local uid
|
||||
[ -n "$HAVE_ROOT" ] && uid="--uid $TPWS_UID:$TPWS_GID"
|
||||
"$TPWS" $uid --socks --bind-addr=127.0.0.1 --port=$SOCKS_PORT "$@" >/dev/null &
|
||||
PID=$!
|
||||
# give some time to initialize
|
||||
minsleep
|
||||
@@ -905,17 +1010,17 @@ tpws_curl_test()
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
# $3,$4,$5, ... - tpws params
|
||||
echo - checking tpws $3 $4 $5 $6 $7 $8 $9 $TPWS_EXTRA "$TPWS_EXTRA_1" "$TPWS_EXTRA_2" "$TPWS_EXTRA_3" "$TPWS_EXTRA_4" "$TPWS_EXTRA_5" "$TPWS_EXTRA_6" "$TPWS_EXTRA_7" "$TPWS_EXTRA_8" "$TPWS_EXTRA_9"
|
||||
echo - checking tpws $3 $4 $5 $6 $7 $8 $9${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||
local ALL_PROXY="socks5://127.0.0.1:$SOCKS_PORT"
|
||||
ws_curl_test tpws_start "$@" $TPWS_EXTRA "$TPWS_EXTRA_1" "$TPWS_EXTRA_2" "$TPWS_EXTRA_3" "$TPWS_EXTRA_4" "$TPWS_EXTRA_5" "$TPWS_EXTRA_6" "$TPWS_EXTRA_7" "$TPWS_EXTRA_8" "$TPWS_EXTRA_9"
|
||||
ws_curl_test tpws_start "$@"${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||
}
|
||||
pktws_curl_test()
|
||||
{
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
# $3,$4,$5, ... - nfqws/dvtws params
|
||||
echo - checking $PKTWSD ${WF:+$WF }$3 $4 $5 $6 $7 $8 $9 $PKTWS_EXTRA "$PKTWS_EXTRA_1" "$PKTWS_EXTRA_2" "$PKTWS_EXTRA_3" "$PKTWS_EXTRA_4" "$PKTWS_EXTRA_5" "$PKTWS_EXTRA_6" "$PKTWS_EXTRA_7" "$PKTWS_EXTRA_8" "$PKTWS_EXTRA_9"
|
||||
ws_curl_test pktws_start "$@" $PKTWS_EXTRA "$PKTWS_EXTRA_1" "$PKTWS_EXTRA_2" "$PKTWS_EXTRA_3" "$PKTWS_EXTRA_4" "$PKTWS_EXTRA_5" "$PKTWS_EXTRA_6" "$PKTWS_EXTRA_7" "$PKTWS_EXTRA_8" "$PKTWS_EXTRA_9"
|
||||
echo - checking $PKTWSD ${WF:+$WF }$3 $4 $5 $6 $7 $8 $9${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
ws_curl_test pktws_start "$@"${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
}
|
||||
xxxws_curl_test_update()
|
||||
{
|
||||
@@ -1173,7 +1278,7 @@ pktws_check_domain_http_bypass()
|
||||
|
||||
local strategy
|
||||
pktws_check_domain_http_bypass_ "$@"
|
||||
strategy="${strategy:+$strategy $PKTWS_EXTRA $PKTWS_EXTRA_1 $PKTWS_EXTRA_2 $PKTWS_EXTRA_3 $PKTWS_EXTRA_4 $PKTWS_EXTRA_5 $PKTWS_EXTRA_6 $PKTWS_EXTRA_7 $PKTWS_EXTRA_8 $PKTWS_EXTRA_9}"
|
||||
strategy="${strategy:+$strategy${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}}"
|
||||
report_strategy $1 $3 $PKTWSD
|
||||
}
|
||||
|
||||
@@ -1181,7 +1286,7 @@ pktws_check_domain_http3_bypass_()
|
||||
{
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
|
||||
|
||||
local f desync frag tests rep
|
||||
|
||||
for rep in '' 2 5 10 20; do
|
||||
@@ -1288,7 +1393,7 @@ tpws_check_domain_http_bypass()
|
||||
|
||||
local strategy
|
||||
tpws_check_domain_http_bypass_ "$@"
|
||||
strategy="${strategy:+$strategy $TPWS_EXTRA $TPWS_EXTRA_1 $TPWS_EXTRA_2 $TPWS_EXTRA_3 $TPWS_EXTRA_4 $TPWS_EXTRA_5 $TPWS_EXTRA_6 $TPWS_EXTRA_7 $TPWS_EXTRA_8 $TPWS_EXTRA_9}"
|
||||
strategy="${strategy:+$strategy${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}}"
|
||||
report_strategy $1 $3 tpws
|
||||
}
|
||||
|
||||
@@ -1379,7 +1484,7 @@ check_domain_http_tcp()
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
echo
|
||||
echo preparing $PKTWSD redirection
|
||||
pktws_ipt_prepare_tcp $2
|
||||
pktws_ipt_prepare_tcp $2 "$(mdig_resolve_all $IPV $4)"
|
||||
|
||||
pktws_check_domain_http_bypass $1 $3 $4
|
||||
|
||||
@@ -1402,7 +1507,7 @@ check_domain_http_udp()
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
echo
|
||||
echo preparing $PKTWSD redirection
|
||||
pktws_ipt_prepare_udp $2
|
||||
pktws_ipt_prepare_udp $2 "$(mdig_resolve_all $IPV $3)"
|
||||
|
||||
pktws_check_domain_http3_bypass $1 $3
|
||||
|
||||
@@ -1605,7 +1710,7 @@ ask_params()
|
||||
SCANLEVEL=${SCANLEVEL:-standard}
|
||||
ask_list SCANLEVEL "quick standard force" "$SCANLEVEL"
|
||||
# disable tpws checks by default in quick mode
|
||||
[ "$SCANLEVEL" = quick -a -z "$SKIP_TPWS" ] && SKIP_TPWS=1
|
||||
[ "$SCANLEVEL" = quick -a -z "$SKIP_TPWS" -a "$UNAME" != Darwin ] && SKIP_TPWS=1
|
||||
|
||||
echo
|
||||
|
||||
@@ -1677,7 +1782,7 @@ pingtest()
|
||||
dnstest()
|
||||
{
|
||||
# $1 - dns server. empty for system resolver
|
||||
"$LOOKUP" w3.org $1 >/dev/null 2>/dev/null
|
||||
"$LOOKUP" iana.org $1 >/dev/null 2>/dev/null
|
||||
}
|
||||
find_working_public_dns()
|
||||
{
|
||||
@@ -1722,10 +1827,14 @@ check_dns_cleanup()
|
||||
{
|
||||
rm -f "$DNSCHECK_DIG1" "$DNSCHECK_DIG2" "$DNSCHECK_DIGS" 2>/dev/null
|
||||
}
|
||||
check_dns()
|
||||
check_dns_()
|
||||
{
|
||||
local C1 C2 dom
|
||||
|
||||
DNS_IS_SPOOFED=0
|
||||
|
||||
[ "$SKIP_DNSCHECK" = 1 ] && return 0
|
||||
|
||||
echo \* checking DNS
|
||||
|
||||
[ -f "$DNSCHECK_DIGS" ] && rm -f "$DNSCHECK_DIGS"
|
||||
@@ -1748,6 +1857,7 @@ check_dns()
|
||||
check_dns_cleanup
|
||||
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
||||
echo -- DNS CHANGE OR DNSCRYPT MAY BE REQUIRED
|
||||
DNS_IS_SPOOFED=1
|
||||
return 1
|
||||
else
|
||||
echo $dom : OK
|
||||
@@ -1759,8 +1869,8 @@ check_dns()
|
||||
for dom in $DNSCHECK_DOM; do echo $dom; done | "$MDIG" --threads=10 --family=4 >"$DNSCHECK_DIGS"
|
||||
fi
|
||||
|
||||
echo checking resolved IP uniqueness for : $DNSCHECK_DOM
|
||||
echo censor\'s DNS can return equal result for multiple blocked domains.
|
||||
echo "checking resolved IP uniqueness for : $DNSCHECK_DOM"
|
||||
echo "censor's DNS can return equal result for multiple blocked domains."
|
||||
C1=$(wc -l <"$DNSCHECK_DIGS")
|
||||
C2=$(sort -u "$DNSCHECK_DIGS" | wc -l)
|
||||
[ "$C1" -eq 0 ] &&
|
||||
@@ -1777,6 +1887,7 @@ check_dns()
|
||||
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
||||
echo -- DNSCRYPT MAY BE REQUIRED
|
||||
check_dns_cleanup
|
||||
DNS_IS_SPOOFED=1
|
||||
return 1
|
||||
}
|
||||
echo all resolved IPs are unique
|
||||
@@ -1786,6 +1897,20 @@ check_dns()
|
||||
return 0
|
||||
}
|
||||
|
||||
check_dns()
|
||||
{
|
||||
local r
|
||||
check_dns_
|
||||
r=$?
|
||||
[ "$DNS_IS_SPOOFED" = 1 ] && SECURE_DNS=${SECURE_DNS:-1}
|
||||
[ "$SECURE_DNS" = 1 ] && {
|
||||
doh_find_working || {
|
||||
echo could not find working DoH server. exiting.
|
||||
exitp 7
|
||||
}
|
||||
}
|
||||
return $r
|
||||
}
|
||||
|
||||
unprepare_all()
|
||||
{
|
||||
@@ -1818,14 +1943,17 @@ sigsilent()
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
fsleep_setup
|
||||
fix_sbin_path
|
||||
check_system
|
||||
check_already
|
||||
[ "$UNAME" = CYGWIN ] || require_root
|
||||
# no divert sockets in MacOS
|
||||
[ "$UNAME" = "Darwin" ] && SKIP_PKTWS=1
|
||||
[ "$UNAME" != CYGWIN -a "$SKIP_PKTWS" != 1 ] && require_root
|
||||
check_prerequisites
|
||||
trap sigint_cleanup INT
|
||||
[ "$SKIP_DNSCHECK" = 1 ] || check_dns
|
||||
check_dns
|
||||
check_virt
|
||||
ask_params
|
||||
trap - INT
|
||||
|
@@ -62,6 +62,10 @@ starts_with()
|
||||
}
|
||||
find_str_in_list()
|
||||
{
|
||||
# $1 - string
|
||||
# $2 - space separated values
|
||||
|
||||
local v
|
||||
[ -n "$1" ] && {
|
||||
for v in $2; do
|
||||
[ "$v" = "$1" ] && return 0
|
||||
@@ -74,6 +78,19 @@ end_with_newline()
|
||||
local c="$(tail -c 1)"
|
||||
[ "$c" = "" ]
|
||||
}
|
||||
trim()
|
||||
{
|
||||
awk '{gsub(/^ +| +$/,"")}1'
|
||||
}
|
||||
|
||||
dir_is_not_empty()
|
||||
{
|
||||
# $1 - directory
|
||||
local n
|
||||
[ -d "$1" ] || return 1
|
||||
n=$(ls "$1" | wc -c | xargs)
|
||||
[ "$n" != 0 ]
|
||||
}
|
||||
|
||||
append_separator_list()
|
||||
{
|
||||
@@ -275,6 +292,14 @@ replace_char()
|
||||
echo "$@" | tr $a $b
|
||||
}
|
||||
|
||||
replace_str()
|
||||
{
|
||||
local a=$(echo "$1" | sed 's/\//\\\//g')
|
||||
local b=$(echo "$2" | sed 's/\//\\\//g')
|
||||
shift; shift
|
||||
echo "$@" | sed "s/$a/$b/g"
|
||||
}
|
||||
|
||||
setup_md5()
|
||||
{
|
||||
[ -n "$MD5" ] && return
|
||||
@@ -329,12 +354,62 @@ win_process_exists()
|
||||
tasklist /NH /FI "IMAGENAME eq ${1}.exe" | grep -q "^${1}.exe"
|
||||
}
|
||||
|
||||
alloc_num()
|
||||
{
|
||||
# $1 - source var name
|
||||
# $2 - target var name
|
||||
# $3 - min
|
||||
# $4 - max
|
||||
|
||||
local v
|
||||
eval v="\$$2"
|
||||
# do not replace existing value
|
||||
[ -n "$v" ] && return
|
||||
eval v="\$$1"
|
||||
[ -n "$v" ] || v=$3
|
||||
eval $2="$v"
|
||||
v=$((v + 1))
|
||||
[ $v -gt $4 ] && v=$3
|
||||
eval $1="$v"
|
||||
}
|
||||
|
||||
std_ports()
|
||||
{
|
||||
HTTP_PORTS=${HTTP_PORTS:-80}
|
||||
HTTPS_PORTS=${HTTPS_PORTS:-443}
|
||||
QUIC_PORTS=${QUIC_PORTS:-443}
|
||||
HTTP_PORTS_IPT=$(replace_char - : $HTTP_PORTS)
|
||||
HTTPS_PORTS_IPT=$(replace_char - : $HTTPS_PORTS)
|
||||
QUIC_PORTS_IPT=$(replace_char - : $QUIC_PORTS)
|
||||
TPWS_PORTS_IPT=$(replace_char - : $TPWS_PORTS)
|
||||
NFQWS_PORTS_TCP_IPT=$(replace_char - : $NFQWS_PORTS_TCP)
|
||||
NFQWS_PORTS_TCP_KEEPALIVE_IPT=$(replace_char - : $NFQWS_PORTS_TCP_KEEPALIVE)
|
||||
NFQWS_PORTS_UDP_IPT=$(replace_char - : $NFQWS_PORTS_UDP)
|
||||
NFQWS_PORTS_UDP_KEEPALIVE_IPT=$(replace_char - : $NFQWS_PORTS_UDP_KEEPALIVE)
|
||||
}
|
||||
|
||||
has_bad_ws_options()
|
||||
{
|
||||
# $1 - nfqws/tpws opts
|
||||
# ПРИМЕЧАНИЕ ДЛЯ РАСПРОСТРАНИТЕЛЕЙ КОПИПАСТЫ
|
||||
# ЭТОТ КОД СДЕЛАН СПЕЦИАЛЬНО ДЛЯ ВАС, ЧТОБЫ ВЫ НЕ ПОСТИЛИ В СЕТЬ ПЛОХИЕ РЕЦЕПТЫ
|
||||
# ЕСЛИ ВАМ ХОЧЕТСЯ ЕГО УДАЛИТЬ И НАПИСАТЬ ИНСТРУКЦИЮ КАК ЕГО УДАЛЯТЬ, ВЫ ДЕЛАЕТЕ ХРЕНОВУЮ УСЛУГУ. НАПИШИТЕ ЛУЧШЕ custom script.
|
||||
# custom script - ЭТО ФАЙЛИК, КОТОРЫЙ ДОСТАТОЧНО СКОПИРОВАТЬ В НУЖНУЮ ДИРЕКТОРИЮ, ЧТОБЫ ОН СДЕЛАЛ ТОЖЕ САМОЕ, НО ЭФФЕКТИВНО.
|
||||
# ФИЛЬТРАЦИЯ ПО IPSET В ЯДРЕ НЕСРАВНИМО ЭФФЕКТИВНЕЕ, ЧЕМ ПЕРЕКИДЫВАТЬ ВСЕ ПАКЕТЫ В nfqws И ТАМ ФИЛЬТРОВАТЬ
|
||||
# --ipset СУЩЕСТВУЕТ ТОЛЬКО ДЛЯ ВИНДЫ И LINUX СИСТЕМ БЕЗ ipset (НАПРИМЕР, Android).
|
||||
# И ТОЛЬКО ПО ЭТОЙ ПРИЧИНЕ ОНО НЕ ВЫКИНУТО ПОЛНОСТЬЮ ИЗ LINUX ВЕРСИИ
|
||||
contains "$1" "--ipset"
|
||||
}
|
||||
check_bad_ws_options()
|
||||
{
|
||||
# $1 - 0 = stop, 1 = start
|
||||
# $2 - nfqws/tpws options
|
||||
if [ "$1" = 1 ] && has_bad_ws_options "$2"; then
|
||||
echo "!!! REFUSING TO USE BAD OPTIONS : $2"
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
help_bad_ws_options()
|
||||
{
|
||||
echo "WARNING ! you have specified --ipset option"
|
||||
echo "WARNING ! it would work but on $UNAME it's not the best option"
|
||||
echo "WARNING ! you should use kernel mode sets. they are much more efficient."
|
||||
echo "WARNING ! to use ipsets you have to write your own custom script"
|
||||
echo "WARNING ! installer will stop here to prevent distribution of easy to use but bad copy-paste solutions"
|
||||
}
|
||||
|
@@ -7,15 +7,10 @@ custom_runner()
|
||||
|
||||
shift
|
||||
|
||||
[ -f "$CUSTOM_DIR/custom" ] && {
|
||||
unset -f $FUNC
|
||||
. "$CUSTOM_DIR/custom"
|
||||
existf $FUNC && $FUNC "$@"
|
||||
}
|
||||
[ -d "$CUSTOM_DIR/custom.d" ] && {
|
||||
n=$(ls "$CUSTOM_DIR/custom.d" | wc -c | xargs)
|
||||
[ "$n" = 0 ] || {
|
||||
dir_is_not_empty "$CUSTOM_DIR/custom.d" && {
|
||||
for script in "$CUSTOM_DIR/custom.d/"*; do
|
||||
[ -f "$script" ] || continue
|
||||
unset -f $FUNC
|
||||
. "$script"
|
||||
existf $FUNC && $FUNC "$@"
|
||||
@@ -23,3 +18,20 @@ custom_runner()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alloc_tpws_port()
|
||||
{
|
||||
# $1 - target var name
|
||||
alloc_num NUMPOOL_TPWS_PORT $1 910 979
|
||||
}
|
||||
alloc_qnum()
|
||||
{
|
||||
# $1 - target var name
|
||||
alloc_num NUMPOOL_QNUM $1 65400 65499
|
||||
}
|
||||
alloc_dnum()
|
||||
{
|
||||
# alloc daemon number
|
||||
# $1 - target var name
|
||||
alloc_num NUMPOOL_DNUM $1 1000 1999
|
||||
}
|
||||
|
@@ -1,13 +1,28 @@
|
||||
require_root()
|
||||
{
|
||||
local exe
|
||||
local exe preserve_env
|
||||
echo \* checking privileges
|
||||
[ $(id -u) -ne "0" ] && {
|
||||
echo root is required
|
||||
exe="$EXEDIR/$(basename "$0")"
|
||||
exists sudo && exec sudo sh "$exe"
|
||||
exists su && exec su root -c "sh \"$exe\""
|
||||
exists sudo && {
|
||||
echo elevating with sudo
|
||||
exec sudo -E sh "$exe"
|
||||
}
|
||||
exists su && {
|
||||
echo elevating with su
|
||||
case "$UNAME" in
|
||||
Linux)
|
||||
preserve_env="--preserve-environment"
|
||||
;;
|
||||
FreeBSD|OpenBSD|Darwin)
|
||||
preserve_env="-m"
|
||||
;;
|
||||
esac
|
||||
exec su $preserve_env root -c "sh \"$exe\""
|
||||
}
|
||||
echo su or sudo not found
|
||||
exitp 2
|
||||
}
|
||||
HAVE_ROOT=1
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
GET_LIST_PREFIX=/ipset/get_
|
||||
readonly GET_LIST_PREFIX=/ipset/get_
|
||||
|
||||
SYSTEMD_DIR=/lib/systemd
|
||||
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
|
||||
@@ -15,13 +15,99 @@ exitp()
|
||||
exit $1
|
||||
}
|
||||
|
||||
extract_var_def()
|
||||
{
|
||||
# $1 - var name
|
||||
# this sed script parses single or multi line shell var assignments with optional ' or " enclosure
|
||||
sed -n \
|
||||
"/^$1=\"/ {
|
||||
:s1
|
||||
/\".*\"/ {
|
||||
p
|
||||
b
|
||||
}
|
||||
N
|
||||
t c1
|
||||
b s1
|
||||
:c1
|
||||
}
|
||||
/^$1='/ {
|
||||
:s2
|
||||
/'.*'/ {
|
||||
p
|
||||
b
|
||||
}
|
||||
N
|
||||
t c2
|
||||
b s2
|
||||
:c2
|
||||
}
|
||||
/^$1=/p
|
||||
"
|
||||
}
|
||||
replace_var_def()
|
||||
{
|
||||
# $1 - var name
|
||||
# $2 - new val
|
||||
# $3 - conf file
|
||||
# this sed script replaces single or multi line shell var assignments with optional ' or " enclosure
|
||||
local repl
|
||||
if [ -z "$2" ]; then
|
||||
repl="#$1="
|
||||
elif contains "$2" " "; then
|
||||
repl="$1=\"$2\""
|
||||
else
|
||||
repl="$1=$2"
|
||||
fi
|
||||
local script=\
|
||||
"/^#*[[:space:]]*$1=\"/ {
|
||||
:s1
|
||||
/\".*\"/ {
|
||||
c\\
|
||||
$repl
|
||||
b
|
||||
}
|
||||
N
|
||||
t c1
|
||||
b s1
|
||||
:c1
|
||||
}
|
||||
/^#*[[:space:]]*$1='/ {
|
||||
:s2
|
||||
/'.*'/ {
|
||||
c\\
|
||||
$repl
|
||||
b
|
||||
}
|
||||
N
|
||||
t c2
|
||||
b s2
|
||||
:c2
|
||||
}
|
||||
/^#*[[:space:]]*$1=/c\\
|
||||
$repl"
|
||||
# there's incompatibility with -i option on MacOS/BSD and busybox/GNU
|
||||
if [ "$UNAME" = "Linux" ]; then
|
||||
sed -i -e "$script" "$3"
|
||||
else
|
||||
sed -i '' -e "$script" "$3"
|
||||
fi
|
||||
}
|
||||
|
||||
parse_var_checked()
|
||||
{
|
||||
# $1 - file name
|
||||
# $2 - var name
|
||||
local sed="sed -nre s/^[[:space:]]*$2=[\\\"|\']?([^\\\"|\']*)[\\\"|\']?/\1/p"
|
||||
local v="$($sed <"$1" | tail -n 1)"
|
||||
eval $2=\"$v\"
|
||||
|
||||
local tmp="/tmp/zvar-pid-$$.sh"
|
||||
local v
|
||||
cat "$1" | extract_var_def "$2" >"$tmp"
|
||||
. "$tmp"
|
||||
rm -f "$tmp"
|
||||
eval v="\$$2"
|
||||
# trim
|
||||
v="$(echo "$v" | trim)"
|
||||
eval $2=\""$v"\"
|
||||
}
|
||||
parse_vars_checked()
|
||||
{
|
||||
@@ -48,22 +134,44 @@ edit_file()
|
||||
}
|
||||
[ -n "$ed" ] && "$ed" "$1"
|
||||
}
|
||||
echo_var()
|
||||
{
|
||||
local v
|
||||
eval v="\$$1"
|
||||
if find_str_in_list $1 "$EDITVAR_NEWLINE_VARS"; then
|
||||
echo "$1=\""
|
||||
echo "$v\"" | sed "s/$EDITVAR_NEWLINE_DELIMETER /$EDITVAR_NEWLINE_DELIMETER\n/g"
|
||||
else
|
||||
if contains "$v" " "; then
|
||||
echo $1=\"$v\"
|
||||
else
|
||||
echo $1=$v
|
||||
fi
|
||||
fi
|
||||
}
|
||||
edit_vars()
|
||||
{
|
||||
# $1,$2,... - var names
|
||||
local n=1 var v tmp="/tmp/zvars"
|
||||
local n=1 var tmp="/tmp/zvars-pid-$$.txt"
|
||||
rm -f "$tmp"
|
||||
while [ 1=1 ]; do
|
||||
while : ; do
|
||||
eval var="\${$n}"
|
||||
[ -n "$var" ] || break
|
||||
eval v="\$$var"
|
||||
echo $var=\"$v\" >>"$tmp"
|
||||
echo_var $var >> "$tmp"
|
||||
n=$(($n+1))
|
||||
done
|
||||
edit_file "$tmp" && parse_vars_checked "$tmp" "$@"
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
list_vars()
|
||||
{
|
||||
while [ -n "$1" ] ; do
|
||||
echo_var $1
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
openrc_test()
|
||||
{
|
||||
exists rc-update || return 1
|
||||
@@ -483,30 +591,14 @@ write_config_var()
|
||||
# $1 - mode var
|
||||
local M
|
||||
eval M="\$$1"
|
||||
|
||||
if grep -q "^$1=\|^#$1=" "$ZAPRET_CONFIG"; then
|
||||
# replace / => \/
|
||||
#M=${M//\//\\\/}
|
||||
M=$(echo $M | sed 's/\//\\\//g')
|
||||
if [ -n "$M" ]; then
|
||||
if contains "$M" " "; then
|
||||
sedi -Ee "s/^#?$1=.*$/$1=\"$M\"/" "$ZAPRET_CONFIG"
|
||||
else
|
||||
sedi -Ee "s/^#?$1=.*$/$1=$M/" "$ZAPRET_CONFIG"
|
||||
fi
|
||||
else
|
||||
# write with comment at the beginning
|
||||
sedi -Ee "s/^#?$1=.*$/#$1=/" "$ZAPRET_CONFIG"
|
||||
fi
|
||||
else
|
||||
# replace / => \/
|
||||
#M=${M//\//\\\/}
|
||||
M=$(echo $M | sed 's/\//\\\//g' | trim)
|
||||
grep -q "^[[:space:]]*$1=\|^#*[[:space:]]*$1=" "$ZAPRET_CONFIG" || {
|
||||
# var does not exist in config. add it
|
||||
contains "$M" " " && M="\"$M\""
|
||||
if [ -n "$M" ]; then
|
||||
echo "$1=$M" >>"$ZAPRET_CONFIG"
|
||||
else
|
||||
echo "#$1=$M" >>"$ZAPRET_CONFIG"
|
||||
fi
|
||||
fi
|
||||
echo $1= >>"$ZAPRET_CONFIG"
|
||||
}
|
||||
replace_var_def $1 "$M" "$ZAPRET_CONFIG"
|
||||
}
|
||||
|
||||
check_prerequisites_linux()
|
||||
|
195
common/ipt.sh
195
common/ipt.sh
@@ -3,15 +3,15 @@ readonly ipt_connbytes="-m connbytes --connbytes-dir=original --connbytes-mode=p
|
||||
|
||||
ipt()
|
||||
{
|
||||
iptables -C "$@" >/dev/null 2>/dev/null || iptables -I "$@"
|
||||
iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null || iptables $FW_EXTRA_PRE -I "$@" $FW_EXTRA_POST
|
||||
}
|
||||
ipta()
|
||||
{
|
||||
iptables -C "$@" >/dev/null 2>/dev/null || iptables -A "$@"
|
||||
iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null || iptables $FW_EXTRA_PRE -A "$@" $FW_EXTRA_POST
|
||||
}
|
||||
ipt_del()
|
||||
{
|
||||
iptables -C "$@" >/dev/null 2>/dev/null && iptables -D "$@"
|
||||
iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null && iptables $FW_EXTRA_PRE -D "$@" $FW_EXTRA_POST
|
||||
}
|
||||
ipt_add_del()
|
||||
{
|
||||
@@ -48,28 +48,6 @@ is_ipt_flow_offload_avail()
|
||||
grep -q FLOWOFFLOAD 2>/dev/null /proc/net/ip$1_tables_targets
|
||||
}
|
||||
|
||||
filter_apply_port_target()
|
||||
{
|
||||
# $1 - var name of iptables filter
|
||||
local f
|
||||
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
||||
f="-p tcp -m multiport --dports $HTTP_PORTS_IPT,$HTTPS_PORTS_IPT"
|
||||
elif [ "$MODE_HTTPS" = "1" ]; then
|
||||
f="-p tcp -m multiport --dports $HTTPS_PORTS_IPT"
|
||||
elif [ "$MODE_HTTP" = "1" ]; then
|
||||
f="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
||||
else
|
||||
echo WARNING !!! HTTP and HTTPS are both disabled
|
||||
fi
|
||||
eval $1="\"\$$1 $f\""
|
||||
}
|
||||
filter_apply_port_target_quic()
|
||||
{
|
||||
# $1 - var name of nftables filter
|
||||
local f
|
||||
f="-p udp -m multiport --dports $QUIC_PORTS_IPT"
|
||||
eval $1="\"\$$1 $f\""
|
||||
}
|
||||
filter_apply_ipset_target4()
|
||||
{
|
||||
# $1 - var name of ipv4 iptables filter
|
||||
@@ -134,7 +112,7 @@ unprepare_tpws_fw()
|
||||
ipt_print_op()
|
||||
{
|
||||
if [ "$1" = "1" ]; then
|
||||
echo "Adding ip$4tables rule for $3 : $2"
|
||||
echo "Inserting ip$4tables rule for $3 : $2"
|
||||
else
|
||||
echo "Deleting ip$4tables rule for $3 : $2"
|
||||
fi
|
||||
@@ -220,7 +198,7 @@ _fw_nfqws_post4()
|
||||
|
||||
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)"
|
||||
|
||||
rule="$2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
rule="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
if [ -n "$4" ] ; then
|
||||
for i in $4; do
|
||||
ipt_add_del $1 POSTROUTING -t mangle -o $i $rule
|
||||
@@ -241,7 +219,7 @@ _fw_nfqws_post6()
|
||||
|
||||
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" 6
|
||||
|
||||
rule="$2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
rule="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
if [ -n "$4" ] ; then
|
||||
for i in $4; do
|
||||
ipt6_add_del $1 POSTROUTING -t mangle -o $i $rule
|
||||
@@ -320,27 +298,13 @@ fw_nfqws_pre()
|
||||
}
|
||||
|
||||
|
||||
produce_reverse_nfqws_rule()
|
||||
{
|
||||
local rule="$1"
|
||||
if contains "$rule" "$ipt_connbytes"; then
|
||||
# autohostlist - need several incoming packets
|
||||
# autottl - need only one incoming packet
|
||||
[ "$MODE_FILTER" = autohostlist ] || rule=$(echo "$rule" | sed -re "s/$ipt_connbytes [0-9]+:[0-9]+/$ipt_connbytes 1:1/")
|
||||
else
|
||||
local n=1
|
||||
[ "$MODE_FILTER" = autohostlist ] && n=$(first_packets_for_mode)
|
||||
rule="$ipt_connbytes 1:$n $rule"
|
||||
fi
|
||||
echo "$rule" | reverse_nfqws_rule_stream
|
||||
}
|
||||
fw_reverse_nfqws_rule4()
|
||||
{
|
||||
fw_nfqws_pre4 $1 "$(produce_reverse_nfqws_rule "$2")" $3
|
||||
fw_nfqws_pre4 $1 "$(reverse_nfqws_rule "$2")" $3
|
||||
}
|
||||
fw_reverse_nfqws_rule6()
|
||||
{
|
||||
fw_nfqws_pre6 $1 "$(produce_reverse_nfqws_rule "$2")" $3
|
||||
fw_nfqws_pre6 $1 "$(reverse_nfqws_rule "$2")" $3
|
||||
}
|
||||
fw_reverse_nfqws_rule()
|
||||
{
|
||||
@@ -353,93 +317,66 @@ fw_reverse_nfqws_rule()
|
||||
fw_reverse_nfqws_rule6 $1 "$3" $4
|
||||
}
|
||||
|
||||
ipt_first_packets()
|
||||
{
|
||||
# $1 - packet count
|
||||
[ -n "$1" -a "$1" != keepalive ] && [ "$1" -ge 1 ] && echo "$ipt_connbytes 1:$1"
|
||||
}
|
||||
ipt_do_nfqws_in_out()
|
||||
{
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - tcp,udp
|
||||
# $3 - ports
|
||||
# $4 - PKT_OUT. special value : 'keepalive'
|
||||
# $5 - PKT_IN
|
||||
local f4 f6 first_packets_only
|
||||
[ -n "$3" ] || return
|
||||
[ -n "$4" -a "$4" != 0 ] &&
|
||||
{
|
||||
first_packets_only="$(ipt_first_packets $4)"
|
||||
f4="-p $2 -m multiport --dports $3 $first_packets_only"
|
||||
f6=$f4
|
||||
filter_apply_ipset_target f4 f6
|
||||
fw_nfqws_post $1 "$f4" "$f6" $QNUM
|
||||
}
|
||||
[ -n "$5" -a "$5" != 0 ] &&
|
||||
{
|
||||
first_packets_only="$(ipt_first_packets $5)"
|
||||
f4="-p $2 -m multiport --dports $3 $first_packets_only"
|
||||
f6=$f4
|
||||
filter_apply_ipset_target f4 f6
|
||||
fw_reverse_nfqws_rule $1 "$f4" "$f6" $QNUM
|
||||
}
|
||||
}
|
||||
|
||||
zapret_do_firewall_standard_rules_ipt()
|
||||
{
|
||||
# $1 - 1 - add, 0 - del
|
||||
|
||||
local f4 f6
|
||||
|
||||
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] &&
|
||||
{
|
||||
f4="-p tcp -m multiport --dports $TPWS_PORTS_IPT"
|
||||
f6=$f4
|
||||
filter_apply_ipset_target f4 f6
|
||||
fw_tpws $1 "$f4" "$f6" $TPPORT
|
||||
}
|
||||
[ "$NFQWS_ENABLE" = 1 ] &&
|
||||
{
|
||||
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_IPT" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
|
||||
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_KEEPALIVE_IPT" keepalive "$NFQWS_TCP_PKT_IN"
|
||||
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_IPT" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
|
||||
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_KEEPALIVE_IPT" keepalive "$NFQWS_UDP_PKT_IN"
|
||||
}
|
||||
}
|
||||
|
||||
zapret_do_firewall_rules_ipt()
|
||||
{
|
||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||
# $1 - 1 - add, 0 - del
|
||||
|
||||
local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)"
|
||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||
local n f4 f6 qn qns qn6 qns6
|
||||
|
||||
case "$mode" in
|
||||
tpws)
|
||||
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
|
||||
echo both http and https are disabled. not applying redirection.
|
||||
else
|
||||
filter_apply_port_target f4
|
||||
f6=$f4
|
||||
filter_apply_ipset_target f4 f6
|
||||
fw_tpws $1 "$f4" "$f6" $TPPORT
|
||||
fi
|
||||
;;
|
||||
|
||||
nfqws)
|
||||
# quite complex but we need to minimize nfqws processes to save RAM
|
||||
get_nfqws_qnums qn qns qn6 qns6
|
||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
||||
filter_apply_port_target f4
|
||||
f4="$f4 $first_packet_only"
|
||||
filter_apply_ipset_target4 f4
|
||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||
fw_reverse_nfqws_rule4 $1 "$f4" $qn
|
||||
else
|
||||
if [ -n "$qn" ]; then
|
||||
f4="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
||||
filter_apply_ipset_target4 f4
|
||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||
fw_reverse_nfqws_rule4 $1 "$f4" $qn
|
||||
fi
|
||||
if [ -n "$qns" ]; then
|
||||
f4="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
|
||||
filter_apply_ipset_target4 f4
|
||||
fw_nfqws_post4 $1 "$f4 $desync" $qns
|
||||
fw_reverse_nfqws_rule4 $1 "$f4" $qns
|
||||
fi
|
||||
fi
|
||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||
filter_apply_port_target f6
|
||||
f6="$f6 $first_packet_only"
|
||||
filter_apply_ipset_target6 f6
|
||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||
fw_reverse_nfqws_rule6 $1 "$f6" $qn6
|
||||
else
|
||||
if [ -n "$qn6" ]; then
|
||||
f6="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
||||
filter_apply_ipset_target6 f6
|
||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||
fw_reverse_nfqws_rule6 $1 "$f6" $qn6
|
||||
fi
|
||||
if [ -n "$qns6" ]; then
|
||||
f6="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
|
||||
filter_apply_ipset_target6 f6
|
||||
fw_nfqws_post6 $1 "$f6 $desync" $qns6
|
||||
fw_reverse_nfqws_rule6 $1 "$f6" $qns6
|
||||
fi
|
||||
fi
|
||||
|
||||
get_nfqws_qnums_quic qn qn6
|
||||
if [ -n "$qn" ]; then
|
||||
f4=
|
||||
filter_apply_port_target_quic f4
|
||||
f4="$f4 $first_packet_only"
|
||||
filter_apply_ipset_target4 f4
|
||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||
fi
|
||||
if [ -n "$qn6" ]; then
|
||||
f6=
|
||||
filter_apply_port_target_quic f6
|
||||
f6="$f6 $first_packet_only"
|
||||
filter_apply_ipset_target6 f6
|
||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||
fi
|
||||
;;
|
||||
custom)
|
||||
custom_runner zapret_custom_firewall $1
|
||||
;;
|
||||
esac
|
||||
zapret_do_firewall_standard_rules_ipt $1
|
||||
custom_runner zapret_custom_firewall $1
|
||||
}
|
||||
|
||||
zapret_do_firewall_ipt()
|
||||
@@ -452,10 +389,6 @@ zapret_do_firewall_ipt()
|
||||
echo Clearing iptables
|
||||
fi
|
||||
|
||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||
|
||||
[ "$mode" = "tpws-socks" ] && return 0
|
||||
|
||||
# always create ipsets. ip_exclude ipset is required
|
||||
[ "$1" = 1 ] && create_ipset no-update
|
||||
|
||||
|
@@ -23,7 +23,7 @@ zapret_do_firewall()
|
||||
# switch on liberal mode on zapret firewall start and switch off on zapret firewall stop
|
||||
# this is only required for processing incoming bad RSTs. incoming rules are only applied in autohostlist mode
|
||||
# calling this after firewall because conntrack module can be not loaded before applying conntrack firewall rules
|
||||
[ "$MODE_FILTER" = "autohostlist" -a "$MODE" != tpws -a "$MODE" != tpws-socks ] && set_conntrack_liberal_mode $1
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && set_conntrack_liberal_mode $1
|
||||
|
||||
[ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK
|
||||
[ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK
|
||||
@@ -38,16 +38,3 @@ zapret_unapply_firewall()
|
||||
{
|
||||
zapret_do_firewall 0 "$@"
|
||||
}
|
||||
|
||||
first_packets_for_mode()
|
||||
{
|
||||
# autohostlist and autottl modes requires incoming traffic sample
|
||||
# always use conntrack packet limiter or nfqws will deal with gigabytes
|
||||
local n
|
||||
if [ "$MODE_FILTER" = "autohostlist" ]; then
|
||||
n=$((6+${AUTOHOSTLIST_RETRANS_THRESHOLD:-3}))
|
||||
else
|
||||
n=6
|
||||
fi
|
||||
echo $n
|
||||
}
|
||||
|
@@ -1,3 +1,6 @@
|
||||
readonly HOSTLIST_MARKER="<HOSTLIST>"
|
||||
readonly HOSTLIST_NOAUTO_MARKER="<HOSTLIST_NOAUTO>"
|
||||
|
||||
find_hostlists()
|
||||
{
|
||||
[ -n "$HOSTLIST_BASE" ] || HOSTLIST_BASE="$ZAPRET_BASE/ipset"
|
||||
@@ -18,38 +21,35 @@ find_hostlists()
|
||||
HOSTLIST_AUTO_DEBUGLOG="$HOSTLIST_BASE/zapret-hosts-auto-debug.log"
|
||||
}
|
||||
|
||||
filter_apply_autohostlist_target()
|
||||
{
|
||||
# $1 - var name of tpws or nfqws params
|
||||
|
||||
local parm1="${AUTOHOSTLIST_FAIL_THRESHOLD:+--hostlist-auto-fail-threshold=$AUTOHOSTLIST_FAIL_THRESHOLD}"
|
||||
local parm2="${AUTOHOSTLIST_FAIL_TIME:+--hostlist-auto-fail-time=$AUTOHOSTLIST_FAIL_TIME}"
|
||||
local parm3 parm4
|
||||
[ "$MODE" = "tpws" -o "$MODE" = "tpws-socks" ] || parm3="${AUTOHOSTLIST_RETRANS_THRESHOLD:+--hostlist-auto-retrans-threshold=$AUTOHOSTLIST_RETRANS_THRESHOLD}"
|
||||
[ "$AUTOHOSTLIST_DEBUGLOG" = 1 ] && parm4="--hostlist-auto-debug=$HOSTLIST_AUTO_DEBUGLOG"
|
||||
eval $1="\"\$$1 --hostlist-auto=$HOSTLIST_AUTO $parm1 $parm2 $parm3 $parm4\""
|
||||
}
|
||||
|
||||
filter_apply_hostlist_target()
|
||||
{
|
||||
# $1 - var name of tpws or nfqws params
|
||||
|
||||
[ "$MODE_FILTER" = "hostlist" -o "$MODE_FILTER" = "autohostlist" ] || return
|
||||
|
||||
local HOSTLIST_BASE HOSTLIST HOSTLIST_USER HOSTLIST_EXCLUDE
|
||||
|
||||
find_hostlists
|
||||
|
||||
[ -n "$HOSTLIST" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
|
||||
[ -n "$HOSTLIST_USER" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST_USER\""
|
||||
[ -n "$HOSTLIST_EXCLUDE" ] && eval $1="\"\$$1 --hostlist-exclude=$HOSTLIST_EXCLUDE\""
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && filter_apply_autohostlist_target $1
|
||||
}
|
||||
|
||||
filter_apply_suffix()
|
||||
{
|
||||
# $1 - var name of tpws or nfqws params
|
||||
# $2 - suffix value
|
||||
local v="${2:+ --new $2}"
|
||||
eval $1="\"\$$1$v\""
|
||||
local v parm parm1 parm2 parm3 parm4 parm5 parm6 parm7 parm8 parmNA
|
||||
eval v="\$$1"
|
||||
if contains "$v" "$HOSTLIST_MARKER" || contains "$v" "$HOSTLIST_NOAUTO_MARKER"; then
|
||||
[ "$MODE_FILTER" = hostlist -o "$MODE_FILTER" = autohostlist ] &&
|
||||
{
|
||||
find_hostlists
|
||||
parm1="${HOSTLIST_USER:+--hostlist=$HOSTLIST_USER}"
|
||||
parm2="${HOSTLIST:+--hostlist=$HOSTLIST}"
|
||||
parm3="${HOSTLIST_EXCLUDE:+--hostlist-exclude=$HOSTLIST_EXCLUDE}"
|
||||
[ "$MODE_FILTER" = autohostlist ] &&
|
||||
{
|
||||
parm4="--hostlist-auto=$HOSTLIST_AUTO"
|
||||
parm5="${AUTOHOSTLIST_FAIL_THRESHOLD:+--hostlist-auto-fail-threshold=$AUTOHOSTLIST_FAIL_THRESHOLD}"
|
||||
parm6="${AUTOHOSTLIST_FAIL_TIME:+--hostlist-auto-fail-time=$AUTOHOSTLIST_FAIL_TIME}"
|
||||
parm7="${AUTOHOSTLIST_RETRANS_THRESHOLD:+--hostlist-auto-retrans-threshold=$AUTOHOSTLIST_RETRANS_THRESHOLD}"
|
||||
parm8="--hostlist=$HOSTLIST_AUTO"
|
||||
}
|
||||
parm="$parm1${parm2:+ $parm2}${parm3:+ $parm3}${parm4:+ $parm4}${parm5:+ $parm5}${parm6:+ $parm6}${parm7:+ $parm7}"
|
||||
parmNA="$parm1${parm2:+ $parm2}${parm3:+ $parm3}${parm8:+ $parm8}"
|
||||
}
|
||||
v="$(replace_str $HOSTLIST_NOAUTO_MARKER "$parmNA" "$v")"
|
||||
v="$(replace_str $HOSTLIST_MARKER "$parm" "$v")"
|
||||
[ "$MODE_FILTER" = autohostlist -a "$AUTOHOSTLIST_DEBUGLOG" = 1 ] && {
|
||||
v="$v --hostlist-auto-debug=$HOSTLIST_AUTO_DEBUGLOG"
|
||||
}
|
||||
eval $1=\""$v"\"
|
||||
fi
|
||||
}
|
||||
|
245
common/nft.sh
245
common/nft.sh
@@ -86,10 +86,16 @@ cat << EOF | nft -f -
|
||||
add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr $TPWS_LOCALHOST4 return comment "route_localnet allow access to tpws"
|
||||
add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr 127.0.0.0/8 drop comment "route_localnet remote access protection"
|
||||
add rule inet $ZAPRET_NFT_TABLE input iif != lo jump localnet_protect
|
||||
add chain inet $ZAPRET_NFT_TABLE postrouting { type filter hook postrouting priority 99; }
|
||||
add chain inet $ZAPRET_NFT_TABLE postrouting
|
||||
flush chain inet $ZAPRET_NFT_TABLE postrouting
|
||||
add chain inet $ZAPRET_NFT_TABLE postnat { type filter hook postrouting priority 101; }
|
||||
add chain inet $ZAPRET_NFT_TABLE postrouting_hook { type filter hook postrouting priority 99; }
|
||||
flush chain inet $ZAPRET_NFT_TABLE postrouting_hook
|
||||
add rule inet $ZAPRET_NFT_TABLE postrouting_hook mark and $DESYNC_MARK == 0 jump postrouting
|
||||
add chain inet $ZAPRET_NFT_TABLE postnat
|
||||
flush chain inet $ZAPRET_NFT_TABLE postnat
|
||||
add chain inet $ZAPRET_NFT_TABLE postnat_hook { type filter hook postrouting priority 101; }
|
||||
flush chain inet $ZAPRET_NFT_TABLE postnat_hook
|
||||
add rule inet $ZAPRET_NFT_TABLE postnat_hook mark and $DESYNC_MARK == 0 jump postnat
|
||||
add chain inet $ZAPRET_NFT_TABLE prerouting { type filter hook prerouting priority -99; }
|
||||
flush chain inet $ZAPRET_NFT_TABLE prerouting
|
||||
add chain inet $ZAPRET_NFT_TABLE prenat { type filter hook prerouting priority -101; }
|
||||
@@ -107,6 +113,7 @@ cat << EOF | nft -f -
|
||||
add set inet $ZAPRET_NFT_TABLE wanif { type ifname; }
|
||||
add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; }
|
||||
add map inet $ZAPRET_NFT_TABLE link_local { type ifname : ipv6_addr; }
|
||||
|
||||
EOF
|
||||
[ -n "$POSTNAT_ALL" ] && {
|
||||
nft_flush_chain predefrag_nfqws
|
||||
@@ -118,6 +125,12 @@ nft_del_chains()
|
||||
# do not delete all chains because of additional user hooks
|
||||
# they must be inside zapret table to use nfsets
|
||||
|
||||
# these chains are newer. do not fail all because chains are not present
|
||||
cat << EOF | nft -f - 2>/dev/null
|
||||
delete chain inet $ZAPRET_NFT_TABLE postrouting_hook
|
||||
delete chain inet $ZAPRET_NFT_TABLE postnat_hook
|
||||
EOF
|
||||
|
||||
cat << EOF | nft -f - 2>/dev/null
|
||||
delete chain inet $ZAPRET_NFT_TABLE dnat_output
|
||||
delete chain inet $ZAPRET_NFT_TABLE dnat_pre
|
||||
@@ -199,7 +212,15 @@ nft_add_rule()
|
||||
# $2,$3,... - rule(s)
|
||||
local chain="$1"
|
||||
shift
|
||||
nft add rule inet $ZAPRET_NFT_TABLE $chain "$@"
|
||||
nft add rule inet $ZAPRET_NFT_TABLE $chain $FW_EXTRA_PRE "$@"
|
||||
}
|
||||
nft_insert_rule()
|
||||
{
|
||||
# $1 - chain
|
||||
# $2,$3,... - rule(s)
|
||||
local chain="$1"
|
||||
shift
|
||||
nft insert rule inet $ZAPRET_NFT_TABLE $chain $FW_EXTRA_PRE "$@"
|
||||
}
|
||||
nft_add_set_element()
|
||||
{
|
||||
@@ -227,6 +248,7 @@ nft_clean_nfqws_rule()
|
||||
nft_add_nfqws_flow_exempt_rule()
|
||||
{
|
||||
# $1 - rule (must be all filters in one var)
|
||||
local FW_EXTRA_POST= FW_EXTRA_PRE=
|
||||
nft_add_rule flow_offload $(nft_clean_nfqws_rule $1) return comment \"direct flow offloading exemption\"
|
||||
# do not need this because of oifname @wanif/@wanif6 filter in forward chain
|
||||
#nft_add_rule flow_offload $(nft_reverse_nfqws_rule $1) return comment \"reverse flow offloading exemption\"
|
||||
@@ -236,6 +258,7 @@ nft_add_flow_offload_exemption()
|
||||
# "$1" - rule for ipv4
|
||||
# "$2" - rule for ipv6
|
||||
# "$3" - comment
|
||||
local FW_EXTRA_POST= FW_EXTRA_PRE=
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || nft_add_rule flow_offload oifname @wanif $1 ip daddr != @nozapret return comment \"$3\"
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || nft_add_rule flow_offload oifname @wanif6 $2 ip6 daddr != @nozapret6 return comment \"$3\"
|
||||
}
|
||||
@@ -275,28 +298,6 @@ nft_apply_flow_offloading()
|
||||
|
||||
|
||||
|
||||
nft_filter_apply_port_target()
|
||||
{
|
||||
# $1 - var name of nftables filter
|
||||
local f
|
||||
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
||||
f="tcp dport {$HTTP_PORTS,$HTTPS_PORTS}"
|
||||
elif [ "$MODE_HTTPS" = "1" ]; then
|
||||
f="tcp dport {$HTTPS_PORTS}"
|
||||
elif [ "$MODE_HTTP" = "1" ]; then
|
||||
f="tcp dport {$HTTP_PORTS}"
|
||||
else
|
||||
echo WARNING !!! HTTP and HTTPS are both disabled
|
||||
fi
|
||||
eval $1="\"\$$1 $f\""
|
||||
}
|
||||
nft_filter_apply_port_target_quic()
|
||||
{
|
||||
# $1 - var name of nftables filter
|
||||
local f
|
||||
f="udp dport {$QUIC_PORTS}"
|
||||
eval $1="\"\$$1 $f\""
|
||||
}
|
||||
nft_filter_apply_ipset_target4()
|
||||
{
|
||||
# $1 - var name of ipv4 nftables filter
|
||||
@@ -399,7 +400,7 @@ nft_only()
|
||||
|
||||
nft_print_op()
|
||||
{
|
||||
echo "Adding nftables ipv$3 rule for $2 : $1"
|
||||
echo "Inserting nftables ipv$3 rule for $2 : $1"
|
||||
}
|
||||
_nft_fw_tpws4()
|
||||
{
|
||||
@@ -410,8 +411,8 @@ _nft_fw_tpws4()
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2"
|
||||
nft_print_op "$filter" "tpws (port $2)" 4
|
||||
nft_add_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$port
|
||||
nft_add_rule dnat_pre iifname @lanif $filter ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$port
|
||||
nft_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||
nft_insert_rule dnat_pre iifname @lanif $filter ip daddr != @nozapret $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||
prepare_route_localnet
|
||||
}
|
||||
}
|
||||
@@ -425,9 +426,9 @@ _nft_fw_tpws6()
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" DNAT6 i
|
||||
nft_print_op "$filter" "tpws (port $port)" 6
|
||||
nft_add_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 dnat ip6 to [::1]:$port
|
||||
nft_insert_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 $FW_EXTRA_POST dnat ip6 to [::1]:$port
|
||||
[ -n "$3" ] && {
|
||||
nft_add_rule dnat_pre $filter ip6 daddr != @nozapret6 dnat ip6 to iifname map @link_local:$port
|
||||
nft_insert_rule dnat_pre $filter ip6 daddr != @nozapret6 $FW_EXTRA_POST dnat ip6 to iifname map @link_local:$port
|
||||
for i in $3; do
|
||||
_dnat6_target $i DNAT6
|
||||
# can be multiple tpws processes on different ports
|
||||
@@ -476,7 +477,7 @@ _nft_fw_nfqws_post4()
|
||||
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4
|
||||
rule="${3:+oifname @wanif }$filter ip daddr != @nozapret"
|
||||
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
||||
nft_add_rule $chain $rule $setmark queue num $port bypass
|
||||
nft_insert_rule $chain $rule $setmark $FW_EXTRA_POST queue num $port bypass
|
||||
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||
}
|
||||
}
|
||||
@@ -491,7 +492,7 @@ _nft_fw_nfqws_post6()
|
||||
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
|
||||
rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6"
|
||||
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
||||
nft_add_rule $chain $rule $setmark queue num $port bypass
|
||||
nft_insert_rule $chain $rule $setmark $FW_EXTRA_POST queue num $port bypass
|
||||
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||
}
|
||||
}
|
||||
@@ -515,7 +516,7 @@ _nft_fw_nfqws_pre4()
|
||||
local filter="$1" port="$2" rule
|
||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
|
||||
rule="${3:+iifname @wanif }$filter ip saddr != @nozapret"
|
||||
nft_add_rule $(get_prechain) $rule queue num $port bypass
|
||||
nft_insert_rule $(get_prechain) $rule $FW_EXTRA_POST queue num $port bypass
|
||||
}
|
||||
}
|
||||
_nft_fw_nfqws_pre6()
|
||||
@@ -528,7 +529,7 @@ _nft_fw_nfqws_pre6()
|
||||
local filter="$1" port="$2" rule
|
||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
|
||||
rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6"
|
||||
nft_add_rule $(get_prechain) $rule queue num $port bypass
|
||||
nft_insert_rule $(get_prechain) $rule $FW_EXTRA_POST queue num $port bypass
|
||||
}
|
||||
}
|
||||
nft_fw_nfqws_pre()
|
||||
@@ -582,29 +583,13 @@ zapret_list_table()
|
||||
|
||||
|
||||
|
||||
nft_produce_reverse_nfqws_rule()
|
||||
{
|
||||
local rule="$1"
|
||||
if contains "$rule" "$nft_connbytes "; then
|
||||
# autohostlist - need several incoming packets
|
||||
# autottl - need only one incoming packet
|
||||
[ "$MODE_FILTER" = autohostlist ] || rule=$(echo "$rule" | sed -re "s/$nft_connbytes [0-9]+-[0-9]+/$nft_connbytes 1/")
|
||||
else
|
||||
# old nft does not swallow 1-1
|
||||
local range=1
|
||||
[ "$MODE_FILTER" = autohostlist ] && range=$(first_packets_for_mode)
|
||||
[ "$range" = 1 ] || range="1-$range"
|
||||
rule="$nft_connbytes $range $rule"
|
||||
fi
|
||||
nft_reverse_nfqws_rule $rule
|
||||
}
|
||||
nft_fw_reverse_nfqws_rule4()
|
||||
{
|
||||
nft_fw_nfqws_pre4 "$(nft_produce_reverse_nfqws_rule "$1")" $2
|
||||
nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule "$1")" $2
|
||||
}
|
||||
nft_fw_reverse_nfqws_rule6()
|
||||
{
|
||||
nft_fw_nfqws_pre6 "$(nft_produce_reverse_nfqws_rule "$1")" $2
|
||||
nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule "$1")" $2
|
||||
}
|
||||
nft_fw_reverse_nfqws_rule()
|
||||
{
|
||||
@@ -616,108 +601,75 @@ nft_fw_reverse_nfqws_rule()
|
||||
nft_fw_reverse_nfqws_rule6 "$2" $3
|
||||
}
|
||||
|
||||
nft_first_packets()
|
||||
{
|
||||
# $1 - packet count
|
||||
[ -n "$1" -a "$1" != keepalive ] && [ "$1" -ge 1 ] &&
|
||||
{
|
||||
if [ "$1" = 1 ] ; then
|
||||
echo "$nft_connbytes 1"
|
||||
else
|
||||
echo "$nft_connbytes 1-$1"
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
nft_apply_nfqws_in_out()
|
||||
{
|
||||
# $1 - tcp,udp
|
||||
# $2 - ports
|
||||
# $3 - PKT_OUT. special value : 'keepalive'
|
||||
# $4 - PKT_IN
|
||||
local f4 f6 first_packets_only
|
||||
[ -n "$2" ] || return
|
||||
[ -n "$3" -a "$3" != 0 ] &&
|
||||
{
|
||||
first_packets_only="$(nft_first_packets $3)"
|
||||
f4="$1 dport {$2} $first_packets_only"
|
||||
f6=$f4
|
||||
nft_filter_apply_ipset_target f4 f6
|
||||
nft_fw_nfqws_post "$f4" "$f6" $QNUM
|
||||
}
|
||||
[ -n "$4" -a "$4" != 0 ] &&
|
||||
{
|
||||
first_packets_only="$(nft_first_packets $4)"
|
||||
f4="$1 dport {$2} $first_packets_only"
|
||||
f6=$f4
|
||||
nft_filter_apply_ipset_target f4 f6
|
||||
nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM
|
||||
}
|
||||
}
|
||||
|
||||
zapret_apply_firewall_standard_rules_nft()
|
||||
{
|
||||
local f4 f6
|
||||
|
||||
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] &&
|
||||
{
|
||||
f4="tcp dport {$TPWS_PORTS}"
|
||||
f6=$f4
|
||||
nft_filter_apply_ipset_target f4 f6
|
||||
nft_fw_tpws "$f4" "$f6" $TPPORT
|
||||
}
|
||||
[ "$NFQWS_ENABLE" = 1 ] &&
|
||||
{
|
||||
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
|
||||
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP_KEEPALIVE" keepalive "$NFQWS_TCP_PKT_IN"
|
||||
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
|
||||
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP_KEEPALIVE" keepalive "$NFQWS_UDP_PKT_IN"
|
||||
}
|
||||
}
|
||||
|
||||
zapret_apply_firewall_rules_nft()
|
||||
{
|
||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||
|
||||
local first_packets_only
|
||||
local desync="mark and $DESYNC_MARK == 0"
|
||||
local f4 f6 qn qns qn6 qns6
|
||||
|
||||
first_packets_only="$nft_connbytes 1-$(first_packets_for_mode)"
|
||||
|
||||
case "$mode" in
|
||||
tpws)
|
||||
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
|
||||
echo both http and https are disabled. not applying redirection.
|
||||
else
|
||||
nft_filter_apply_port_target f4
|
||||
f6=$f4
|
||||
nft_filter_apply_ipset_target f4 f6
|
||||
nft_fw_tpws "$f4" "$f6" $TPPORT
|
||||
fi
|
||||
;;
|
||||
nfqws)
|
||||
local POSTNAT_SAVE=$POSTNAT
|
||||
|
||||
POSTNAT=1
|
||||
# quite complex but we need to minimize nfqws processes to save RAM
|
||||
get_nfqws_qnums qn qns qn6 qns6
|
||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
||||
nft_filter_apply_port_target f4
|
||||
f4="$f4 $first_packets_only"
|
||||
nft_filter_apply_ipset_target4 f4
|
||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||
nft_fw_reverse_nfqws_rule4 "$f4" $qn
|
||||
else
|
||||
if [ -n "$qn" ]; then
|
||||
f4="tcp dport {$HTTP_PORTS}"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packets_only"
|
||||
nft_filter_apply_ipset_target4 f4
|
||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||
nft_fw_reverse_nfqws_rule4 "$f4" $qn
|
||||
fi
|
||||
if [ -n "$qns" ]; then
|
||||
f4="tcp dport {$HTTPS_PORTS} $first_packets_only"
|
||||
nft_filter_apply_ipset_target4 f4
|
||||
nft_fw_nfqws_post4 "$f4 $desync" $qns
|
||||
nft_fw_reverse_nfqws_rule4 "$f4" $qns
|
||||
fi
|
||||
fi
|
||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||
nft_filter_apply_port_target f6
|
||||
f6="$f6 $first_packets_only"
|
||||
nft_filter_apply_ipset_target6 f6
|
||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||
nft_fw_reverse_nfqws_rule6 "$f6" $qn6
|
||||
else
|
||||
if [ -n "$qn6" ]; then
|
||||
f6="tcp dport {$HTTP_PORTS}"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packets_only"
|
||||
nft_filter_apply_ipset_target6 f6
|
||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||
nft_fw_reverse_nfqws_rule6 "$f6" $qn6
|
||||
fi
|
||||
if [ -n "$qns6" ]; then
|
||||
f6="tcp dport {$HTTPS_PORTS} $first_packets_only"
|
||||
nft_filter_apply_ipset_target6 f6
|
||||
nft_fw_nfqws_post6 "$f6 $desync" $qns6
|
||||
nft_fw_reverse_nfqws_rule6 "$f6" $qns6
|
||||
fi
|
||||
fi
|
||||
|
||||
get_nfqws_qnums_quic qn qn6
|
||||
if [ -n "$qn" ]; then
|
||||
f4=
|
||||
nft_filter_apply_port_target_quic f4
|
||||
f4="$f4 $first_packets_only"
|
||||
nft_filter_apply_ipset_target4 f4
|
||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||
fi
|
||||
if [ -n "$qn6" ]; then
|
||||
f6=
|
||||
nft_filter_apply_port_target_quic f6
|
||||
f6="$f6 $first_packets_only"
|
||||
nft_filter_apply_ipset_target6 f6
|
||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||
fi
|
||||
|
||||
POSTNAT=$POSTNAT_SAVE
|
||||
;;
|
||||
custom)
|
||||
custom_runner zapret_custom_firewall_nft
|
||||
;;
|
||||
esac
|
||||
zapret_apply_firewall_standard_rules_nft
|
||||
custom_runner zapret_custom_firewall_nft
|
||||
}
|
||||
|
||||
zapret_apply_firewall_nft()
|
||||
{
|
||||
echo Applying nftables
|
||||
|
||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||
|
||||
[ "$mode" = "tpws-socks" ] && return 0
|
||||
|
||||
create_ipset no-update
|
||||
nft_create_firewall
|
||||
nft_fill_ifsets_overload
|
||||
@@ -734,6 +686,7 @@ zapret_unapply_firewall_nft()
|
||||
|
||||
unprepare_route_localnet
|
||||
nft_del_firewall
|
||||
custom_runner zapret_custom_firewall_nft_flush
|
||||
return 0
|
||||
}
|
||||
zapret_do_firewall_nft()
|
||||
|
71
common/pf.sh
71
common/pf.sh
@@ -1,5 +1,5 @@
|
||||
PF_MAIN="/etc/pf.conf"
|
||||
PF_ANCHOR_DIR=/etc/pf.anchors
|
||||
PF_ANCHOR_DIR="/etc/pf.anchors"
|
||||
PF_ANCHOR_ZAPRET="$PF_ANCHOR_DIR/zapret"
|
||||
PF_ANCHOR_ZAPRET_V4="$PF_ANCHOR_DIR/zapret-v4"
|
||||
PF_ANCHOR_ZAPRET_V6="$PF_ANCHOR_DIR/zapret-v6"
|
||||
@@ -108,33 +108,17 @@ pf_anchor_zapret_tables()
|
||||
}
|
||||
pf_nat_reorder_rules()
|
||||
{
|
||||
# this is dirty hack to move rdr above route-to and remove route-to dups
|
||||
sort -rfu
|
||||
}
|
||||
pf_anchor_port_target()
|
||||
{
|
||||
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
||||
echo "{$HTTP_PORTS_IPT,$HTTPS_PORTS_IPT}"
|
||||
elif [ "$MODE_HTTPS" = "1" ]; then
|
||||
echo "{$HTTPS_PORTS_IPT}"
|
||||
elif [ "$MODE_HTTP" = "1" ]; then
|
||||
echo "{$HTTP_PORTS_IPT}"
|
||||
fi
|
||||
# this is dirty hack to move rdr above route-to
|
||||
# use only first word as a key and preserve order within a single key
|
||||
sort -srfk 1,1
|
||||
}
|
||||
|
||||
pf_anchor_zapret_v4_tpws()
|
||||
{
|
||||
# $1 - tpws listen port
|
||||
# $2 - rdr ports. defaults are used if empty
|
||||
|
||||
local rule port
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
port="{$2}"
|
||||
else
|
||||
port=$(pf_anchor_port_target)
|
||||
fi
|
||||
# $2 - rdr ports
|
||||
|
||||
local rule port="{$2}"
|
||||
for lan in $IFACE_LAN; do
|
||||
for t in $tbl; do
|
||||
echo "rdr on $lan inet proto tcp from any to $t port $port -> 127.0.0.1 port $1"
|
||||
@@ -157,31 +141,19 @@ pf_anchor_zapret_v4()
|
||||
{
|
||||
local tbl port
|
||||
[ "$DISABLE_IPV4" = "1" ] || {
|
||||
case "${MODE_OVERRIDE:-$MODE}" in
|
||||
tpws)
|
||||
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
||||
pf_anchor_zapret_v4_tpws $TPPORT
|
||||
;;
|
||||
custom)
|
||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
||||
custom_runner zapret_custom_firewall_v4 | pf_nat_reorder_rules
|
||||
;;
|
||||
esac
|
||||
{
|
||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
||||
custom_runner zapret_custom_firewall_v4
|
||||
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && pf_anchor_zapret_v4_tpws $TPPORT "$TPWS_PORTS_IPT"
|
||||
} | pf_nat_reorder_rules
|
||||
}
|
||||
}
|
||||
pf_anchor_zapret_v6_tpws()
|
||||
{
|
||||
# $1 - tpws listen port
|
||||
# $2 - rdr ports. defaults are used if empty
|
||||
# $2 - rdr ports
|
||||
|
||||
local rule LL_LAN port
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
port="{$2}"
|
||||
else
|
||||
port=$(pf_anchor_port_target)
|
||||
fi
|
||||
local rule LL_LAN port="{$2}"
|
||||
|
||||
# LAN link local is only for router
|
||||
for lan in $IFACE_LAN; do
|
||||
@@ -207,19 +179,12 @@ pf_anchor_zapret_v6_tpws()
|
||||
pf_anchor_zapret_v6()
|
||||
{
|
||||
local tbl port
|
||||
|
||||
[ "$DISABLE_IPV6" = "1" ] || {
|
||||
case "${MODE_OVERRIDE:-$MODE}" in
|
||||
tpws)
|
||||
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
||||
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
||||
pf_anchor_zapret_v6_tpws $TPPORT
|
||||
;;
|
||||
custom)
|
||||
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
||||
custom_runner zapret_custom_firewall_v6 | pf_nat_reorder_rules
|
||||
;;
|
||||
esac
|
||||
{
|
||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
||||
custom_runner zapret_custom_firewall_v6
|
||||
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS_IPT" ] && pf_anchor_zapret_v6_tpws $TPPORT "$TPWS_PORTS_IPT"
|
||||
} | pf_nat_reorder_rules
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,9 @@
|
||||
|
||||
# override firewall type : iptables,nftables,ipfw
|
||||
#FWTYPE=iptables
|
||||
# nftables only : set this to 0 to use pre-nat mode. default is post-nat.
|
||||
# pre-nat mode disables some bypass techniques for forwarded traffic but allows to see client IP addresses in debug log
|
||||
#POSTNAT=0
|
||||
|
||||
# options for ipsets
|
||||
# maximum number of elements in sets. also used for nft sets
|
||||
@@ -40,53 +43,59 @@ GZIP_LISTS=1
|
||||
# set to "-" to disable reload
|
||||
#LISTS_RELOAD="pfctl -f /etc/pf.conf"
|
||||
|
||||
# override ports
|
||||
#HTTP_PORTS=80-81,85
|
||||
#HTTPS_PORTS=443,500-501
|
||||
#QUIC_PORTS=443,444
|
||||
|
||||
# CHOOSE OPERATION MODE
|
||||
# MODE : nfqws,tpws,tpws-socks,filter,custom
|
||||
# nfqws : nfqws for dpi desync
|
||||
# tpws : tpws transparent mode
|
||||
# tpws-socks : tpws socks mode
|
||||
# filter : no daemon, just create ipset or download hostlist
|
||||
# custom : custom mode. should modify custom init script and add your own code
|
||||
MODE=tpws
|
||||
# apply fooling to http
|
||||
MODE_HTTP=1
|
||||
# for nfqws only. support http keep alives. enable only if DPI checks for http request in any outgoing packet
|
||||
MODE_HTTP_KEEPALIVE=0
|
||||
# apply fooling to https
|
||||
MODE_HTTPS=1
|
||||
# apply fooling to quic
|
||||
MODE_QUIC=0
|
||||
# none,ipset,hostlist,autohostlist
|
||||
MODE_FILTER=none
|
||||
|
||||
# CHOOSE NFQWS DAEMON OPTIONS for DPI desync mode. run "nfq/nfqws --help" for option list
|
||||
# SUFFIX VARS define additional lower priority desync profile. it's required if MODE_FILTER=hostlist and strategy has hostlist-incompatible 0-phase desync methods (syndata,wssize)
|
||||
# mark bit used by nfqws to prevent loop
|
||||
DESYNC_MARK=0x40000000
|
||||
DESYNC_MARK_POSTNAT=0x20000000
|
||||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-ttl6=0 --dpi-desync-fooling=badsum"
|
||||
#NFQWS_OPT_DESYNC_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTP=""
|
||||
#NFQWS_OPT_DESYNC_HTTP_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTPS=""
|
||||
#NFQWS_OPT_DESYNC_HTTPS_SUFFIX="--wssize 1:6"
|
||||
#NFQWS_OPT_DESYNC_HTTP6=""
|
||||
#NFQWS_OPT_DESYNC_HTTP6_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTPS6=""
|
||||
#NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="--wssize 1:6"
|
||||
NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake --dpi-desync-repeats=6"
|
||||
#NFQWS_OPT_DESYNC_QUIC_SUFFIX=""
|
||||
#NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
|
||||
#NFQWS_OPT_DESYNC_QUIC6_SUFFIX=""
|
||||
|
||||
# CHOOSE TPWS DAEMON OPTIONS. run "tpws/tpws --help" for option list
|
||||
# SUFFIX VARS define additional lower priority desync profile. it's required if MODE_FILTER=hostlist and strategy has hostlist-incompatible 0-phase desync methods (mss)
|
||||
TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3 --oob"
|
||||
#TPWS_OPT_SUFFIX="--mss 88"
|
||||
TPWS_SOCKS_ENABLE=0
|
||||
# tpws socks listens on this port on localhost and LAN interfaces
|
||||
TPPORT_SOCKS=987
|
||||
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
|
||||
TPWS_SOCKS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
"
|
||||
|
||||
TPWS_ENABLE=0
|
||||
TPWS_PORTS=80,443
|
||||
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
|
||||
TPWS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
"
|
||||
|
||||
NFQWS_ENABLE=0
|
||||
# redirect outgoing traffic with connbytes limiter applied in both directions.
|
||||
NFQWS_PORTS_TCP=80,443
|
||||
NFQWS_PORTS_UDP=443
|
||||
# PKT_OUT means connbytes dir original
|
||||
# PKT_IN means connbytes dir reply
|
||||
# this is --dpi-desync-cutoff=nX kernel mode implementation for linux. it saves a lot of CPU.
|
||||
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
|
||||
NFQWS_TCP_PKT_IN=3
|
||||
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
|
||||
NFQWS_UDP_PKT_IN=0
|
||||
# redirect outgoing traffic without connbytes limiter and incoming with connbytes limiter
|
||||
# normally it's needed only for stateless DPI that matches every packet in a single TCP session
|
||||
# typical example are plain HTTP keep alives
|
||||
# this mode can be very CPU consuming. enable with care !
|
||||
#NFQWS_PORTS_TCP_KEEPALIVE=80
|
||||
#NFQWS_PORTS_UDP_KEEPALIVE=
|
||||
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
|
||||
NFQWS_OPT="
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
|
||||
# none,ipset,hostlist,autohostlist
|
||||
MODE_FILTER=none
|
||||
|
||||
# openwrt only : donttouch,none,software,hardware
|
||||
FLOWOFFLOAD=donttouch
|
||||
@@ -123,4 +132,4 @@ DISABLE_IPV6=1
|
||||
# select which init script will be used to get ip or host list
|
||||
# possible values : get_user.sh get_antizapret.sh get_combined.sh get_reestr.sh get_hostlist.sh
|
||||
# comment if not required
|
||||
GETLIST=get_antifilter_ipsmart.sh
|
||||
#GETLIST=
|
||||
|
@@ -323,3 +323,35 @@ v64:
|
||||
blockcheck: warn if dpi bypass software is already running
|
||||
blockcheck: TPWS_EXTRA, NFQWS_EXTRA
|
||||
init.d: multiple custom scripts
|
||||
|
||||
v65:
|
||||
|
||||
init.d: dynamic number allocation for dnum,tpws_port,qnum
|
||||
init.d: FW_EXTRA_PRE, FW_EXTRA_POST
|
||||
init.d: zapret_custom_firewall_nft_flush
|
||||
nfqws,tpws: l7proto and client ip:port info in autohostlist debug log
|
||||
nfqws,tpws: user mode ipset filter support
|
||||
nfqws,tpws: l7proto filter support
|
||||
tpws: fixed MSS apply in transparent mode
|
||||
nfqws: fixed autottl apply if desync profile changed
|
||||
tpws,nfqws: fixed 100% cpu hang on gzipped list with comments
|
||||
ipset: get_refilter_ipsum.sh , get_refilter_domain.sh
|
||||
|
||||
v66:
|
||||
|
||||
init.d: rewrite traffic interception and daemon launch parameters in config file. this break compatibility with old versions.
|
||||
init.d: openwrt-minimal : tpws launch for low storage openwrt devices
|
||||
|
||||
v67:
|
||||
|
||||
mdig: --dns-make-query, --dns-parse-query for side-channel resolving (DoH)
|
||||
blockcheck: use DoH resolvers if DNS spoof is detected
|
||||
blockcheck: restring fooling to testing domain's IPs
|
||||
nfqws,tpws: internal hostlist deduplication to save RAM
|
||||
nfqws,tpws: hostlist/ipset auto reload on file change. no more HUP.
|
||||
nfqws,tpws: --filter-tcp, --filter-udp take comma separated port range list
|
||||
nfqws,tpws: @<config_file> - read config from a file
|
||||
config: <HOSTLIST_NOAUTO> marker
|
||||
binaries: remove zapret-winws. add win32.
|
||||
blockcheck, install_easy.sh: preserve user environment variables during elevation
|
||||
blockcheck: do not require root if SKIP_PKTWS=1
|
||||
|
@@ -19,13 +19,13 @@ For dpi desync attack :
|
||||
nft delete table inet ztest
|
||||
nft create table inet ztest
|
||||
nft add chain inet ztest post "{type filter hook postrouting priority mangle;}"
|
||||
nft add rule inet ztest post tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass
|
||||
nft add rule inet ztest post udp dport 443 ct original packets 1-4 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-12 queue num 200 bypass
|
||||
|
||||
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
|
||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
||||
nft add chain inet ztest pre "{type filter hook prerouting priority filter;}"
|
||||
nft add rule inet ztest pre tcp sport "{80,443}" ct reply packets 1-4 queue num 200 bypass
|
||||
nft add rule inet ztest pre tcp sport "{80,443}" ct reply packets 1-3 queue num 200 bypass
|
||||
|
||||
|
||||
show rules : nft list table inet ztest
|
||||
|
@@ -22,9 +22,9 @@
|
||||
1) Чтобы процедура установки сработала в штатном режиме на openwrt, нужно раcсчитывать на свободное место около 1-2 Mb
|
||||
для установки самого zapret и необходимых дополнительных пакетов.
|
||||
Если места мало и нет возможности его увеличить за счет extroot, возможно придется отказаться от варианта
|
||||
простой установки и прикручивать в ручном режиме без имеющихся скриптов запуска, либо попробовать засунуть требуемые
|
||||
zapret дополнительные пакеты в сжатый образ squashfs с помощью image builder и перешить этим вариантом роутер.
|
||||
См docs/manual_setup.txt , docs/readme.txt .
|
||||
простой установки и прикручивать в ручном режиме без имеющихся скриптов запуска.
|
||||
Можно использовать облегченный tpws вариант из init.d/openwrt-minimal, либо попробовать засунуть требуемые zapret
|
||||
дополнительные пакеты в сжатый образ squashfs с помощью image builder и перешить этим вариантом роутер.
|
||||
|
||||
2) Скачайте zip архив проекта с github в /tmp, распакуйте его там,
|
||||
либо клонируйте проект через : git clone --depth 1 https://github.com/bol-van/zapret
|
||||
@@ -42,8 +42,12 @@ install_prereq.sh
|
||||
Вас могут спросить о типе фаервола (iptables/nftables) и использовании ipv6. Это нужно для установки
|
||||
правильных пакетов в ОС, чтобы не устанавливать лишнее.
|
||||
|
||||
6) Запустите blockcheck.sh. blockcheck.sh в начале проверяет DNS. Если выводятся сообщения о подмене адресов, то
|
||||
первым делом нужно решить эту проблему, иначе ничего не будет работать.
|
||||
6) Запустите blockcheck.sh. blockcheck.sh в начале проверяет DNS.
|
||||
Если выводятся сообщения о подмене адресов, то нужно будет решить проблему с DNS.
|
||||
blockcheck перейдет в этом случае на DoH и будет пытаться получить и использовать реальные IP адреса.
|
||||
Но если вы не настроите решение этой проблемы, обход будет работать только для тех программ
|
||||
или ОС, которые сами реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
|
||||
Решение проблемы DNS выходит за рамки проекта. Обычно она решается либо заменой DNS серверов
|
||||
от провайдера на публичные (1.1.1.1, 8.8.8.8), либо в случае перехвата провайдером обращений
|
||||
к сторонним серверам - через специальные средства шифрования DNS запросов, такие как dnscrypt, DoT, DoH.
|
||||
@@ -83,10 +87,9 @@ iptables/nftables. В /etc/resolv.conf нельзя прописать DNS на
|
||||
|
||||
Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
|
||||
Вероятно, все остальные домены блокированы подобным образом, но не факт.
|
||||
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, но для этого необходимо понимать
|
||||
"что там за буковки". Если вы в сетях слабо разбираетесь, это не для вас. В противном случае читайте readme.txt.
|
||||
zapret не может пробить блокировку по IP адресу
|
||||
Для проверки нескольких доменов вводите их через пробел.
|
||||
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
|
||||
Необходимо понимать как работают стратегии.
|
||||
zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
|
||||
|
||||
Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
|
||||
с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
|
||||
@@ -104,37 +107,72 @@ badseq может работать только на https и не работа
|
||||
может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
|
||||
она стабильна, на третьих полный хаос, и проще отказаться.
|
||||
|
||||
Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска tpws и/или nfqws
|
||||
с использованием мультистратегии. Как работают мультистратегии описано в readme.txt.
|
||||
|
||||
Если кратко, то обычно параметры конструируются так :
|
||||
"--filter-udp=443 'параметры для quic' <HOSTLIST_NOAUTO> --new
|
||||
--filter-tcp=80,443 'обьединенные параметры для http и https' <HOSTLIST>"
|
||||
|
||||
Или так :
|
||||
"--filter-udp=443 "параметры для quic" <HOSTLIST_NOAUTO> --new
|
||||
--filter-tcp=80 'параметры для http' <HOSTLIST> --new
|
||||
--filter-tcp=443 'параметры для https' <HOSTLIST>"
|
||||
|
||||
"<HOSTLIST>" и "<HOSTLIST_NOAUTO>" так и пишутся. Их не надо на что-то заменять. Это сделают скрипты запуска,
|
||||
если вы выбрали режим фильтрации по хостлистам, и уберут в противном случае.
|
||||
Если для какого-то протокола надо дурить все без стандартного хостлиста - просто уберите оттуда "<HOSTLIST>"
|
||||
и "<HOSTLIST_NOAUTO>".
|
||||
Можно писать свои параметры --hostlist и --hostlist-exclude для дополнительных хостлистов
|
||||
или в профилях специализаций под конкретный ресурс. В последнем случае стандартный хостлист там не нужен.
|
||||
Следует избегать указания собственных параметров --hostlist на листы из директории ipset.
|
||||
Эта логика включена в "<HOSTLIST>" и "<HOSTLIST_NOAUTO>".
|
||||
Отличие "<HOSTLIST_NOAUTO>" в том, что стандартный автолист по этому профилю используется как обычный,
|
||||
то есть без автоматического добавления доменов. Однако, добавления в других профилях автоматически
|
||||
отражаются во всех остальных.
|
||||
|
||||
Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
|
||||
"--filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" <HOSTLIST_NOAUTO> --new
|
||||
--filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' <HOSTLIST> --new
|
||||
--filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' <HOSTLIST> --new
|
||||
--filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" <HOSTLIST_NOAUTO> --new
|
||||
--filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' <HOSTLIST> --new
|
||||
--filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6' <HOSTLIST>"
|
||||
|
||||
Но здесь совсем "копи-пастный" вариант.
|
||||
Чем больше вы обьедините стратегий и сократите их общее количество, тем будет лучше.
|
||||
|
||||
Если вам не нужно дурение отдельных протоколов, лучше всего будет их убрать из системы перехвата трафика через
|
||||
параметры TPWS_PORTS, NFQWS_PORTS_TCP, NFQWS_PORTS_UDP и убрать соответствующие им профили мультистратегии.
|
||||
tcp 80 - http, tcp 443 - https, udp 443 - quic.
|
||||
|
||||
Если используются методы нулевой фазы десинхронизации (--mss, --wssize, --dpi-desync=syndata) и режим фильтрации hostlist,
|
||||
то все параметры, относящиеся к этим методам, следует помещать не в основные параметры (например, NFQWS_OPT_DESYNC),
|
||||
а в suffix (NFQWS_OPT_DESYNC_SUFFIX). Чтобы не ошибиться, можно их продублировать и там, и там.
|
||||
Иначе они могут не работать.
|
||||
то все параметры, относящиеся к этим методам, следует помещать в отдельные профили мульистратегии, которые получат
|
||||
управление до определения имени хоста. Необходимо понимать алгоритм работы мультистратегий.
|
||||
Самым надежным вариантом будет дублирование этих параметров на 2 профиля. Какой-нибудь сработает в зависимости
|
||||
от параметра MODE_FILTER.
|
||||
|
||||
"--filter-tcp=80 'параметры для http' <HOSTLIST> --new
|
||||
--filter-tcp=443 'параметры для https' --wssize 1:6 <HOSTLIST> --new
|
||||
--filter-tcp=443 --wssize 1:6"
|
||||
|
||||
В этом примере wssize будет применяться всегда к порту tcp 443 вне зависимости от параметра MODE_FILTER.
|
||||
Хостлист будет игнорироваться, если таковой имеется. К http применять wssize вредно и бессмысленно.
|
||||
|
||||
Никто не мешает использовать tpws для http, nfqws для https, либо комбинировать действие nfqws и tpws для одного протокола.
|
||||
В текущем варианте скриптов запуска это делается максимально гибко и независимо друг от друга.
|
||||
|
||||
8) Запустите install_easy.sh.
|
||||
Выберите nfqws или tpws, затем согласитесь на редактирование параметров.
|
||||
Откроется редактор, куда впишите найденные стратегии.
|
||||
Для nfqws отдельно настраиваются стратегии на http и https для ipv4 и ipv6.
|
||||
То есть по максимуму 4 разных варианта.
|
||||
NFQWS_OPT_DESYNC - это общая установка, которая применяется, если какой-либо уточняющий параметр не задан
|
||||
NFQWS_OPT_DESYNC_HTTP и NFQWS_OPT_DESYNC_HTTPS заменяют стратегию для http и https.
|
||||
Если у вас включен ipv6, то они так же будут применены и к ipv6. Если для ipv6 нужна другая стратегия,
|
||||
то можно задать уточняющие параметры NFQWS_OPT_DESYNC_HTTP6 и NFQWS_OPT_DESYNC_HTTPS6.
|
||||
Если стратегии для ipv4 и ipv6 отличаются лишь ttl, то в целях экономии ресурсов роутера (меньше процессов nfqws)
|
||||
следует отказаться от использования специфических для ipv6 установок. Вместо них использовать параметры
|
||||
--dpi-desync-ttl и --dpi-desync-ttl6 в общих установках. Таким способом можно заставить один процесс nfqws
|
||||
обрабатывать трафик на ipv4 и на ipv6 с разным ttl.
|
||||
|
||||
Важным вопросом является вопрос о поддержке http keep alive.
|
||||
Отвечайте N. Если вдруг на http сайтах будут хаотические сбои типа то загружается, то заглушка или сброс,
|
||||
попробуйте включить поддержку keep alive. Но просто "на всякий случай" не включайте - это увеличит нагрузку на роутер.
|
||||
|
||||
Если это не помогает, или хаотичное поведение наблюдается и на https, то еще раз прогоните blockcheck
|
||||
с установленным числом попыток проверки не менее 5. Возможно, ваш провайдер использует балансировку нагрузки,
|
||||
где на разных путях установлен разный DPI.
|
||||
Выберите nfqws и/или tpws, затем согласитесь на редактирование параметров.
|
||||
Откроется редактор, куда впишите созданную на предыдущем этапе стратегию.
|
||||
|
||||
9) На все остальные вопросы install_easy.sh отвечайте согласно выводимой аннонтации.
|
||||
|
||||
10) Если ломаются отдельные незаблокированные ресурсы, следует вносить их в исключения, либо пользоваться ограничивающим
|
||||
ipset или хост листом. Читайте основной талмуд readme.txt ради подробностей.
|
||||
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
|
||||
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
|
||||
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
|
||||
|
||||
Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
|
||||
В некоторых случаях вы не обойдетесь без знаний и основного "талмуда".
|
||||
|
@@ -2,7 +2,10 @@
|
||||
|
||||
Как обычно, компьютерная грамотность ложится полностью на вас.
|
||||
Вы должны уметь работать с консолью windows и иметь минимальные навыки обращения с командными файлами bat,cmd.
|
||||
Если грамотность отсутствует и возникает куча "как" на базовых вещах - проходите мимо или ищите помощь в другом месте.
|
||||
Если грамотность отсутствует и возникает куча "как" на базовых вещах, значит эта программа не для вас.
|
||||
Разработчик не будет отвечать на вопросы из серии школы компьютерной грамотности.
|
||||
Если вы все-таки хотите продолжать, задавайте вопросы в дискуссиях на github или на форумах.
|
||||
Возможно, кто-то вам поможет. Но не надо писать issue на github. Они будут закрываться сразу.
|
||||
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод, которому сопротивляется окружающая среда,
|
||||
которому автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах,
|
||||
@@ -34,29 +37,36 @@
|
||||
|
||||
РЕШЕНИЕ "КАК ПОЛОЖЕНО"
|
||||
|
||||
1) Если у вас windows 7, обновляйте систему. Годами не обновляемая 7-ка может не запускать драйвер windivert.
|
||||
Поддержка 32-битных x86 windows возможна, но в готовом виде отсутствует.
|
||||
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip
|
||||
|
||||
2) Если у вас Windows 7 x64, читайте docs/windows.txt. Без описанной там подготовки может не работать.
|
||||
Для 32-битных систем Windows нет готового полного варианта, но есть собранные бинарники :
|
||||
https://github.com/bol-van/zapret-win32
|
||||
На windows 11 arm64 выполните arm64/install_arm64.cmd от имени администратора и перезагрузите компьютер.
|
||||
Читайте docs/windows.txt
|
||||
|
||||
Имейте в виду, что антивирусы могут плохо реагировать на windivert.
|
||||
cygwin имеет внушительный список несовместимостей с антивирусами. Многие антивирусы его ломают.
|
||||
https://www.cygwin.com/faq.html#faq.using.bloda
|
||||
Если это имеет место , используйте исключения. Если это не помогает - отключайте антивирус совсем.
|
||||
cygwin так же имеет внушительный список несовместимостей с антивирусами, хотя современные антивирусы
|
||||
более-менее научились с ним дружить.
|
||||
Если проблема имеет место , используйте исключения. Если не помогает - отключайте антивирус совсем.
|
||||
|
||||
2) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
|
||||
3) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
|
||||
|
||||
3) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
4) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
|
||||
4) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip
|
||||
5) Запустите blockcheck\blockcheck.cmd. blockcheck в начале проверяет DNS.
|
||||
Если выводятся сообщения о подмене адресов, то нужно будет решить проблему с DNS.
|
||||
blockcheck перейдет в этом случае на DoH и будет пытаться получить и использовать реальные IP адреса.
|
||||
Но если вы не настроите решение этой проблемы, обход будет работать только для тех программ,
|
||||
которые сами реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
|
||||
5) Запустите blockcheck\blockcheck.cmd. blockcheck в начале проверяет DNS. Если выводятся сообщения о подмене адресов, то
|
||||
первым делом нужно решить эту проблему, иначе ничего не будет работать.
|
||||
Решение проблемы DNS выходит за рамки проекта. Обычно она решается либо заменой DNS серверов
|
||||
от провайдера на публичные (1.1.1.1, 8.8.8.8), либо в случае перехвата провайдером обращений
|
||||
к сторонним серверам - через специальные средства шифрования DNS запросов, такие как dnscrypt, DoT, DoH.
|
||||
В современных броузерах чаще всего DoH включен по умолчанию, но curl будет использовать обычный системный DNS.
|
||||
Новые билды win10 и win11 поддерживают системные DoH из коробки. Они не настроены по умолчанию.
|
||||
win11 поддерживает системные DoH из коробки. Они не настроены по умолчанию.
|
||||
В последних билдах win10 существует неофициальный обходной путь для включения DoH.
|
||||
Для остальных систем нужно стороннее решение, работающие по принципу DNS proxy.
|
||||
|
||||
Тут все разжевано как и где это включается : https://hackware.ru/?p=13707
|
||||
|
||||
@@ -66,10 +76,9 @@ https://www.cygwin.com/faq.html#faq.using.bloda
|
||||
|
||||
Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
|
||||
Вероятно, все остальные домены блокированы подобным образом, но не факт.
|
||||
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, но для этого необходимо понимать
|
||||
"что там за буковки". Если вы в сетях слабо разбираетесь, это не для вас. В противном случае читайте readme.txt.
|
||||
zapret не может пробить блокировку по IP адресу
|
||||
Для проверки нескольких доменов вводите их через пробел.
|
||||
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
|
||||
Необходимо понимать как работают стратегии.
|
||||
zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
|
||||
|
||||
Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
|
||||
с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
|
||||
@@ -87,10 +96,58 @@ badseq может работать только на https и не работа
|
||||
может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
|
||||
она стабильна, на третьих полный хаос, и проще отказаться.
|
||||
|
||||
Если используются методы нулевой фазы десинхронизации (--wssize, --dpi-desync=syndata) и фильтр hostlist,
|
||||
то все параметры, относящиеся к этим методам, следует помещать в следующий профиль без хостлиста,
|
||||
к которому перейдет управление, когда имя хоста еще неизвестно.
|
||||
Используйте параметр --debug для отладки вашего сценария.
|
||||
Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
|
||||
с использованием мультистратегии. Как работают мультистратегии описано в readme.txt.
|
||||
|
||||
Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры
|
||||
--wf-l3, --wf-tcp, --wf-udp.
|
||||
--wf-l3 относится к версии ip протокола - ipv4 или ipv6.
|
||||
--wf-tcp и --wf-udp содержат перечень портов или диапазонов портов через запятую.
|
||||
|
||||
Пример стандартного фильтра для перехвата http, https, quic : --wf-tcp=80,443 --wf-udp=443
|
||||
|
||||
Фильтр должен быть минимально необходимым. Перехват лишнего трафика приведет только к бессмысленному
|
||||
расходованию ресурсов процессора и замедлению интернета.
|
||||
|
||||
Если кратко по мультистратегии, то обычно параметры конструируются так :
|
||||
"--filter-udp=443 'параметры для quic' --new
|
||||
--filter-tcp=80,443 'обьединенные параметры для http и https'"
|
||||
|
||||
Или так :
|
||||
"--filter-udp=443 "параметры для quic" --new
|
||||
--filter-tcp=80 'параметры для http' --new
|
||||
--filter-tcp=443 'параметры для https'"
|
||||
|
||||
Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
|
||||
"--filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" --new
|
||||
--filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' --new
|
||||
--filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' --new
|
||||
--filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" --new
|
||||
--filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' --new
|
||||
--filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6'"
|
||||
|
||||
Но здесь совсем "копи-пастный" вариант.
|
||||
Чем больше вы обьедините стратегий и сократите их общее количество, тем будет лучше.
|
||||
|
||||
Если вам не нужно дурение отдельных протоколов, лучше всего будет их убрать из системы перехвата трафика через
|
||||
параметры --wf-* и убрать соответствующие им профили мультистратегии.
|
||||
tcp 80 - http, tcp 443 - https, udp 443 - quic.
|
||||
|
||||
Если используются методы нулевой фазы десинхронизации (--mss, --wssize, --dpi-desync=syndata) и фильтрация hostlist,
|
||||
то все параметры, относящиеся к этим методам, следует помещать в отдельные профили мультистратегии, которые получат
|
||||
управление до определения имени хоста. Необходимо понимать алгоритм работы мультистратегий.
|
||||
|
||||
"--filter-tcp=80 'параметры для http' --new
|
||||
--filter-tcp=443 'параметры для https' --hostlist=d:/users/user/temp/list.txt --new
|
||||
--filter-tcp=443 --wssize 1:6"
|
||||
|
||||
autohostlist профиль приоритетен, поэтому wssize нужно писать туда :
|
||||
|
||||
"--filter-tcp=80 'параметры для http' --new
|
||||
--filter-tcp=443 'параметры для https' --wssize 1:6 --hostlist-auto=d:/users/user/temp/autolist.txt"
|
||||
|
||||
В этих примерах wssize будет применяться всегда к порту tcp 443, а хостлист будет игнорироваться.
|
||||
К http применять wssize вредно и бессмысленно.
|
||||
|
||||
7) Протестируйте найденные стратегии на winws. winws следует брать из zapret-winws.
|
||||
Для этого откройте командную строку windows от имени администратора в директории zapret-winws.
|
||||
@@ -113,10 +170,12 @@ badseq может работать только на https и не работа
|
||||
|
||||
Аналогично настраиваются и службы windows. Смотрите service_*.cmd
|
||||
|
||||
9) Если ломаются отдельные незаблокированные ресурсы, используйте хост-листы.
|
||||
Где они будут находиться - решайте сами.
|
||||
Параметры управления хост-листами точно такие же, как в *nix.
|
||||
9) Если ломаются отдельные незаблокированные ресурсы, нужно пользоваться ограничивающим
|
||||
ipset или хост листом. Читайте основной талмуд readme.txt ради подробностей.
|
||||
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
|
||||
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
|
||||
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
|
||||
|
||||
Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
|
||||
В некоторых случаях вы не обойдетесь без знаний и основного "толмуда".
|
||||
В некоторых случаях вы не обойдетесь без знаний и основного "талмуда".
|
||||
Подробности и полное техническое описание расписаны в readme.txt
|
||||
|
@@ -97,7 +97,8 @@ Then we can reduce CPU load, refusing to process unnecessary packets.
|
||||
`iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass`
|
||||
|
||||
Mark filter does not allow nfqws-generated packets to enter the queue again.
|
||||
Its necessary to use this filter when also using `connbytes 1:6`. Without it packet ordering can be changed breaking the whole idea.
|
||||
Its necessary to use this filter when also using `connbytes`. Without it packet ordering can be changed breaking the whole idea.
|
||||
Also if there's huge packet send from nfqws it may deadlock without mark filter.
|
||||
|
||||
Some attacks require redirection of incoming packets :
|
||||
|
||||
@@ -152,6 +153,8 @@ For BSD systems there is dvtws. Its built from the same source and has almost th
|
||||
nfqws takes the following parameters:
|
||||
|
||||
```
|
||||
@<config_file> ; read file for options. must be the only argument. other options are ignored.
|
||||
|
||||
--debug=0|1
|
||||
--qnum=<nfqueue_number>
|
||||
--daemon ; daemonize
|
||||
@@ -208,8 +211,11 @@ nfqws takes the following parameters:
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
--new ; begin new strategy
|
||||
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||
--filter-tcp=[~]port1[-port2] ; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp.
|
||||
--filter-udp=[~]port1[-port2] ; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp.
|
||||
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp. comma separated list supported.
|
||||
--filter-udp=[~]port1[-port2]|* ; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp. comma separated list supported.
|
||||
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.
|
||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
```
|
||||
|
||||
The manipulation parameters can be combined in any way.
|
||||
@@ -574,18 +580,18 @@ You need to use nftables instead with hook priority 101 or higher.
|
||||
`nfqws` can apply different strategies to different requests. It's done with multiple desync profiles.
|
||||
Profiles are delimited by the `--new` parameter. First profile is created automatically and does not require `--new`.
|
||||
Each profile has a filter. By default it's empty and profile matches any packet.
|
||||
Filter can have hard parameters : ip version and tcp/udp port range.
|
||||
Hard parameters are always identified unambiguously even on zero-phase when hostname is unknown yet.
|
||||
Hostlist can also act as a filter. They can be combined with hard parameters.
|
||||
Filter can have hard parameters : ip version, ipset and tcp/udp port range.
|
||||
Hard parameters are always identified unambiguously even on zero-phase when hostname and L7 are unknown yet.
|
||||
Hostlists can also act as a filter. They can be combined with hard parameters.
|
||||
When a packet comes profiles are matched from the first to the last until first filter condition match.
|
||||
Hard filter is matched first. If it does not match verification goes to the next profile.
|
||||
If a profile matches hard filter and has autohostlist it's selected immediately.
|
||||
If a profile matches hard filter and has normal hostlist(s) and hostname is unknown yet verification goes to the next profile.
|
||||
If a profile matches hard filter , L7 filter and has autohostlist it's selected immediately.
|
||||
If a profile matches hard filter , L7 filter and has normal hostlist(s) and hostname is unknown yet verification goes to the next profile.
|
||||
Otherwise profile hostlist(s) are checked for the hostname. If it matches profile is selected.
|
||||
Otherwise verification goes to the next profile.
|
||||
|
||||
It's possible that before getting hostname connection is served by one profile and after
|
||||
hostname is revealed it's switched to another profile.
|
||||
It's possible that before knowing L7 and hostname connection is served by one profile and after
|
||||
this information is revealed it's switched to another profile.
|
||||
If you use 0-phase desync methods think carefully what can happen during strategy switch.
|
||||
Use `--debug` logging to understand better what `nfqws` does.
|
||||
|
||||
@@ -596,11 +602,16 @@ IMPORTANT : multiple strategies exist only for the case when it's not possible t
|
||||
Copy-pasting blockcheck results of different websites to multiple strategies lead to the mess.
|
||||
This way you may never unblock all resources and only confuse yourself.
|
||||
|
||||
IMPORTANT : user-mode ipset implementation was not designed as a kernel version replacement. Kernel version is much more effective.
|
||||
It's for the systems that lack ipset support : Windows and Linux without nftables and ipset kernel modules (Android, for example).
|
||||
|
||||
## tpws
|
||||
|
||||
tpws is transparent proxy.
|
||||
|
||||
```
|
||||
@<config_file> ; read file for options. must be the only argument. other options are ignored.
|
||||
|
||||
--debug=0|1|2|syslog|@<filename> ; 1 and 2 means log to console and set debug level. for other targets use --debug-level.
|
||||
--debug-level=0|1|2 ; specify debug level for syslog and @<filename>
|
||||
--bind-addr=<v4_addr>|<v6_addr>; for v6 link locals append %interface_name : fe80::1%br-lan
|
||||
@@ -635,7 +646,10 @@ tpws is transparent proxy.
|
||||
|
||||
--new ; begin new strategy
|
||||
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||
--filter-tcp=[~]port1[-port2] ; TCP port filter. ~ means negation
|
||||
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. comma separated list supported.
|
||||
--filter-l7=[http|tls|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.
|
||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
|
||||
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||
@@ -844,7 +858,7 @@ 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 reread lists on HUP signal.
|
||||
tpws and nfqws automatically reload lists if their modification date is changed.
|
||||
|
||||
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 !
|
||||
@@ -854,7 +868,7 @@ When using large regulator lists estimate the amount of RAM on the router !
|
||||
This mode analyzes both client requests and server replies.
|
||||
If a host is not in any list and a situation similar to block occurs host is automatically added to the special list both in memory and file.
|
||||
Use exclude hostlist to prevent autohostlist triggering.
|
||||
If it did happen - delete the undesired record from the file and restart tpws/nfqws or send them SIGHUP to force lists reload.
|
||||
If it did happen - delete the undesired record from the file.
|
||||
|
||||
In case of nfqws it's required to redirect both incoming and outgoing traffic to the queue.
|
||||
It's strongly recommended to use connbytes filter or nfqws will process gigabytes of incoming traffic.
|
||||
@@ -882,7 +896,7 @@ Otherwise it's nothing to lose.
|
||||
However false positives still can occur in case target website is behaving abnormally
|
||||
(may be due to DDoS attack or server malfunction). If it happens bypass strategy
|
||||
may start to break the website. This situation can only be controlled manually.
|
||||
Remove undesired domain from the autohostlist file, restart nfqws/tpws or send them SIGHUP.
|
||||
Remove undesired domain from the autohostlist file.
|
||||
Use exclude hostlist to prevent further auto additions.
|
||||
|
||||
It's possible to use one auto hostlist with multiple processes. All processes check for file modification time.
|
||||
@@ -905,35 +919,106 @@ On openwrt by default `nftables` is selected on `firewall4` based systems.
|
||||
|
||||
`FWTYPE=iptables`
|
||||
|
||||
Main mode :
|
||||
With `nftables` post-NAT scheme is used by default. It allows more DPI attacks on forwarded traffic.
|
||||
It's possible to use `iptables`-like pre-NAT scheme. `nfqws` will see client source IPs and display them in logs.
|
||||
|
||||
`#POSTNAT=0`
|
||||
|
||||
There'are 3 standard options configured separately and independently : `tpws-socks`, `tpws`, `nfqws`.
|
||||
They can be used alone or combined. Custom scripts in `init.d/{sysv,openwrt,macos}/custom.d` are always applied.
|
||||
|
||||
`tpws-socks` requires daemon parameter configuration but does not require traffic interception.
|
||||
Other standard options require also traffic interception.
|
||||
Each standard option launches single daemon instance. Strategy differiences are managed using multi-profile scheme.
|
||||
Main rule for interception is "intercept required minumum". Everything else only wastes CPU resources and slows down connection.
|
||||
|
||||
`--ipset` option is prohibited intentionally to disallow easy to use but ineffective user-mode filtering.
|
||||
Use kernel ipsets instead. It may require custom scripts.
|
||||
|
||||
To use standard updatable hostlists from the `ipset` dir use `<HOSTLIST>` placeholder. It's automatically replaced
|
||||
with hostlist parameters if `MODE_FILTER` variable enables hostlists and is removed otherwise.
|
||||
Standard hostlists are expected in final (fallback) strategies closing groups of filter parameters.
|
||||
Don't use `<HOSTLIST>` in highly specialized profiles. Use your own filter or hostlist(s).
|
||||
`<HOSTLIST_NOAUTO>` marker uses standard autohostlist as usual hostlist thus disabling auto additions in this profile.
|
||||
If any other profile adds something this profile accepts the change automatically.
|
||||
|
||||
|
||||
`tpws` socks proxy mode switch
|
||||
|
||||
`TPWS_SOCKS_ENABLE=0`
|
||||
|
||||
Listening tcp port for `tpws` proxy mode.
|
||||
|
||||
`TPPORT_SOCKS=987`
|
||||
|
||||
`tpws` socks mode parameters
|
||||
|
||||
```
|
||||
tpws - tpws transparent mode
|
||||
tpws-socks - tpws socks mode
|
||||
binds to localhost and LAN interface (if IFACE_LAN is specified or the system is OpenWRT). port 988
|
||||
nfqws - nfqws
|
||||
filter - only fill ipset or load hostlist
|
||||
custom - use custom script for running daemons and establishing firewall rules
|
||||
TPWS_SOCKS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
"
|
||||
```
|
||||
|
||||
`MODE=tpws`
|
||||
`tpws` transparent mode switch
|
||||
|
||||
Enable http fooling :
|
||||
`TPWS_ENABLE=0`
|
||||
|
||||
`MODE_HTTP=1`
|
||||
`tpws` transparent mode target ports
|
||||
|
||||
Apply fooling to keep alive http sessions. Only applicable to nfqws. Tpws always fool keepalives.
|
||||
Not enabling this can save CPU time.
|
||||
`TPWS_PORTS=80,443`
|
||||
|
||||
`MODE_HTTP_KEEPALIVE=0`
|
||||
`tpws` transparent mode parameters
|
||||
|
||||
Enable https fooling :
|
||||
```
|
||||
TPWS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
"
|
||||
```
|
||||
|
||||
`MODE_HTTPS=1`
|
||||
`nfqws` enable switch
|
||||
|
||||
Enable quic fooling :
|
||||
`NFQWS_ENABLE=0`
|
||||
|
||||
`nfqws` port targets for `connbytes`-limited interception. `connbytes` allows to intercept only starting packets from connections.
|
||||
This is more effective kernel-mode alternative to `nfqws --dpi-desync-cutoff=nX`.
|
||||
|
||||
```
|
||||
NFQWS_PORTS_TCP=80,443
|
||||
NFQWS_PORTS_UDP=443
|
||||
```
|
||||
|
||||
How many starting packets should be intercepted to nfqws in each direction
|
||||
|
||||
```
|
||||
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
|
||||
NFQWS_TCP_PKT_IN=3
|
||||
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
|
||||
NFQWS_UDP_PKT_IN=0
|
||||
```
|
||||
|
||||
There's kind of traffic that requires interception of entire outgoing stream.
|
||||
Typically it's support for plain http keepalives and stateless DPI.
|
||||
This mode of interception significantly increases CPU utilization. Use with care and only if required.
|
||||
Here you specify port numbers for unlimited interception.
|
||||
It's advised also to remove these ports from `connbytes`-limited interception list.
|
||||
|
||||
```
|
||||
#NFQWS_PORTS_TCP_KEEPALIVE=80
|
||||
#NFQWS_PORTS_UDP_KEEPALIVE=
|
||||
```
|
||||
|
||||
`nfqws` parameters
|
||||
|
||||
```
|
||||
NFQWS_OPT="
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
```
|
||||
|
||||
`MODE_QUIC=1`
|
||||
|
||||
Host filtering mode :
|
||||
```
|
||||
@@ -945,62 +1030,6 @@ autohostlist - hostlist mode + blocks auto detection
|
||||
|
||||
`MODE_FILTER=none`
|
||||
|
||||
Its possible to change manipulation options used by tpws :
|
||||
|
||||
`TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3"`
|
||||
|
||||
Additional low priority desync profile for `MODE_FILTER=hostlist`.
|
||||
With multiple profile support 0-phase desync methods are no more applied with hostlist !
|
||||
To apply them additional profile is required without hostlist filter.
|
||||
|
||||
`TPWS_OPT_SUFFIX="--mss=88"`
|
||||
|
||||
nfqws options for DPI desync attack:
|
||||
|
||||
```
|
||||
DESYNC_MARK=0x40000000
|
||||
DESYNC_MARK_POSTNAT=0x20000000
|
||||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum --dpi-desync-fwmark=$DESYNC_MARK"
|
||||
```
|
||||
|
||||
Separate nfqws options for http and https and ip protocol versions 4,6:
|
||||
|
||||
```
|
||||
NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||
NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||
NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
|
||||
NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
|
||||
```
|
||||
|
||||
If one of `NFQWS_OPT_DESYNC_HTTP`/`NFQWS_OPT_DESYNC_HTTPS` is not defined it takes value of NFQWS_OPT_DESYNC.
|
||||
If one of `NFQWS_OPT_DESYNC_HTTP6`/`NFQWS_OPT_DESYNC_HTTPS6` is not defined it takes value from
|
||||
`NFQWS_OPT_DESYNC_HTTP`/`NFQWS_OPT_DESYNC_HTTPS`.
|
||||
It means if only `NFQWS_OPT_DESYNC` is defined all four take its value.
|
||||
|
||||
If a variable is not defined, the value `NFQWS_OPT_DESYNC` is taken.
|
||||
|
||||
Additional low priority desync profile for `MODE_FILTER=hostlist`.
|
||||
With multiple profile support 0-phase desync methods are no more applied with hostlist !
|
||||
To apply them additional profile is required without hostlist filter.
|
||||
```
|
||||
#NFQWS_OPT_DESYNC_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTP_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTPS_SUFFIX="--wssize 1:6"
|
||||
#NFQWS_OPT_DESYNC_HTTP6_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="--wssize 1:6"
|
||||
```
|
||||
|
||||
Defaults are filled the same ways as with NFQWS_OPT_*.
|
||||
|
||||
Separate QUIC options for ip protocol versions :
|
||||
|
||||
```
|
||||
NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
||||
NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
|
||||
```
|
||||
|
||||
If `NFQWS_OPT_DESYNC_QUIC6` is not specified `NFQWS_OPT_DESYNC_QUIC` is taken.
|
||||
|
||||
|
||||
flow offloading control (if supported)
|
||||
|
||||
@@ -1176,7 +1205,8 @@ Note that DNS check is mostly Russia targeted. It checks several pre-defined blo
|
||||
verifies system DNS answers with public DNS answers. Because ISP can block public DNS or redirect any DNS queries
|
||||
to their servers `blockcheck.sh` also checks that all returned answers are unique. Usually if DNS is blocked
|
||||
ISP returns single ip for all blocked domains to redirect you to their "access denied" page.
|
||||
`blockcheck.sh` works in Linux and FreeBSD.
|
||||
DoH servers are used automatically for checks if DNS spoof is detected.
|
||||
`blockcheck.sh` works on all systems supported by `zapret`.
|
||||
|
||||
### desktop linux system
|
||||
|
||||
@@ -1198,6 +1228,8 @@ After installation remove `/tmp/zapret` to free RAM.
|
||||
|
||||
The absolute minimum for openwrt is 64/8 system, 64/16 is comfortable, 128/extroot is recommended.
|
||||
|
||||
For low storage openwrt see `init.d/openwrt-minimal`.
|
||||
|
||||
### Android
|
||||
|
||||
Its not possible to use nfqws and tpws in transparent proxy mode without root privileges.
|
||||
|
411
docs/readme.txt
411
docs/readme.txt
@@ -1,4 +1,4 @@
|
||||
zapret v.64
|
||||
zapret v.67
|
||||
|
||||
English
|
||||
-------
|
||||
@@ -225,6 +225,8 @@ nfqws
|
||||
Эта программа - модификатор пакетов и обработчик очереди NFQUEUE.
|
||||
Для BSD систем существует адаптированный вариант - dvtws, собираемый из тех же исходников (см. bsd.txt).
|
||||
|
||||
@<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
|
||||
|
||||
--debug=0|1 ; 1=выводить отладочные сообщения
|
||||
--daemon ; демонизировать прогу
|
||||
--pidfile=<file> ; сохранить PID в файл
|
||||
@@ -269,8 +271,14 @@ nfqws
|
||||
--dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули
|
||||
--dpi-desync-start=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они объединяются. пустой обший лист = его отсутствие
|
||||
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они объединяются
|
||||
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
|
||||
; в файле должен быть хост на каждой строке.
|
||||
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; при изменении времени модификации файла он перечитывается автоматически по необходимости
|
||||
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
||||
; списков может быть множество. пустой общий лист = его отсутствие
|
||||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
|
||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
||||
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
||||
@@ -278,8 +286,11 @@ nfqws
|
||||
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
||||
--new ; начало новой стратегии
|
||||
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
||||
--filter-tcp=[~]port1[-port2] ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp.
|
||||
--filter-udp=[~]port1[-port2] ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает udp.
|
||||
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую.
|
||||
--filter-udp=[~]port1[-port2]|* ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает udp. поддерживается список через запятую.
|
||||
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
|
||||
Параметры манипуляции могут сочетаться в любых комбинациях.
|
||||
|
||||
@@ -464,8 +475,8 @@ mark нужен, чтобы сгенерированный поддельный
|
||||
чтобы не допустить изменения порядка следования пакетов. Процессинг очереди - процесс отложенный.
|
||||
Если ядро имеет пакеты на отсылку вне очереди - оно их отправляет незамедлительно.
|
||||
Изменение правильного порядка следования пакетов при десинхронизации ломает всю идею.
|
||||
При отсутствии ограничения на connbytes, атака будет работать и без фильтра по mark.
|
||||
Но лучше его все же оставить для увеличения скорости.
|
||||
Так же были замечены дедлоки при достаточно большой отсылке пакетов из nfqws и отсутствии mark фильтра.
|
||||
Процесс может зависнуть. Поэтому наличие фильтра по mark в ip/nf tables можно считать обязательным.
|
||||
|
||||
Почему --connbytes 1:6 :
|
||||
1 - для работы методов десинхронизации 0-й фазы и wssize
|
||||
@@ -664,20 +675,22 @@ nfqws способен по-разному реагировать на разл
|
||||
Профили разделяются в командной строке параметром --new. Первый профиль создается автоматически.
|
||||
Для него не нужно --new. Каждый профиль имеет фильтр. По умолчанию он пуст, то есть профиль удовлетворяет
|
||||
любым условиям.
|
||||
Фильтр может содержать жесткие параметры : версия ip протокола или порты tcp/udp.
|
||||
Они всегда однозначно идентифицируются даже на нулевой фазе десинхронизации, когда еще хост неизвестен.
|
||||
В качестве фильтра могут выступать и хост-листы. Они могут сочетаться с жесткими параметрами.
|
||||
Фильтр может содержать жесткие параметры : версия ip протокола, ipset и порты tcp/udp.
|
||||
Они всегда однозначно идентифицируются даже на нулевой фазе десинхронизации, когда еще хост и L7 неизвестны.
|
||||
В качестве мягкого фильтра могут выступать хост-листы и протокол прикладного уровня (l7).
|
||||
L7 протокол становится известен обычно после первого пакета с данными.
|
||||
При поступлении запроса идет проверка профилей в порядке от первого до последнего до
|
||||
достижения первого совпадения с фильтром.
|
||||
Жесткие параметры фильтра сверяются первыми. При несовпадении идет сразу же переход к следующему профилю.
|
||||
Если какой-то профиль удовлетворяет жесткому фильтру и содержит авто-хостлист, он выбирается сразу.
|
||||
Если профиль удовлетворяет жесткому фильтру, для него задан хостлист, и у нас еще нет имени хоста,
|
||||
Если какой-то профиль удовлетворяет жесткому фильтру и L7 фильтру и содержит авто-хостлист, он выбирается сразу.
|
||||
Если профиль удовлетворяет жесткому фильтру и L7 фильтру, для него задан хостлист, и у нас еще нет имени хоста,
|
||||
идет переход к следующему профилю. В противном случае идет проверка по хостлистам этого профиля.
|
||||
Если имя хоста удовлетворяет листам, выбирается этот профиль. Иначе идет переход к следующему.
|
||||
Может так случиться, что до получения имени хоста соединение идет по одному профилю, а при получении
|
||||
хоста профиль меняется на лету. Поэтому если у вас есть параметры дурения нулевой фазы, тщательно
|
||||
продумывайте что может произойти при переключении стратегии. Смотрите debug log, чтобы лучше
|
||||
понять что делает nfqws.
|
||||
Может так случиться, что до получения имени хоста или узнавания L7 протокола соединение идет по одному профилю,
|
||||
а при выяснении этих параметров профиль меняется на лету. Это может произойти даже дважды - при выяснении L7
|
||||
и имени хоста. Чаще всего это выяснение совмещается в одно действие, поскольку по одному пакету как правило узнается и L7, и хост.
|
||||
Поэтому если у вас есть параметры дурения нулевой фазы, тщательно продумывайте что может произойти при переключении стратегии.
|
||||
Смотрите debug log, чтобы лучше понять что делает nfqws.
|
||||
Нумерация профилей идет с 1 до N. Последним в цепочке создается пустой профиль с номером 0.
|
||||
Он используется, когда никакие условия фильтров не совпали.
|
||||
|
||||
@@ -686,11 +699,18 @@ nfqws способен по-разному реагировать на разл
|
||||
во множество профилей без понимания как они работают приведет к нагромождению параметров, которые все равно
|
||||
не покроют все возможные заблокированные ресурсы. Вы только увязните в этой каше.
|
||||
|
||||
ВАЖНО : user-mode реализация ipset создавалась не как удобная замена *nix версии, реализованной в ядре.
|
||||
Вариант в ядре работает гораздо эффективнее. Это создавалось для систем без подержки ipset в ядре.
|
||||
Конкретно - Windows и ядра Linux, собранные без nftables и ipset модулей ядра. Например, в android нет ipset.
|
||||
|
||||
|
||||
tpws
|
||||
-----
|
||||
|
||||
tpws - это transparent proxy.
|
||||
|
||||
@<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
|
||||
|
||||
--debug=0|1|2|syslog|@<filename> ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка.
|
||||
--debug-level=0|1|2 ; указать уровень логирования для syslog и @<filename>
|
||||
--daemon ; демонизировать прогу
|
||||
@@ -764,19 +784,22 @@ tpws - это transparent proxy.
|
||||
--tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока)
|
||||
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
|
||||
; в файле должен быть хост на каждой строке.
|
||||
; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; по сигналу HUP список будет перечитан при следующем принятом соединении
|
||||
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; при изменении времени модификации файла он перечитывается автоматически по необходимости
|
||||
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
||||
; списков может быть множество, они объединяются. пустой общий лист = его отсутствие
|
||||
; списков может быть множество. пустой общий лист = его отсутствие
|
||||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов, они объединяются
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
|
||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
||||
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
||||
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
||||
--new ; начало новой стратегии
|
||||
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
||||
--filter-tcp=[~]port1[-port2] ; фильтр портов tcp для текущей стратегии. ~ означает инверсию.
|
||||
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую.
|
||||
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
|
||||
|
||||
--debug позволяет выводить подробный лог действий на консоль, в syslog или в файл.
|
||||
@@ -940,6 +963,7 @@ TCP_USER_TIMEOUT. Под таймаутом подразумевается вр
|
||||
Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии.
|
||||
Смотрите вывод --debug, чтобы убедиться в правильности настроек.
|
||||
|
||||
|
||||
Способы получения списка заблокированных IP
|
||||
-------------------------------------------
|
||||
|
||||
@@ -981,10 +1005,13 @@ Cкрипты с названием get_antifilter_* оперируют спис
|
||||
9) ipset/get_antifilter_allyouneed.sh. получает лист https://antifilter.download/list/allyouneed.lst.
|
||||
Суммарный список префиксов, созданный из ipsum.lst и subnet.lst.
|
||||
|
||||
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.
|
||||
Варианты 2-9 дополнительно вызывают вариант 1.
|
||||
10) ipset/get_refilter_ipsum.sh.
|
||||
Список берется отсюда : https://github.com/1andrevich/Re-filter-lists
|
||||
|
||||
10) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config
|
||||
Все варианты рассмотренных скриптов автоматически создают и заполняют ipset.
|
||||
Варианты 2-10 дополнительно вызывают вариант 1.
|
||||
|
||||
11) ipset/get_config.sh. этот скрипт вызывает то, что прописано в переменной GETLIST из файла config
|
||||
Если переменная не определена, то ресолвятся лишь листы для ipset nozapret/nozapret6.
|
||||
|
||||
Листы РКН все время изменяются. Возникают новые тенденции. Требования к RAM могут меняться.
|
||||
@@ -992,7 +1019,7 @@ Cкрипты с названием get_antifilter_* оперируют спис
|
||||
Или вы можете узнать о проблеме лишь когда у вас начнет постоянно пропадать wifi, и вам придется
|
||||
его перезагружать каждые 2 часа (метод кувалды).
|
||||
|
||||
Самые щадящие варианты по RAM - get_antifilter_allyouneed.sh, get_antifilter_ipsum.sh.
|
||||
Самые щадящие варианты по RAM - get_antifilter_allyouneed.sh, get_antifilter_ipsum.sh, get_refilter_*.sh.
|
||||
|
||||
Листы zapret-ip.txt и zapret-ipban.txt сохраняются в сжатом виде в файлы .gz.
|
||||
Это позволяет снизить их размер во много раз и сэкономить место на роутере.
|
||||
@@ -1082,6 +1109,26 @@ ip2net фильтрует входные данные, выкидывая неп
|
||||
Не надо делать такое : 5000000/10000000. 1/2 - гораздо лучше.
|
||||
|
||||
|
||||
mdig
|
||||
----
|
||||
|
||||
Программа предназначена для многопоточного ресолвинга больших листов через системный DNS.
|
||||
Она берет из stdin список доменов и выводит в stdout результат ресолвинга. Ошибки выводятся в stderr.
|
||||
|
||||
--threads=<threads_number> ; количество потоков. по умолчанию 1.
|
||||
--family=<4|6|46> ; выбор семейства IP адресов : ipv4, ipv6, ipv4+ipv6
|
||||
--verbose ; дебаг-лог на консоль
|
||||
--stats=N ; выводить статистику каждые N доменов
|
||||
--log-resolved=<file> ; сохранять успешно отресолвленные домены в файл
|
||||
--log-failed=<file> ; сохранять неудачно отресолвленные домены в файл
|
||||
--dns-make-query=<domain> ; вывести в stdout бинарный DNS запрос по домену. если --family=6, запрос будет AAAA, иначе A.
|
||||
--dns-parse-query ; распарсить бинарный DNS ответ и выдать все ivp4 и ipv6 адреса из него в stdout
|
||||
|
||||
Параметры --dns-make-query и --dns-parse-query позволяют провести ресолвинг одного домена через произвольный канал.
|
||||
Например, следующим образом можно выполнить DoH запрос, используя лишь mdig и curl :
|
||||
mdig --family=6 --dns-make-query=rutracker.org | curl --data-binary @- -H "Content-Type: application/dns-message" https://cloudflare-dns.com/dns-query | mdig --dns-parse-query
|
||||
|
||||
|
||||
Фильтрация по именам доменов
|
||||
----------------------------
|
||||
|
||||
@@ -1111,12 +1158,14 @@ ipset/zapret-hosts-users-exclude.txt.gz или ipset/zapret-hosts-users-exclude.
|
||||
|
||||
Поддомены учитываются автоматически. Например, строчка "ru" вносит в список "*.ru". Строчка "*.ru" в списке не сработает.
|
||||
|
||||
Список доменов РКН может быть получен скриптами ipset/get_reestr_hostlist.sh или ipset/get_antizapret_domains.sh
|
||||
Список доменов РКН может быть получен скриптами
|
||||
ipset/get_reestr_hostlist.sh
|
||||
ipset/get_antizapret_domains.sh
|
||||
ipset/get_reestr_resolvable_domains.sh
|
||||
ipset/get_refilter_domains.sh
|
||||
- кладется в ipset/zapret-hosts.txt.gz.
|
||||
|
||||
Чтобы обновить списки, перезапускать nfqws или tpws не нужно. Обновляете файлы, затем даете сигнал HUP.
|
||||
По HUP листы будут перечитаны. Если вдруг какого-то листа не окажется, процесс завершится с ошибкой.
|
||||
Скрипты получения листов из ipset сами выдают HUP в конце.
|
||||
При изменении времени модификации файлов списки перечитываются автоматически.
|
||||
|
||||
При фильтрации по именам доменов демон должен запускаться без фильтрации по ipset.
|
||||
tpws и nfqws решают нужно ли применять дурение в зависимости от хоста, полученного из протокола прикладного уровня (http, tls, quic).
|
||||
@@ -1190,7 +1239,7 @@ nfqws и tpws могут сечь варианты 1-3, 4 они не распо
|
||||
По логу можно понять как избежать ложных срабатываний и подходит ли вообще вам этот режим.
|
||||
|
||||
Можно использовать один autohostlist с множеством процессов. Все процессы проверяют время модификации файла.
|
||||
Если файл был изменен в другом процессе, то происходит перечитывание всех include листов, включая autohostlist.
|
||||
Если файл был изменен в другом процессе, происходит его перечитывание.
|
||||
Все процессы должны работать под одним uid, чтобы были права доступа на файл.
|
||||
|
||||
Скрипты zapret ведут autohostlist в ipset/zapret-hosts-auto.txt.
|
||||
@@ -1212,6 +1261,7 @@ install_easy.sh при апгрейде zapret сохраняет этот фа
|
||||
Если DNS подменяется и провайдер перехватывает обращения к сторонним DNS, настройте dnscrypt.
|
||||
Еще один эффективный вариант - использовать ресолвер от yandex 77.88.8.88 на нестандартном порту 1253.
|
||||
Многие провайдеры не анализируют обращения к DNS на нестандартных портах.
|
||||
blockcheck если видит подмену DNS автоматически переключается на DoH сервера.
|
||||
|
||||
Следует прогнать blockcheck по нескольким заблокированным сайтам и выявить общий характер блокировок.
|
||||
Разные сайты могут быть заблокированы по-разному, нужно искать такую технику, которая работает на большинстве.
|
||||
@@ -1236,6 +1286,24 @@ Blockcheck имеет 3 уровня сканирования.
|
||||
standard дает возможность провести исследование как и на что реагирует DPI в плане методов обхода.
|
||||
force дает максимум проверок даже в случаях, когда ресурс работает без обхода или с более простыми стратегиями.
|
||||
|
||||
Есть ряд других параметров, которые не будут спрашиваться в диалоге, но которые можно переопределить через
|
||||
переменные.
|
||||
|
||||
DOMAINS - список тестируемых доменов через пробел
|
||||
CURL_MAX_TIME - время таймаута curl в секундах
|
||||
CURL_MAX_TIME_QUIC - время таймаута curl для quic. если не задано, используется значение CURL_MAX_TIME
|
||||
HTTP_PORT, HTTPS_PORT, QUIC_PORT - номера портов для соответствующих протоколов
|
||||
SKIP_DNSCHECK=1 - отказ от проверки DNS
|
||||
SKIP_TPWS=1 - отказ от тестов tpws
|
||||
SKIP_PKTWS=1 - отказ от тестов nfqws/dvtws/winws
|
||||
PKTWS_EXTRA, TPWS_EXTRA - дополнительные параметры nfqws/dvtws/winws и tpws
|
||||
PKTWS_EXTRA_1 .. PKTWS_EXTRA_9, TPWS_EXTRA_1 .. TPWS_EXTRA_9 - отдельно дополнительные параметры, содержащие пробелы
|
||||
SECURE_DNS=0|1 - принудительно выключить или включить DoH
|
||||
DOH_SERVERS - список URL DoH через пробел для автоматического выбора работающего сервера
|
||||
DOH_SERVER - конкретный DoH URL, отказ от поиска
|
||||
|
||||
Пример запуска с переменными : SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 ./blockcheck.sh
|
||||
|
||||
СКАН ПОРТОВ
|
||||
Если в системе присутствует совместимый netcat (ncat от nmap или openbsd ncat. в openwrt по умолчанию нет.),
|
||||
то выполняется сканирование портов http или https всех IP адресов домена.
|
||||
@@ -1345,86 +1413,98 @@ curl: (28) Connection timed out after 2002 milliseconds
|
||||
|
||||
FWTYPE=iptables
|
||||
|
||||
Основной режим :
|
||||
tpws - tpws в режиме transparent
|
||||
tpws-socks - tpws в режиме socks
|
||||
вешается на localhost и LAN интерфейс (если задан IFACE_LAN или если система - OpenWRT). порт 988
|
||||
nfqws - nfqws
|
||||
filter - только заполнить ipset или загрузить hostlist
|
||||
custom - нужно самому запрограммировать запуск демонов в init скрипте и правила iptables
|
||||
На nftables можно отключить стандартную схему перехвата трафика после NAT и перейти на перехват до NAT.
|
||||
Это сделает невозможным применение некоторых методов дурения на проходящем трафике как в случае с iptables.
|
||||
nfqws начнет получать адреса пакетов из локальной сети и отображать их в логах.
|
||||
#POSTNAT=0
|
||||
|
||||
MODE=tpws
|
||||
Существует 3 стандартных опции запуска, настраиваемых раздельно и независимо : tpws-socks, tpws, nfqws.
|
||||
Их можно использовать как по отдельности, так и вместе. Например, вам надо сделать комбинацию
|
||||
из методов, доступных только в tpws и только в nfqws. Их можно задействовать вместе.
|
||||
tpws будет прозрачно локализовывать трафик на системе и применять свое дурение, nfqws будет дурить трафик,
|
||||
исходящий с самой системы после обработки на tpws.
|
||||
А можно на эту же систему повесить без параметров socks proxy, чтобы получать доступ к обходу блокировок через прокси.
|
||||
Таким образом, все 3 режима вполне могут задействоваться вместе.
|
||||
Так же безусловно и независимо, в добавок к стандартным оцпиям, применяются все custom скрипты в init.d/{sysv,openwrt,macos}/custom.d.
|
||||
|
||||
Применять ли дурение к HTTP :
|
||||
tpws-socks требует настройки параметров tpws, но не требует перехвата трафика.
|
||||
Остальные оцпии требуют раздельно настройки перехвата трафика и опции самих демонов.
|
||||
Каждая опция предполагет запуск одного инстанса соответствующего демона. Все различия методов дурения
|
||||
для http, https, quic и т.д. должны быть отражены через схему мультистратегий.
|
||||
В этом смысле настройка похожа на вариант winws на Windows, а перенос конфигов не должен представлять больших сложностей.
|
||||
Основное правило настройки перехвата - перехватывайте только необходимый минимум.
|
||||
Любой перехват лишнего - это бессмысленная нагрузка на вашу систему.
|
||||
Опции демонов "--ipset" использовать запрещено. Это сделано намеренно и искусственно, чтобы не поощрать простой и
|
||||
работающий, но неэффективный метод на *nix системах. Используйте ipset-ы режима ядра.
|
||||
При необходимости пишите и задействуйте custom scripts.
|
||||
Настройки демонов можно для удобства писать на нескольких строках, используя двойные или одинарные кавычки.
|
||||
Чтобы задействовать стандартные обновляемые хост-листы из ipset, используйте маркер <HOSTLIST>.
|
||||
Он будет заменен на параметры, соответствующие режиму MODE_FILTER, и будут подставлены реально существующие файлы.
|
||||
Если MODE_FILTER не предполагает стандартного хостлиста, <HOSTLIST> будет заменен на пустую строку.
|
||||
Стандартные хостлисты следует вставлять в финальных стратегиях (стратегиях по умолчанию), закрывающих цепочки по
|
||||
группе параметров фильтра. Таких мест может быть несколько.
|
||||
Не нужно использовать <HOSTLIST> в узких специализациях и в тех профилях, по которым точно не будет проходить
|
||||
трафик с известными протоколами, откуда поддерживается извлечение имени хоста (http, tls, quic).
|
||||
<HOSTLIST_NOAUTO> - это вариация, при которой стандартный автолист используется как обычный.
|
||||
То есть на этом профиле не происходит автоматическое добавление заблокированных доменов.
|
||||
Но если на другом профиле что-то будет добавлено, то этот профиль примет изменения автоматически.
|
||||
|
||||
MODE_HTTP=1
|
||||
# включение стандартной опции tpws в режиме socks
|
||||
TPWS_SOCKS_ENABLE=0
|
||||
# на каком порту будет слушать tpws socks. прослушивается только localhost и LAN.
|
||||
TPPORT_SOCKS=987
|
||||
# параметры tpws для режима socks
|
||||
TPWS_SOCKS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
"
|
||||
|
||||
Применять ли дурение к последовательным http запросам в одном tcp соединении (http keeaplive).
|
||||
Относится только к nfqws. Выключение данной функции способно сэкономить загрузку процессора.
|
||||
tpws всегда работает с http keepalive
|
||||
# включение стандартной опции tpws в прозрачном режиме
|
||||
TPWS_ENABLE=0
|
||||
# какие tcp порты следует перенаправлять на tpws
|
||||
TPWS_PORTS=80,443
|
||||
# параметры tpws для прозрачного режима
|
||||
TPWS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
"
|
||||
|
||||
MODE_HTTP_KEEPALIVE=0
|
||||
# включение стандартной опции nfqws
|
||||
NFQWS_ENABLE=0
|
||||
# какие tcp и udp порты следует перенаправлять на nfqws с использованием connbytes ограничителя
|
||||
# connbytes позволяет из каждого соединения перенаправить только заданное количество начальных пакетов по каждому направлению - на вход и на выход
|
||||
# это более эффективная kernel-mode замена параметра nfqws --dpi-desync-cutoff=nX
|
||||
NFQWS_PORTS_TCP=80,443
|
||||
NFQWS_PORTS_UDP=443
|
||||
# сколько начальных входящих и исходящих пакетов нужно перенаправлять на nfqws по каждому направлению
|
||||
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
|
||||
NFQWS_TCP_PKT_IN=3
|
||||
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
|
||||
NFQWS_UDP_PKT_IN=0
|
||||
# есть трафик, исходящий сеанс для которого необходимо перенаправлять весь без ограничителей
|
||||
# типичное применение - поддержка http keepalives на stateless DPI
|
||||
# это существенно нагружает процессор. использовать только если понимаете зачем. чаще всего это не нужно.
|
||||
# входящий трафик ограничивается по connbytes через параметры PKT_IN
|
||||
# задать порты для перенаправления на nfqws без connbytes ограничителя
|
||||
# если указываете здесь какие-то порты, желательно их убрать из версии с connbytes ограничителем
|
||||
#NFQWS_PORTS_TCP_KEEPALIVE=80
|
||||
#NFQWS_PORTS_UDP_KEEPALIVE=
|
||||
# параметры nfqws
|
||||
NFQWS_OPT="
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
|
||||
Применять ли дурение к HTTPS :
|
||||
|
||||
MODE_HTTPS=1
|
||||
|
||||
Применять ли дурение к QUIC :
|
||||
|
||||
MODE_QUIC=0
|
||||
|
||||
Режим фильтрации хостов :
|
||||
none - применять дурение ко всем хостам
|
||||
ipset - ограничить дурение ipset-ом zapret/zapret6
|
||||
hostlist - ограничить дурение списком хостов из файла
|
||||
autohostlist - режим hostlist + распознавание блокировок и ведения автоматического листа
|
||||
autohostlist - режим hostlist + распознавание блокировок и ведение автоматического листа
|
||||
|
||||
MODE_FILTER=none
|
||||
|
||||
Опции tpws :
|
||||
|
||||
TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3"
|
||||
|
||||
Дополнительный низкоприоритетный профиль десинхронизации для режимов с MODE_FILTER=hostlist.
|
||||
После реализации поддержки множественных профилей режимы нулевой фазы десинхронизации больше не применяются с хостлистом !
|
||||
Для их применения требуется дополнительный профиль без хостлист фильтра.
|
||||
|
||||
#TPWS_OPT_SUFFIX="--mss 88"
|
||||
|
||||
Опции nfqws для атаки десинхронизации DPI :
|
||||
|
||||
DESYNC_MARK=0x40000000
|
||||
DESYNC_MARK_POSTNAT=0x20000000
|
||||
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||
|
||||
Задание раздельных опций nfqws для http и https и для версий ip протоколов 4,6 :
|
||||
|
||||
NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||
NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
|
||||
NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
|
||||
NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
|
||||
|
||||
Если какая-то из переменных NFQWS_OPT_DESYNC_HTTP/NFQWS_OPT_DESYNC_HTTPS не определена,
|
||||
берется значение NFQWS_OPT_DESYNC.
|
||||
Если какая-то из переменных NFQWS_OPT_DESYNC_HTTP6/NFQWS_OPT_DESYNC_HTTPS6 не определена,
|
||||
берется значение NFQWS_OPT_DESYNC_HTTP/NFQWS_OPT_DESYNC_HTTPS.
|
||||
|
||||
Дополнительный низкоприоритетный профиль десинхронизации для режимов с MODE_FILTER=hostlist.
|
||||
После реализации поддержки множественных профилей режимы нулевой фазы десинхронизации больше не применяются с хостлистом !
|
||||
Для их применения требуется дополнительный профиль без хостлист фильтра.
|
||||
#NFQWS_OPT_DESYNC_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTP_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTPS_SUFFIX="--wssize 1:6"
|
||||
#NFQWS_OPT_DESYNC_HTTP6_SUFFIX="--dpi-desync=syndata"
|
||||
#NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="--wssize 1:6"
|
||||
|
||||
Значения по умолчанию заполняются аналогично NFQWS_OPT_*.
|
||||
|
||||
Опции дурения для QUIC :
|
||||
NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
||||
NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
|
||||
Если NFQWS_OPT_DESYNC_QUIC6 не задано, то берется NFQWS_OPT_DESYNC_QUIC.
|
||||
|
||||
Настройка системы управления выборочным traffic offload (только если поддерживается)
|
||||
donttouch : выборочное управление отключено, используется системная настройка, простой инсталлятор выключает системную настройку, если она не совместима с выбранным режимом
|
||||
none : выборочное управление отключено, простой инсталлятор выключает системную настройку
|
||||
@@ -1475,8 +1555,11 @@ IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
|
||||
IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5"
|
||||
|
||||
Настройка режима autohostlist.
|
||||
При увеличении AUTOHOSTLIST_RETRANS_THRESHOLD и использовании nfqws следует пересмотреть значения параметров
|
||||
NFQWS_TCP_PKT_OUT и NFQWS_UDP_PKT_OUT. Все ретрансмиссии должны быть получены nfqws, иначе триггер "зависание запроса" не сработает.
|
||||
|
||||
AUTOHOSTLIST_RETRANS_THRESHOLD=3
|
||||
AUTOHOSTLIST_FAIL_THRESHOLD=2
|
||||
AUTOHOSTLIST_FAIL_THRESHOLD=3
|
||||
AUTOHOSTLIST_FAIL_TIME=60
|
||||
AUTOHOSTLIST_DEBUG=0
|
||||
|
||||
@@ -1518,6 +1601,7 @@ IFACE_WAN6="henet ipsec0"
|
||||
Включаются только режимы, обеспечивающие перехват транзитного трафика.
|
||||
Возможно определить несколько интерфейсов следующим образом : IFACE_LAN="eth0 eth1 eth2"
|
||||
|
||||
|
||||
Прикручивание к системе управления фаерволом или своей системе запуска
|
||||
----------------------------------------------------------------------
|
||||
|
||||
@@ -1572,21 +1656,21 @@ nfset-ы принадлежат только одной таблице, след
|
||||
Вариант custom
|
||||
--------------
|
||||
|
||||
custom код вынесен в отдельные shell includes.
|
||||
Поддерживается старый вариант в
|
||||
/opt/zapret/init.d/sysv/custom
|
||||
/opt/zapret/init.d/openwrt/custom
|
||||
/opt/zapret/init.d/macos/custom
|
||||
Он считается устаревшим. Актуальный вариант - помещать отдельные скрипты там же, но в директорию "custom.d".
|
||||
Она будет просканирована стандартным образом, т.е. в алфавитном порядке, и каждый скрипт будет применен.
|
||||
Рядом имеется "custom.d.examples". Это готовые скрипты, который можно копировать в "custom.d".
|
||||
Особо стоит отметить "10-inherit-*". Они наследуют стандартные режимы nfqws/tpws/tpws-socks.
|
||||
Полезно, чтобы не писать код заново. Достаточно лишь скопировать соответствующий файл.
|
||||
custom скрипты - это маленькие shell программы, управляющие нестандартными режимами применения zapret
|
||||
или частными случаями, которые не могут быть интегрированы в основную часть без загромождения и замусоривания кода.
|
||||
Для применеия custom следует помещать файлы в следующие директории в зависимости от вашей системы :
|
||||
/opt/zapret/init.d/sysv/custom.d
|
||||
/opt/zapret/init.d/openwrt/custom.d
|
||||
/opt/zapret/init.d/macos/custom.d
|
||||
Директория будет просканирована в алфавитном порядке, и каждый скрипт будет применен.
|
||||
Рядом имеется "custom.d.examples". Это готовые скрипты, которые можно копировать в "custom.d".
|
||||
Их можно взять за основу для написания собственных.
|
||||
|
||||
Для linux пишется код в функции
|
||||
zapret_custom_daemons
|
||||
zapret_custom_firewall
|
||||
zapret_custom_firewall_nft
|
||||
zapret_custom_firewall_nft_flush
|
||||
|
||||
Для macos
|
||||
zapret_custom_daemons
|
||||
@@ -1594,35 +1678,46 @@ zapret_custom_firewall_v4
|
||||
zapret_custom_firewall_v6
|
||||
|
||||
zapret_custom_daemons поднимает демоны nfqws/tpws в нужном вам количестве и с нужными вам параметрами.
|
||||
Особо обратите внимание на номер демона в функциях "run_daemon" и "do_daemon".
|
||||
Для систем традиционного linux (sysv) и MacOS в первом параметре передается код операции : 1 = запуск, 0 = останов.
|
||||
Для openwrt логика останова отсутствует за ненадобностью.
|
||||
Схема запуска демонов в openwrt отличается - используется procd.
|
||||
|
||||
zapret_custom_firewall поднимает и убирает правила iptables.
|
||||
В первом параметре передается код операции : 1 = запуск, 0 = останов.
|
||||
|
||||
zapret_custom_firewall_nft поднимает правила nftables.
|
||||
Логика останова отсутствует за ненадобностью. Стандартные цепочки zapret удаляются автоматически.
|
||||
Однако, sets и правила из ваших собственных цепочек не удаляются.
|
||||
Их нужно подчистить в zapret_custom_firewall_nft_flush.
|
||||
Если set-ов и собственных цепочек у вас нет, функцию можно не определять или оставить пустой.
|
||||
|
||||
Если вам не нужны iptables или nftables - можете не писать соответствующую функцию.
|
||||
|
||||
В linux можно использовать локальные переменные FW_EXTRA_PRE и FW_EXTRA_POST.
|
||||
FW_EXTRA_PRE добавляет код к правилам ip/nf tables до кода, генерируемого функциями-хелперами.
|
||||
FW_EXTRA_POST добавляет код после.
|
||||
|
||||
В linux функции-хелперы добавляют правило в начало цепочек, то есть перед уже имеющимися.
|
||||
Поэтому специализации должны идти после более общих вариантов.
|
||||
Для macos правило обратное. Там правила добавляются в конец.
|
||||
По этой же причине фаервол в Linux сначала применяется в стандартном режиме, потом custom,
|
||||
а в MacOS сначала custom, потом стандартный режим.
|
||||
|
||||
В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout,
|
||||
содержащий правила для pf-якоря. Остальное сделает обертка.
|
||||
|
||||
Особо обратите внимание на номер демона в функциях "run_daemon" и "do_daemon", номера портов tpws
|
||||
и очередей nfqueue.
|
||||
Они должны быть уникальными во всех скриптах. При накладке будет ошибка.
|
||||
Так же следует избегать пересечения номеров портов tpws и очередей nfqws.
|
||||
При пересечении какой-то из демонов не запустится.
|
||||
Чтобы как-то нивелировать эту проблему, в examples используется переменная DNUM.
|
||||
На ее базе считается диапазон номеров очередей (5 шт), которые использует этот скрипт.
|
||||
При таком подходе достаточно, чтобы DNUM был везде уникален.
|
||||
Поскольку номера очереди и портов имеют нумерацию до 65536, можно использовать DNUM до 13106.
|
||||
Однако, следует оставить номера очереди 200-299 для стандартных режимов и не использовать их.
|
||||
Поэтому используйте функции динамического получения этих значений из пула.
|
||||
|
||||
custom скрипты могут использовать переменные из config. Можно помещать в config свои переменные
|
||||
и использовать их в скриптах.
|
||||
и задействовать их в скриптах.
|
||||
Можно использовать функции-хелперы. Они являются частью общего пространства функций shell.
|
||||
Полезные функции можно взять из примеров скриптов. Так же смотрите "common/*.sh".
|
||||
Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи
|
||||
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
|
||||
Хелперы это учитывают, вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и
|
||||
параметрах демонов.
|
||||
|
||||
Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку демонов.
|
||||
Запуск это или остановка передается в параметре $1 (0 или 1).
|
||||
В openwrt за остановку отвечает procd.
|
||||
|
||||
Для фаервола в linux кастом пишется отдельно для iptables и nftables. Все очень похоже, но отличается
|
||||
написание фильтров и названия процедур хелперов. Если вам не нужны iptables или nftables -
|
||||
можете не писать соответствующую функцию.
|
||||
|
||||
В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout,
|
||||
содержащий правила для pf-якоря. Остальное сделает обертка.
|
||||
Хелперы это учитывают. Вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и параметрах демонов.
|
||||
|
||||
|
||||
Простая установка
|
||||
@@ -1679,6 +1774,64 @@ install_easy.sh автоматизирует ручные варианты пр
|
||||
Система простой инсталяции заточена на любое умышленное или неумышленное изменение прав доступа на файлы.
|
||||
Устойчива к репаку под windows. После копирования в /opt права будут принудительно восстановлены.
|
||||
|
||||
|
||||
Установка на openwrt в режиме острой нехватки места на диске
|
||||
------------------------------------------------------------
|
||||
|
||||
Требуется около 120-200 кб на диске. Придется отказаться от всего, кроме tpws.
|
||||
|
||||
* Инструкция для openwrt 22 и выше с nftables.
|
||||
|
||||
Никаких зависимостей устанавливать не нужно.
|
||||
|
||||
Установка :
|
||||
|
||||
Скопируйте все из init.d/openwrt-minimal/tpws/* в корень openwrt.
|
||||
Скопируйте бинарник tpws подходящей архитектуры в /usr/bin/tpws.
|
||||
Установите права на файлы : chmod 755 /etc/init.d/tpws /usr/bin/tpws
|
||||
Отредактируйте /etc/config/tpws
|
||||
Если не нужен ipv6, отредактируйте /etc/nftables.d/90-tpws.nft и закомментируйте строки с редиректом ipv6.
|
||||
/etc/init.d/tpws enable
|
||||
/etc/init.d/tpws start
|
||||
fw4 restart
|
||||
|
||||
Полное удаление :
|
||||
|
||||
/etc/init.d/tpws disable
|
||||
/etc/init.d/tpws stop
|
||||
rm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpws /usr/bin/tpws
|
||||
fw4 restart
|
||||
|
||||
* Инструкция для openwrt 21 и ниже с iptables.
|
||||
|
||||
Установите зависимости :
|
||||
opkg update
|
||||
opkg install iptables-mod-extra
|
||||
только для IPV6 : opkg install ip6tables-mod-nat
|
||||
|
||||
Убедитесь, что в /etc/firewall.user нет ничего значимого.
|
||||
Если есть - не следуйте слепо инструкции. Обьедините код или создайте свой firewall include в /etc/config/firewall.
|
||||
|
||||
Установка :
|
||||
|
||||
Скопируйте все из init.d/openwrt-minimal/tpws/* в корень openwrt.
|
||||
Скопируйте бинарник tpws подходящей архитектуры в /usr/bin/tpws.
|
||||
Установите права на файлы : chmod 755 /etc/init.d/tpws /usr/bin/tpws
|
||||
Отредактируйте /etc/config/tpws
|
||||
Если не нужен ipv6, отредактируйте /etc/firewall.user и установите там DISABLE_IPV6=1.
|
||||
/etc/init.d/tpws enable
|
||||
/etc/init.d/tpws start
|
||||
fw3 restart
|
||||
|
||||
Полное удаление :
|
||||
|
||||
/etc/init.d/tpws disable
|
||||
/etc/init.d/tpws stop
|
||||
rm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpws
|
||||
touch /etc/firewall.user
|
||||
fw3 restart
|
||||
|
||||
|
||||
Android
|
||||
-------
|
||||
|
||||
|
@@ -15,7 +15,7 @@ Tor поддерживает "из коробки" режим transparent proxy.
|
||||
4) Завернуть через iptables или nftables трафик с порта назначения 443 и на ip адреса из ipset/nfset 'zapret' на соксификатор
|
||||
Тоже самое сделать с ipset/nfset 'ipban' для всех tcp портов.
|
||||
Буду рассматривать систему на базе openwrt, где уже установлена система обхода dpi "zapret".
|
||||
Если вам не нужны функции обхода DPI, можно выбрать режим MODE=filter.
|
||||
Если вам не нужны функции обхода DPI, его можно не включать. Обновление фильтра от этого не зависит.
|
||||
|
||||
|
||||
* Сделать так, чтобы все время при загрузке системы на некотором порту возникал socks
|
||||
|
@@ -71,7 +71,7 @@ NLM networks are adapter independent. Usually MAC address of the default router
|
||||
That's why NLM is more universal than `ssid-filter`.
|
||||
|
||||
`Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`.
|
||||
That's why exists separate standalone version in `binaries/win64/zapret-tpws`.
|
||||
If you want to run `winws` from `cygwin` delete, rename or move `cygwin1.dll`.
|
||||
`Cygwin` is required for `blockcheck.sh` support but `winws` itself can be run standalone without cygwin.
|
||||
|
||||
How to get `windows 7` and `winws` compatible `cygwin` :
|
||||
@@ -80,11 +80,11 @@ curl -O https://www.cygwin.com/setup-x86_64.exe
|
||||
setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215
|
||||
```
|
||||
You must choose to install `curl`. To compile from sources install `gcc-core`,`make`,`zlib-devel`.
|
||||
Make from directory `nfq` using `make cygwin64` or `make cygwin32` for 64 and 32 bit versions.
|
||||
|
||||
`winws` requires `cygwin1.dll`, `windivert.dll`, `windivert64.sys`. You can take them from `binaries/win64/zapret-winws`.
|
||||
`winws` requires `cygwin1.dll`, `windivert.dll`, `windivert64.sys` or `windivert32.sys`.
|
||||
You can take them from `binaries/win64` or `binaries/win32`.
|
||||
|
||||
It's possible to build x86 32-bit version but this version is not shipped. You have to build it yourself.
|
||||
32-bit `windivert` can be downloaded from it's developer github. Required version is 2.2.2.
|
||||
There's no `arm64` signed `windivert` driver and no `cygwin`.
|
||||
But it's possible to use unsigned driver version in test mode and user mode components with x64 emulation.
|
||||
x64 emulation requires `windows 11` and not supported in `windows 10`.
|
||||
@@ -120,8 +120,12 @@ cd "C:\\Users\\vasya"
|
||||
cd "C:/Users/vasya"
|
||||
cd "/cygdrive/c/Users/vasya"
|
||||
```
|
||||
`Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`.
|
||||
If you want to run `winws` from `cygwin` delete, rename or move `cygwin1.dll`.
|
||||
|
||||
`Cygwin` is required only for `blockcheck.sh`. Standalone `winws` can be run without it.
|
||||
|
||||
To simplify things it's advised to use `zapret-win-bundle`.
|
||||
|
||||
### auto start
|
||||
|
||||
@@ -159,3 +163,5 @@ unix2dos winws.log
|
||||
```
|
||||
|
||||
`winws.log` will be in `cygwin/home/<username>`. `unix2dos` helps with `windows 7` notepad. It's not necessary in `Windows 10` and later.
|
||||
|
||||
Because 32-bit systems are rare nowadays `zapret-win-bundle` exists only for `Windows x64/arm64`.
|
||||
|
@@ -105,11 +105,11 @@ network locations в win10/11. Кое-что есть в powershell.
|
||||
|
||||
Если в путях присутствуют национальные символы, то при вызове winws из cmd или bat кодировку нужно использовать OEM.
|
||||
Для русского языка это 866. Пути с пробелами нужно брать в кавычки.
|
||||
При использовании опции @<config_file> кодировка в файле должна быть UTF-8 без BOM mark.
|
||||
|
||||
Существует неочевидный момент, каcаемый запуска winws из cygwin шелла. Если в директории, где находится nfqws, находится
|
||||
копия cygwin1.dll, winws не запустится. Поэтому в binaries/win64 существует директория zapret-winws, содержащая полный
|
||||
комплект для запуска без cygwin. Его вы и берете для повседневного использования.
|
||||
Если нужен запуск под cygwin, то следует запускать из binaries/win64. Это нужно для работы blockcheck.
|
||||
Существует неочевидный момент, каcаемый запуска winws из cygwin шелла. Если в директории, где находится winws, находится
|
||||
копия cygwin1.dll, winws не запустится.
|
||||
Если нужен запуск под cygwin, то следует удалить или переместить cygwin1.dll из binaries/win64. Это нужно для работы blockcheck.
|
||||
Из cygwin шелла можно посылать winws сигналы через kill точно так же, как в *nix.
|
||||
|
||||
Как получить совместимый с windows 7 и winws cygwin :
|
||||
@@ -118,10 +118,9 @@ setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouc
|
||||
Следует выбрать установку curl.
|
||||
|
||||
Для сборки из исходников требуется gcc-core,make,zlib-devel.
|
||||
Собирать из директории nfq командой "make cygwin".
|
||||
winws требует cygwin1.dll, windivert.dll, windivert64.sys. Их можно взять из binaries/win64/zapret-winws.
|
||||
Версию для 32-битных x86 windows собрать можно, но такие системы уже уходят в прошлое, поэтому если надо - собирайте сами.
|
||||
32-битный windivert можно взять с сайта разработчика. Требуется версия 2.2.2.
|
||||
Собирать из директории nfq командой "make cygwin64" или "make cygwin32" для 64 и 32 битных версий соответственно.
|
||||
winws требует cygwin1.dll, windivert.dll, windivert64.sys или windivert32.sys.
|
||||
Их можно взять из binaries/win64 и binaries/win32.
|
||||
|
||||
Для arm64 windows нет подписанного драйвера windivert и нет cygwin.
|
||||
Однако, эмуляция x64 windows 11 позволяет использовать все, кроме WinDivert64.sys без изменений.
|
||||
@@ -171,10 +170,15 @@ blockcheck.sh написан на posix shell и требует некоторы
|
||||
Корректный вариант 1 : cd "C:\\Users\\vasya"
|
||||
Корректный вариант 2 : cd "C:/Users/vasya"
|
||||
Корректный вариант 3 : cd "/cygdrive/c/Users/vasya"
|
||||
Существует неочевидный момент, каcаемый запуска winws из cygwin шелла. Если в директории, где находится winws, находится
|
||||
копия cygwin1.dll, winws не запустится. Нужно переименовать файл cygwin1.dll.
|
||||
Далее все как в *nix : 1 раз ./install_bin.sh , затем ./blockcheck.sh.
|
||||
WSL использовать нельзя, это не то же самое.
|
||||
|
||||
cygwin для обычной работы winws не нужен. Разве что вы хотите посылать winws SIGHUP для перечитки листов без перезапуска.
|
||||
cygwin для обычной работы winws не нужен.
|
||||
|
||||
Однако, хотя такой способ и работает, использование winws сильно облегчает zapret-win-bundle.
|
||||
Там нет проблемы с cygwin.dll.
|
||||
|
||||
автозапуск winws
|
||||
----------------
|
||||
@@ -220,3 +224,5 @@ winws --debug --wf-tcp=80,443 | tee winws.log
|
||||
winws.log будет в cygwin/home/<имя_пользователя>
|
||||
Если у вас windows 7, то блокнот не поймет переводы строк в стиле unix. Воспользуйтесь командой
|
||||
unix2dos winws.log
|
||||
|
||||
Поскольку 32-битные windows мало востребованы, zapret-win-bundle существует только в варианте для windows x64/arm64.
|
||||
|
@@ -282,6 +282,14 @@ ipt PREROUTING -t mangle -i $DEVICE -m set --match-set ipban dst -m set ! --matc
|
||||
|
||||
# /etc/init.d/firewall restart
|
||||
|
||||
Чтобы правила обновлялись в процессе поднятия интерфейсов в системе, нужно внести параметр "reload" в указанное место :
|
||||
--- /etc/config/firewall ---
|
||||
config include
|
||||
option path '/etc/firewall.user'
|
||||
option reload '1'
|
||||
----------------------------
|
||||
|
||||
|
||||
--- Маркировка трафика nftables ---
|
||||
|
||||
В новых openwrt по умолчанию установлен nftables, iptables отсутствует.
|
||||
|
@@ -1,18 +0,0 @@
|
||||
# this custom script applies tpws mode as it would be with MODE=tpws
|
||||
|
||||
OVERRIDE=tpws
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1
|
||||
}
|
||||
zapret_custom_firewall_v4()
|
||||
{
|
||||
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v4
|
||||
}
|
||||
zapret_custom_firewall_v6()
|
||||
{
|
||||
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v6
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks
|
||||
|
||||
OVERRIDE=tpws-socks
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1
|
||||
}
|
||||
zapret_custom_firewall_v4()
|
||||
{
|
||||
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v4
|
||||
}
|
||||
zapret_custom_firewall_v6()
|
||||
{
|
||||
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v6
|
||||
}
|
@@ -1,20 +1,19 @@
|
||||
# this script is an example describing how to run tpws on a custom port
|
||||
|
||||
DNUM=100
|
||||
TPPORT_MY=${TPPORT_MY:-987}
|
||||
TPWS_OPT_MY=${TPWS_OPT_MY:-987}
|
||||
TPWS_OPT_SUFFIX_MY="${TPWS_OPT_SUFFIX_MY:-}"
|
||||
DPORTS_MY=${DPORTS_MY:-20443,20444,30000-30009}
|
||||
TPWS_OPT_EXTRA=${TPWS_OPT_EXTRA:---split-pos=2}
|
||||
DPORTS_EXTRA=${DPORTS_EXTRA:-20443,20444,30000-30009}
|
||||
|
||||
alloc_dnum DNUM_EXTRA_TPWS
|
||||
alloc_tpws_port TPPORT_EXTRA_TPWS
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
local opt="--user=root --port=$TPPORT_MY"
|
||||
local opt="--user=root --port=$TPPORT_EXTRA_TPWS"
|
||||
tpws_apply_binds opt
|
||||
opt="$opt $TPWS_OPT_MY"
|
||||
opt="$opt $TPWS_OPT_EXTRA"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$TPWS_OPT_SUFFIX_MY"
|
||||
do_daemon $1 $DNUM "$TPWS" "$opt"
|
||||
do_daemon $1 $DNUM_EXTRA_TPWS "$TPWS" "$opt"
|
||||
}
|
||||
|
||||
# custom firewall functions echo rules for zapret-v4 and zapret-v6 anchors
|
||||
@@ -22,9 +21,9 @@ zapret_custom_daemons()
|
||||
|
||||
zapret_custom_firewall_v4()
|
||||
{
|
||||
pf_anchor_zapret_v4_tpws $TPPORT_MY $(replace_char - : $DPORTS_MY)
|
||||
pf_anchor_zapret_v4_tpws $TPPORT_EXTRA_TPWS $(replace_char - : $DPORTS_EXTRA)
|
||||
}
|
||||
zapret_custom_firewall_v6()
|
||||
{
|
||||
pf_anchor_zapret_v6_tpws $TPPORT_MY $(replace_char - : $DPORTS_MY)
|
||||
pf_anchor_zapret_v6_tpws $TPPORT_EXTRA_TPWS $(replace_char - : $DPORTS_EXTRA)
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ IPSET_DIR=$ZAPRET_BASE/ipset
|
||||
|
||||
PIDDIR=/var/run
|
||||
[ -n "$TPPORT" ] || TPPORT=988
|
||||
[ -n "$TPPORT_SOCKS" ] || TPPORT=987
|
||||
[ -n "$WS_USER" ] || WS_USER=daemon
|
||||
TPWS_WAIT="--bind-wait-ifup=30 --bind-wait-ip=30"
|
||||
TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30"
|
||||
@@ -117,18 +118,14 @@ zapret_do_firewall()
|
||||
[ "$1" = 1 -a -n "$INIT_FW_PRE_UP_HOOK" ] && $INIT_FW_PRE_UP_HOOK
|
||||
[ "$1" = 0 -a -n "$INIT_FW_PRE_DOWN_HOOK" ] && $INIT_FW_PRE_DOWN_HOOK
|
||||
|
||||
case "${MODE_OVERRIDE:-$MODE}" in
|
||||
tpws|filter|custom)
|
||||
if [ "$1" = "1" ] ; then
|
||||
pf_anchor_root || return 1
|
||||
pf_anchors_create
|
||||
pf_anchors_load || return 1
|
||||
pf_enable
|
||||
else
|
||||
pf_anchors_clear
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if [ "$1" = "1" ] ; then
|
||||
pf_anchor_root || return 1
|
||||
pf_anchors_create
|
||||
pf_anchors_load || return 1
|
||||
pf_enable
|
||||
else
|
||||
pf_anchors_clear
|
||||
fi
|
||||
|
||||
[ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK
|
||||
[ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK
|
||||
@@ -150,49 +147,36 @@ zapret_restart_firewall()
|
||||
}
|
||||
|
||||
|
||||
standard_mode_daemons()
|
||||
{
|
||||
local opt
|
||||
|
||||
if [ "$1" = "1" ] && [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] ; then
|
||||
echo "both ipv4 and ipv6 are disabled. nothing to do"
|
||||
else
|
||||
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
|
||||
opt="--user=root --port=$TPPORT"
|
||||
tpws_apply_binds opt
|
||||
opt="$opt $TPWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
do_daemon $1 1 "$TPWS" "$opt"
|
||||
}
|
||||
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
||||
opt="--socks --user=$WS_USER --port=$TPPORT_SOCKS"
|
||||
tpws_apply_socks_binds opt
|
||||
opt="$opt $TPWS_SOCKS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
do_daemon $1 2 "$TPWS" "$opt"
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
zapret_do_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local opt
|
||||
|
||||
case "${MODE_OVERRIDE:-$MODE}" in
|
||||
tpws)
|
||||
[ "$1" = "1" ] && [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && {
|
||||
echo "both ipv4 and ipv6 are disabled. nothing to do"
|
||||
return 0
|
||||
}
|
||||
# MacOS requires root. kernel hardcoded requirement for /dev/pf ioctls
|
||||
opt="--user=root --port=$TPPORT"
|
||||
tpws_apply_binds opt
|
||||
opt="$opt $TPWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
|
||||
do_daemon $1 1 "$TPWS" "$opt"
|
||||
;;
|
||||
tpws-socks)
|
||||
[ "$1" = "1" ] && [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && {
|
||||
echo "both ipv4 and ipv6 are disabled. nothing to do"
|
||||
return 0
|
||||
}
|
||||
opt="--socks --user=$WS_USER --port=$TPPORT"
|
||||
tpws_apply_socks_binds opt
|
||||
opt="$opt $TPWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
|
||||
do_daemon $1 1 "$TPWS" "$opt"
|
||||
;;
|
||||
filter)
|
||||
;;
|
||||
custom)
|
||||
custom_runner zapret_custom_daemons $1
|
||||
;;
|
||||
*)
|
||||
echo "unsupported MODE=$MODE"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
standard_mode_daemons $1
|
||||
custom_runner zapret_custom_daemons $1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
54
init.d/openwrt-minimal/readme.txt
Normal file
54
init.d/openwrt-minimal/readme.txt
Normal file
@@ -0,0 +1,54 @@
|
||||
Minimal tpws startup script for low storage openwrt.
|
||||
|
||||
--- openwrt with NFTABLES (22+)
|
||||
|
||||
Make sure you are running openwrt with nftables, not iptables.
|
||||
No opkg dependencies required !
|
||||
|
||||
* install :
|
||||
|
||||
Copy everything from tpws directory to the root of the router.
|
||||
Copy tpws binary for your architecture to /usr/bin/tpws
|
||||
Set proper access rights : chmod 755 /etc/init.d/tpws /usr/bin/tpws
|
||||
EDIT /etc/config/tpws
|
||||
If you don't want ipv6 : edit /etc/nftables.d and comment lines with ipv6 redirect
|
||||
/etc/init.d/tpws enable
|
||||
/etc/init.d/tpws start
|
||||
fw4 restart
|
||||
|
||||
* full uninstall :
|
||||
|
||||
/etc/init.d/tpws disable
|
||||
/etc/init.d/tpws stop
|
||||
rm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpws
|
||||
fw4 restart
|
||||
|
||||
--- openwrt with IPTABLES (21-)
|
||||
|
||||
Make sure you are running openwrt with iptables, not nftables.
|
||||
Make sure you do not have anything valuable in /etc/firewall.user.
|
||||
If you have - do not blindly follow instruction in firewall.user part.
|
||||
Merge the code instead or setup your own firewall include in /etc/config/firewall.
|
||||
|
||||
opkg update
|
||||
opkg install iptables-mod-extra
|
||||
IPV6 ONLY : opkg install ip6tables-mod-nat
|
||||
|
||||
* install :
|
||||
|
||||
Copy everything from tpws directory to the root of the router.
|
||||
Copy tpws binary for your architecture to /usr/bin/tpws
|
||||
Set proper access rights : chmod 755 /etc/init.d/tpws /usr/bin/tpws
|
||||
EDIT /etc/config/tpws
|
||||
If you don't want ipv6 : edit /etc/firewall.user and set DISABLE_IPV6=1
|
||||
/etc/init.d/tpws enable
|
||||
/etc/init.d/tpws start
|
||||
fw3 restart
|
||||
|
||||
* full uninstall :
|
||||
|
||||
/etc/init.d/tpws disable
|
||||
/etc/init.d/tpws stop
|
||||
rm -f /etc/nftables.d/90-tpws.nft /etc/firewall.user /etc/init.d/tpws
|
||||
touch /etc/firewall.user
|
||||
fw3 restart
|
12
init.d/openwrt-minimal/tpws/etc/config/tpws
Normal file
12
init.d/openwrt-minimal/tpws/etc/config/tpws
Normal file
@@ -0,0 +1,12 @@
|
||||
config global defaults
|
||||
option user daemon
|
||||
option tpws /usr/bin/tpws
|
||||
|
||||
config tpws
|
||||
option port 900
|
||||
option opt '--split-pos=2 --oob'
|
||||
option enabled 1
|
||||
config tpws
|
||||
option port 901
|
||||
option opt '--split-tls=sni --disorder'
|
||||
option enabled 0
|
49
init.d/openwrt-minimal/tpws/etc/firewall.user
Normal file
49
init.d/openwrt-minimal/tpws/etc/firewall.user
Normal file
@@ -0,0 +1,49 @@
|
||||
DISABLE_IPV6=0
|
||||
TP_PORT=900
|
||||
TP_USER=daemon
|
||||
|
||||
EXCLUDE4="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 127.0.0.0/8"
|
||||
EXCLUDE6="fc00::/7 fe80::/10 ::1"
|
||||
IPTS="iptables ip6tables"
|
||||
[ "$DISABLE_IPV6" = 1 ] && IPTS=iptables
|
||||
|
||||
exists()
|
||||
{
|
||||
which "$1" >/dev/null 2>/dev/null
|
||||
}
|
||||
|
||||
ipt()
|
||||
{
|
||||
$IPTABLES -C "$@" >/dev/null 2>/dev/null || $IPTABLES -I "$@"
|
||||
}
|
||||
|
||||
redirect_port()
|
||||
{
|
||||
ipt tpws -t nat -p tcp --dport $1 -j REDIRECT --to-port $2
|
||||
}
|
||||
|
||||
redirect()
|
||||
{
|
||||
redirect_port 80 $TP_PORT
|
||||
redirect_port 443 $TP_PORT
|
||||
}
|
||||
|
||||
for IPTABLES in $IPTS; do
|
||||
$IPTABLES -t nat -N tpws 2>/dev/null
|
||||
$IPTABLES -t nat -F tpws
|
||||
redirect
|
||||
done
|
||||
|
||||
for net in $EXCLUDE4; do
|
||||
iptables -t nat -I tpws -d $net -j RETURN
|
||||
done
|
||||
[ "$DISABLE_IPV6" = 1 ] || {
|
||||
for net in $EXCLUDE6; do
|
||||
ip6tables -t nat -I tpws -d $net -j RETURN
|
||||
done
|
||||
}
|
||||
|
||||
for IPTABLES in $IPTS; do
|
||||
ipt PREROUTING -t nat -j tpws
|
||||
ipt OUTPUT -t nat -m owner ! --uid-owner $TP_USER -j tpws
|
||||
done
|
34
init.d/openwrt-minimal/tpws/etc/init.d/tpws
Executable file
34
init.d/openwrt-minimal/tpws/etc/init.d/tpws
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
TPWS_DEFAULT=/usr/bin/tpws
|
||||
TPWS_USER_DEFAULT=daemon
|
||||
|
||||
START=99
|
||||
STOP=01
|
||||
USE_PROCD=1
|
||||
|
||||
tpws_instance()
|
||||
{
|
||||
config_get "$@"
|
||||
|
||||
local enabled port opt
|
||||
|
||||
config_get_bool enabled "$1" enabled 0
|
||||
[ "$enabled" -eq 1 ] || return 1
|
||||
|
||||
config_get port "$1" port
|
||||
config_get opt "$1" opt
|
||||
|
||||
local COMMAND="$TPWS --user=$TPWS_USER --port=$port $opt"
|
||||
procd_open_instance
|
||||
procd_set_param command $COMMAND
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
start_service()
|
||||
{
|
||||
config_load tpws
|
||||
config_get TPWS_USER defaults user $TPWS_USER_DEFAULT
|
||||
config_get TPWS defaults tpws $TPWS_DEFAULT
|
||||
config_foreach tpws_instance tpws
|
||||
}
|
18
init.d/openwrt-minimal/tpws/etc/nftables.d/90-tpws.nft
Normal file
18
init.d/openwrt-minimal/tpws/etc/nftables.d/90-tpws.nft
Normal file
@@ -0,0 +1,18 @@
|
||||
set tpws_exclude4 {
|
||||
type ipv4_addr; flags interval; auto-merge;
|
||||
elements = { 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,127.0.0.0/8 }
|
||||
}
|
||||
set tpws_exclude6 {
|
||||
type ipv6_addr; flags interval; auto-merge;
|
||||
elements = { fc00::/7, fe80::/10, ::1 }
|
||||
}
|
||||
chain tpws_pre {
|
||||
type nat hook prerouting priority dstnat; policy accept;
|
||||
tcp dport {80,443} ip daddr != @tpws_exclude4 redirect to :900
|
||||
tcp dport {80,443} ip6 daddr != @tpws_exclude6 redirect to :900
|
||||
}
|
||||
chain tpws_out {
|
||||
type nat hook output priority -100; policy accept;
|
||||
tcp dport {80,443} skuid != daemon ip daddr != @tpws_exclude4 redirect to :900
|
||||
tcp dport {80,443} skuid != daemon ip6 daddr != @tpws_exclude6 redirect to :900
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
# this custom script applies nfqws mode as it would be with MODE=nfqws
|
||||
|
||||
OVERRIDE=nfqws
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# stop logic is managed by procd
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE start_daemons_procd
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
# this custom script applies tpws mode as it would be with MODE=tpws
|
||||
|
||||
OVERRIDE=tpws
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE start_daemons_procd
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks
|
||||
|
||||
OVERRIDE=tpws-socks
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE start_daemons_procd
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft
|
||||
}
|
@@ -1,15 +1,17 @@
|
||||
# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering
|
||||
# need to add to config : NFQWS_OPT_DESYNC_DHT="--dpi-desync=fake --dpi-desync-ttl=5"
|
||||
|
||||
DNUM=101
|
||||
QNUM2=$(($DNUM * 5))
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---dpi-desync=tamper}"
|
||||
|
||||
alloc_dnum DNUM_DHT4ALL
|
||||
alloc_qnum QNUM_DHT4ALL
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# stop logic is managed by procd
|
||||
|
||||
local opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
||||
run_daemon $DNUM $NFQWS "$opt"
|
||||
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_DHT"
|
||||
run_daemon $DNUM_DHT4ALL $NFQWS "$opt"
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
@@ -17,12 +19,11 @@ zapret_custom_firewall()
|
||||
|
||||
local f uf4 uf6
|
||||
local first_packet_only="$ipt_connbytes 1:1"
|
||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||
|
||||
f='-p udp -m length --length 109:407 -m u32 --u32'
|
||||
uf4='0>>22&0x3C@8>>16=0x6431'
|
||||
uf6='48>>16=0x6431'
|
||||
fw_nfqws_post $1 "$f $uf4 $desync $first_packet_only" "$f $uf6 $desync $first_packet_only" $QNUM2
|
||||
fw_nfqws_post $1 "$f $uf4 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL
|
||||
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
@@ -31,9 +32,7 @@ zapret_custom_firewall_nft()
|
||||
|
||||
local f
|
||||
local first_packet_only="$nft_connbytes 1"
|
||||
local desync="mark and $DESYNC_MARK == 0"
|
||||
|
||||
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
|
||||
nft_fw_nfqws_post "$f $desync $first_packet_only" "$f $desync $first_packet_only" $QNUM2
|
||||
nft_fw_nfqws_post "$f $first_packet_only" "$f $first_packet_only" $QNUM_DHT4ALL
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@@ -1,37 +0,0 @@
|
||||
# this custom script runs desync to all QUIC initial packets, without ipset/hostlist filtering
|
||||
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
|
||||
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
|
||||
|
||||
DNUM=102
|
||||
QNUM2=$(($DNUM * 5))
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
|
||||
run_daemon $DNUM $NFQWS "$opt"
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local f
|
||||
local first_packets_only="$ipt_connbytes 1:3"
|
||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||
|
||||
f="-p udp -m multiport --dports $QUIC_PORTS_IPT"
|
||||
fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2
|
||||
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
local f
|
||||
local first_packets_only="$nft_connbytes 1-3"
|
||||
local desync="mark and $DESYNC_MARK == 0"
|
||||
|
||||
f="udp dport {$QUIC_PORTS}"
|
||||
nft_fw_nfqws_post "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2
|
||||
}
|
@@ -1,71 +0,0 @@
|
||||
# this custom script demonstrates how to apply tpws to http and nfqws to https
|
||||
# it preserves config settings : MODE_HTTP, MODE_HTTPS, MODE_FILTER, TPWS_OPT, NFQWS_OPT_DESYNC, NFQWS_OPT_DESYNC_HTTPS
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local opt
|
||||
|
||||
[ "$MODE_HTTP" = "1" ] && {
|
||||
opt="--port=$TPPORT $TPWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
|
||||
run_tpws 1 "$opt"
|
||||
}
|
||||
|
||||
[ "$MODE_HTTPS" = "1" ] && {
|
||||
opt="--qnum=$QNUM $NFQWS_OPT_DESYNC_HTTPS"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS_SUFFIX"
|
||||
run_daemon 2 $NFQWS "$opt"
|
||||
}
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local f4 f6
|
||||
local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)"
|
||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||
|
||||
[ "$MODE_HTTP" = "1" ] && {
|
||||
f4="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
|
||||
f6=$f4
|
||||
filter_apply_ipset_target f4 f6
|
||||
fw_tpws $1 "$f4" "$f6" $TPPORT
|
||||
}
|
||||
|
||||
[ "$MODE_HTTPS" = "1" ] && {
|
||||
f4="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
|
||||
f6=$f4
|
||||
filter_apply_ipset_target f4 f6
|
||||
fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM
|
||||
# for modes that require incoming traffic
|
||||
fw_reverse_nfqws_rule $1 "$f4" "$f6" $QNUM
|
||||
}
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
local f4 f6
|
||||
local first_packet_only="$nft_connbytes 1-$(first_packets_for_mode)"
|
||||
local desync="mark and $DESYNC_MARK == 0"
|
||||
|
||||
[ "$MODE_HTTP" = "1" ] && {
|
||||
f4="tcp dport {$HTTP_PORTS}"
|
||||
f6=$f4
|
||||
nft_filter_apply_ipset_target f4 f6
|
||||
nft_fw_tpws "$f4" "$f6" $TPPORT
|
||||
}
|
||||
|
||||
[ "$MODE_HTTPS" = "1" ] && {
|
||||
f4="tcp dport {$HTTPS_PORTS} $first_packet_only"
|
||||
f6=$f4
|
||||
nft_filter_apply_ipset_target f4 f6
|
||||
nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
||||
# for modes that require incoming traffic
|
||||
nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM
|
||||
}
|
||||
}
|
@@ -6,7 +6,6 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
||||
. "$ZAPRET_CONFIG"
|
||||
. "$ZAPRET_BASE/common/base.sh"
|
||||
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||
. "$ZAPRET_BASE/common/queue.sh"
|
||||
. "$ZAPRET_BASE/common/linux_iphelper.sh"
|
||||
. "$ZAPRET_BASE/common/ipt.sh"
|
||||
. "$ZAPRET_BASE/common/nft.sh"
|
||||
@@ -17,6 +16,7 @@ CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
|
||||
|
||||
[ -n "$QNUM" ] || QNUM=200
|
||||
[ -n "$TPPORT" ] || TPPORT=988
|
||||
[ -n "$TPPORT_SOCKS" ] || TPPORT_SOCKS=987
|
||||
[ -n "$WS_USER" ] || WS_USER=daemon
|
||||
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
|
||||
[ -n "$DESYNC_MARK_POSTNAT" ] || DESYNC_MARK_POSTNAT=0x20000000
|
||||
@@ -32,8 +32,6 @@ IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
|
||||
IPSET_EXCLUDE="-m set ! --match-set nozapret"
|
||||
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
||||
|
||||
apply_unspecified_desync_modes
|
||||
|
||||
|
||||
# can be multiple ipv6 outgoing interfaces
|
||||
# uplink from isp, tunnelbroker, vpn, ...
|
||||
|
@@ -114,68 +114,30 @@ tpws_apply_socks_binds()
|
||||
}
|
||||
|
||||
|
||||
standard_mode_daemons()
|
||||
{
|
||||
local opt
|
||||
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$TPWS_OPT" && {
|
||||
opt="--port=$TPPORT $TPWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
run_tpws 1 "$opt"
|
||||
}
|
||||
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
||||
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
run_tpws_socks 2 "$opt"
|
||||
}
|
||||
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$NFQWS_OPT" && {
|
||||
opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
run_daemon 3 "$NFQWS" "$opt"
|
||||
}
|
||||
}
|
||||
|
||||
start_daemons_procd()
|
||||
{
|
||||
local opt qn qns qn6 qns6
|
||||
|
||||
case "${MODE_OVERRIDE:-$MODE}" in
|
||||
tpws)
|
||||
opt="--port=$TPPORT $TPWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
|
||||
run_tpws 1 "$opt"
|
||||
;;
|
||||
tpws-socks)
|
||||
opt="--port=$TPPORT $TPWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
|
||||
run_tpws_socks 1 "$opt"
|
||||
;;
|
||||
nfqws)
|
||||
# quite complex but we need to minimize nfqws processes to save RAM
|
||||
get_nfqws_qnums qn qns qn6 qns6
|
||||
[ -z "$qn" ] || {
|
||||
opt="--qnum=$qn $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTP"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTP_SUFFIX"
|
||||
run_daemon 1 "$NFQWS" "$opt"
|
||||
}
|
||||
[ -z "$qns" ] || [ "$qns" = "$qn" ] || {
|
||||
opt="--qnum=$qns $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS_SUFFIX"
|
||||
run_daemon 2 "$NFQWS" "$opt"
|
||||
}
|
||||
[ -z "$qn6" ] || [ "$qn6" = "$qn" ] || [ "$qn6" = "$qns" ] || {
|
||||
opt="--qnum=$qn6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTP6"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTP6_SUFFIX"
|
||||
run_daemon 3 "$NFQWS" "$opt"
|
||||
}
|
||||
[ -z "$qns6" ] || [ "$qns6" = "$qn" ] || [ "$qns6" = "$qns" ] || [ "$qns6" = "$qn6" ] || {
|
||||
opt="--qnum=$qns6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS6"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS6_SUFFIX"
|
||||
run_daemon 4 "$NFQWS" "$opt"
|
||||
}
|
||||
get_nfqws_qnums_quic qn qn6
|
||||
[ -z "$qn" ] || {
|
||||
opt="--qnum=$qn $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_QUIC_SUFFIX"
|
||||
run_daemon 10 "$NFQWS" "$opt"
|
||||
}
|
||||
[ -z "$qn6" ] || [ "$qn6" = "$qn" ] || {
|
||||
opt="--qnum=$qn6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC6"
|
||||
filter_apply_hostlist_target opt
|
||||
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_QUIC6_SUFFIX"
|
||||
run_daemon 11 "$NFQWS" "$opt"
|
||||
}
|
||||
;;
|
||||
custom)
|
||||
custom_runner zapret_custom_daemons $1
|
||||
;;
|
||||
esac
|
||||
standard_mode_daemons
|
||||
custom_runner zapret_custom_daemons
|
||||
|
||||
return 0
|
||||
}
|
||||
|
@@ -1,22 +0,0 @@
|
||||
# this custom script applies nfqws mode as it would be with MODE=nfqws
|
||||
|
||||
OVERRIDE=nfqws
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_do_firewall_rules_ipt $1
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
MODE_OVERRIDE=$OVERRIDE zapret_apply_firewall_rules_nft
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user