mirror of
https://github.com/bol-van/zapret.git
synced 2025-12-25 00:48:09 +03:00
Compare commits
129 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c8e4ed15d | ||
|
|
8c06a6335d | ||
|
|
f12cae3674 | ||
|
|
170281bfa6 | ||
|
|
5d4747458f | ||
|
|
5774e883d6 | ||
|
|
80b801c1ca | ||
|
|
9d8ee398c3 | ||
|
|
4d35d8d1ec | ||
|
|
977d117417 | ||
|
|
cc8313db51 | ||
|
|
1e51f90130 | ||
|
|
da6b89e739 | ||
|
|
90470440a7 | ||
|
|
a5c9d79417 | ||
|
|
c003ef2a7b | ||
|
|
42541fcab8 | ||
|
|
20b5952978 | ||
|
|
4b6aa1b5f9 | ||
|
|
9e141dcefd | ||
|
|
b1b992eb3f | ||
|
|
2d061c911a | ||
|
|
a213084188 | ||
|
|
1c7ec32b96 | ||
|
|
dcd9cfbb2b | ||
|
|
beb0692d28 | ||
|
|
140af2b741 | ||
|
|
f8cc109f0b | ||
|
|
b4a2f44d56 | ||
|
|
14d05d8012 | ||
|
|
71d5afeaf4 | ||
|
|
45df8bfb09 | ||
|
|
784058cf66 | ||
|
|
ce367b1a91 | ||
|
|
a832c19974 | ||
|
|
2c14109163 | ||
|
|
c467e696e3 | ||
|
|
528c27a01a | ||
|
|
c2f1e708fc | ||
|
|
211a4f4673 | ||
|
|
fd81053d79 | ||
|
|
1bb9f260dd | ||
|
|
26f3cbd06f | ||
|
|
e384f88931 | ||
|
|
59bce0036b | ||
|
|
0a48c923b8 | ||
|
|
ed4782887f | ||
|
|
80b6b75934 | ||
|
|
245ce41550 | ||
|
|
db5dca28b0 | ||
|
|
6dad239fe3 | ||
|
|
aa4982a526 | ||
|
|
61808b37d8 | ||
|
|
4b90ee920c | ||
|
|
170e9d7ffd | ||
|
|
d8f9ba29c3 | ||
|
|
4914b813e7 | ||
|
|
c3fdec9bf0 | ||
|
|
1cbdf9b891 | ||
|
|
706dd7b2d9 | ||
|
|
b2468a9095 | ||
|
|
acfbbc58ac | ||
|
|
fd506dfe08 | ||
|
|
1ee25e01ea | ||
|
|
521c385adb | ||
|
|
17971e87b4 | ||
|
|
4dc1d035d8 | ||
|
|
07eee8af25 | ||
|
|
06e7818240 | ||
|
|
00b0f3c940 | ||
|
|
17df2adbe0 | ||
|
|
40342745f7 | ||
|
|
54d4cdb2d5 | ||
|
|
b251ea839c | ||
|
|
595cf863fc | ||
|
|
91d5b90ded | ||
|
|
33a7132920 | ||
|
|
d9b23f14a2 | ||
|
|
06613b4fd5 | ||
|
|
7364bab8a7 | ||
|
|
1f48453989 | ||
|
|
dc5efebee2 | ||
|
|
10c9499647 | ||
|
|
a50082df92 | ||
|
|
0c33bbfb37 | ||
|
|
ea1be413a6 | ||
|
|
850d4023fb | ||
|
|
4872b8e4e8 | ||
|
|
75eaefa950 | ||
|
|
582ade3190 | ||
|
|
efd369bb0e | ||
|
|
784465bdcf | ||
|
|
40a80cd328 | ||
|
|
73f21b0524 | ||
|
|
34698479d0 | ||
|
|
0830633f42 | ||
|
|
fc837e14fa | ||
|
|
0e288262b5 | ||
|
|
dce049d6b8 | ||
|
|
d103602d86 | ||
|
|
aaf8f18a7d | ||
|
|
de19cc3cd4 | ||
|
|
1e56703d4b | ||
|
|
cd0f1c4bdf | ||
|
|
135b152497 | ||
|
|
56456c1e0c | ||
|
|
d6a8d1dc33 | ||
|
|
04b3b6abcb | ||
|
|
fd58ecf8a5 | ||
|
|
a560e251a1 | ||
|
|
2ff0f9c0ff | ||
|
|
4dbd673eaa | ||
|
|
497810ab4e | ||
|
|
4cfed1db7e | ||
|
|
fd6b7a2b7f | ||
|
|
6d865ad790 | ||
|
|
dfe36aee4c | ||
|
|
2d704a859d | ||
|
|
8026d11f71 | ||
|
|
2f77cec863 | ||
|
|
ba7954f068 | ||
|
|
8b5c951451 | ||
|
|
84e75b0f28 | ||
|
|
c4e5db309f | ||
|
|
769f7b60c8 | ||
|
|
b0578c5e9f | ||
|
|
40362bfb5b | ||
|
|
10eb9050a1 | ||
|
|
b63e598085 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,3 +1,4 @@
|
||||
* text=auto eol=lf
|
||||
*.cmd eol=crlf
|
||||
*.bat eol=crlf
|
||||
init.d/windivert.filter.examples/** eol=crlf
|
||||
|
||||
24
.github/ISSUE_TEMPLATE/issue-warning.md
vendored
24
.github/ISSUE_TEMPLATE/issue-warning.md
vendored
@@ -7,13 +7,19 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
1. Здесь не место для вопросов, касающихся компьютерной грамотности и навыков использования ОС
|
||||
2. Здесь не место для вопросов "у меня не работает" без технических подробностей
|
||||
3. Здесь не место для вопросов "как мне открыть ютуб", "что писать в ...", "перестало открываться".
|
||||
4. Здесь не место для обсуждения сборок
|
||||
5. Вирусов здесь нет. У вас либо чья-то сборка, либо ваш антивирус давно пора отправить на покой. Антивирусы в основном жалуются на upx и windivert, которые убраны НЕ будут. upx - это паковщик для сокращения требуемого места на openwrt, windivert - замена iptables для windows, потенциальный инструмент хакера или компонент зловредной программы, но сам по себе вирусом не является. Не согласны - удаляйте софт. За агрессивные наезды "почему автор распространяет вирусы" молча схватите бан.
|
||||
Issues - это место для обращений к разработчику.
|
||||
Discussions - место для обсуждения вопросов между пользователями.
|
||||
Не тратье время разработчика на ерунду. Вам не будут здесь обьяснять как скопировать, что "писать в", почему сразу же закрывается окно, почему не открывается сайт или госуслуги. Здесь не место обсуждению любых шаманств , т.е. манипуляций без понимания, в стиле 4pda.
|
||||
Пишите только конкретные проблемы на техническом уровне в оригинальном zapret (не в сборках), которые вы заметили, и которые являются или могут являться багами в софте.
|
||||
Или если вы считаете, что ваше обращение обосновано, технически грамотно и по адресу.
|
||||
Все, что будет нарушать эти критерии, может быть молча удалено, закрыто или перенесено в дискуссии на усмотрение разработчика.
|
||||
Если сомневаетесь - пишите лучше сразу в дискуссии.
|
||||
|
||||
Все означенное обсуждать в дискуссиях или на форумах.
|
||||
При нарушении будет закрываться или конвертироваться в дискуссии.
|
||||
Issue только для обсуждения проблем самого софта. Неработа стратегии или ваше неумение настроить - это ваша проблема, а не проблема софта.
|
||||
Однокнопочные решения дают только сборщики, поэтому "открытие сайта" не является функцией программы, и нет смысла жаловаться, что он не открывается. Но можно это обсудить в дискуссиях. Не захламляйте issues !
|
||||
Прочитайте для начала docs/quick_start.md или docs/quick_start_windows.md.
|
||||
Там обьясняется для кого этот софт, какие требуются знания, почему это не простая волшебная таблетка.
|
||||
|
||||
Вирусов здесь нет. У вас либо чья-то сборка, либо ваш антивирус давно пора отправить на покой. Антивирусы в основном жалуются на upx и windivert, которые убраны НЕ будут. upx - это паковщик для сокращения требуемого места на openwrt, windivert - замена iptables для windows, потенциальный инструмент хакера или компонент зловредной программы, но сам по себе вирусом не является. Не согласны - удаляйте софт. За агрессивные наезды "почему автор распространяет вирусы" молча схватите бан.
|
||||
|
||||
|
||||
Here is the place for bugs only. All questions, especially user-like questions (non-technical) go to Discussions.
|
||||
There're also no viruses here. All virus claims and everyting non-technical and non-bugs will be instantly deleted, closed or moved to Discussions.
|
||||
|
||||
183
blockcheck.sh
183
blockcheck.sh
@@ -47,6 +47,7 @@ HTTPS_PORT=${HTTPS_PORT:-443}
|
||||
QUIC_PORT=${QUIC_PORT:-443}
|
||||
UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org}
|
||||
PARALLEL_OUT=/tmp/zapret_parallel
|
||||
SIM_SUCCESS_RATE=${SIM_SUCCESS_RATE:-10}
|
||||
|
||||
HDRTEMP=/tmp/zapret-hdr
|
||||
|
||||
@@ -396,6 +397,9 @@ check_system()
|
||||
PKTWS="$WINWS"
|
||||
PKTWSD=winws
|
||||
FWTYPE=windivert
|
||||
# ts fooling requires timestamps. they are disabled by default in windows.
|
||||
echo enabling tcp timestamps
|
||||
netsh interface tcp set global timestamps=enabled >/dev/null
|
||||
;;
|
||||
*)
|
||||
echo $UNAME not supported
|
||||
@@ -408,6 +412,13 @@ check_system()
|
||||
else
|
||||
uname -a
|
||||
fi
|
||||
[ -f /etc/os-release ] && {
|
||||
. /etc/os-release
|
||||
[ -n "$PRETTY_NAME" ] && echo "distro: $PRETTY_NAME"
|
||||
[ -n "$OPENWRT_RELEASE" ] && echo "openwrt release: $OPENWRT_RELEASE"
|
||||
[ -n "$OPENWRT_BOARD" ] && echo "openwrt board: $OPENWRT_BOARD"
|
||||
[ -n "$OPENWRT_ARCH" ] && echo "openwrt arch: $OPENWRT_ARCH"
|
||||
}
|
||||
echo firewall type is $FWTYPE
|
||||
echo CURL=$CURL
|
||||
$CURL --version
|
||||
@@ -800,7 +811,7 @@ nft_scheme()
|
||||
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 chain inet $NFT_TABLE postnat { type filter hook postrouting priority 102; }"
|
||||
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK == 0 ip${ipver} daddr {$iplist} ct mark set ct mark or $DESYNC_MARK queue num $QNUM"
|
||||
# for strategies with incoming packets involved (autottl)
|
||||
nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }"
|
||||
@@ -1060,6 +1071,17 @@ ws_curl_test()
|
||||
# $3 - domain
|
||||
# $4,$5,$6, ... - ws params
|
||||
local code ws_start=$1 testf=$2 dom=$3
|
||||
|
||||
[ "$SIMULATE" = 1 ] && {
|
||||
n=$(random 0 99)
|
||||
if [ "$n" -lt "$SIM_SUCCESS_RATE" ]; then
|
||||
echo "SUCCESS"
|
||||
return 0
|
||||
else
|
||||
echo "FAILED"
|
||||
return 7
|
||||
fi
|
||||
}
|
||||
shift
|
||||
shift
|
||||
shift
|
||||
@@ -1082,7 +1104,7 @@ tpws_curl_test()
|
||||
shift; shift;
|
||||
strategy="$@"
|
||||
strategy_append_extra_tpws
|
||||
report_append "ipv${IPV} $dom $testf : tpws ${WF:+$WF }$strategy"
|
||||
report_append "$dom" "$testf ipv${IPV}" "tpws ${WF:+$WF }$strategy"
|
||||
}
|
||||
return $code
|
||||
}
|
||||
@@ -1101,7 +1123,7 @@ pktws_curl_test()
|
||||
[ "$code" = 0 ] && {
|
||||
strategy="$@"
|
||||
strategy_append_extra_pktws
|
||||
report_append "ipv${IPV} $dom $testf : $PKTWSD ${WF:+$WF }$strategy"
|
||||
report_append "$dom" "$testf ipv${IPV}" "$PKTWSD ${WF:+$WF }$strategy"
|
||||
}
|
||||
return $code
|
||||
}
|
||||
@@ -1141,8 +1163,35 @@ tpws_curl_test_update()
|
||||
|
||||
report_append()
|
||||
{
|
||||
# $1 - domain
|
||||
# $2 - test function + ipver
|
||||
# $3 - value
|
||||
local hashstr hash hashvar hashcountvar val ct
|
||||
|
||||
# save resources if only one domain
|
||||
[ "$DOMAINS_COUNT" -gt 1 ] && {
|
||||
hashstr="$2 : $3"
|
||||
hash="$(echo -n "$hashstr" | md5f)"
|
||||
hashvar=RESHASH_${hash}
|
||||
hashcountvar=${hashvar}_COUNTER
|
||||
|
||||
NRESHASH=${NRESHASH:-0}
|
||||
|
||||
eval val="\$$hashvar"
|
||||
if [ -n "$val" ]; then
|
||||
eval ct="\$$hashcountvar"
|
||||
ct=$(($ct + 1))
|
||||
eval $hashcountvar="\$ct"
|
||||
else
|
||||
eval $hashvar=\"$hashstr\"
|
||||
eval $hashcountvar=1
|
||||
eval RES_$NRESHASH="\$hash"
|
||||
NRESHASH=$(($NRESHASH+1))
|
||||
fi
|
||||
}
|
||||
|
||||
NREPORT=${NREPORT:-0}
|
||||
eval REPORT_${NREPORT}=\"$@\"
|
||||
eval REPORT_${NREPORT}=\"$2 $1 : $3\"
|
||||
NREPORT=$(($NREPORT+1))
|
||||
}
|
||||
report_print()
|
||||
@@ -1155,6 +1204,22 @@ report_print()
|
||||
n=$(($n+1))
|
||||
done
|
||||
}
|
||||
result_intersection_print()
|
||||
{
|
||||
local n=0 hash hashvar hashcountvar ct val
|
||||
while : ; do
|
||||
eval hash=\"\$RES_$n\"
|
||||
[ -n "$hash" ] || break
|
||||
hashvar=RESHASH_${hash}
|
||||
hashcountvar=${hashvar}_COUNTER
|
||||
eval ct=\"\$$hashcountvar\"
|
||||
[ "$ct" = "$DOMAINS_COUNT" ] && {
|
||||
eval val=\"\$$hashvar\"
|
||||
echo "$val"
|
||||
}
|
||||
n=$(($n + 1))
|
||||
done
|
||||
}
|
||||
report_strategy()
|
||||
{
|
||||
# $1 - test function
|
||||
@@ -1166,23 +1231,26 @@ report_strategy()
|
||||
strategy="$(echo "$strategy" | xargs)"
|
||||
echo "!!!!! $1: working strategy found for ipv${IPV} $2 : $3 $strategy !!!!!"
|
||||
echo
|
||||
# report_append "ipv${IPV} $2 $1 : $3 ${WF:+$WF }$strategy"
|
||||
return 0
|
||||
else
|
||||
echo "$1: $3 strategy for ipv${IPV} $2 not found"
|
||||
echo
|
||||
report_append "ipv${IPV} $2 $1 : $3 not working"
|
||||
report_append "$2" "$1 ipv${IPV}" "$3 not working"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
test_has_split()
|
||||
{
|
||||
contains "$1" split || contains "$1" disorder
|
||||
}
|
||||
test_has_fakedsplit()
|
||||
{
|
||||
contains "$1" fakedsplit || contains "$1" fakeddisorder
|
||||
}
|
||||
test_has_split()
|
||||
{
|
||||
contains "$1" multisplit || contains "$1" multidisorder || test_has_fakedsplit "$1"
|
||||
}
|
||||
test_has_hostfakesplit()
|
||||
{
|
||||
contains "$1" hostfakesplit
|
||||
}
|
||||
test_has_fake()
|
||||
{
|
||||
[ "$1" = fake ] || starts_with "$1" fake,
|
||||
@@ -1195,6 +1263,7 @@ warn_fool()
|
||||
echo "WARNING ! fakedsplit/fakeddisorder with md5sig fooling and low split position causes MTU overflow with multi-segment TLS (kyber)"
|
||||
;;
|
||||
datanoack) echo 'WARNING ! although datanoack fooling worked it may break NAT and may only work with external IP. Additionally it may require nftables to work correctly.' ;;
|
||||
ts) echo 'WARNING ! although ts fooling worked it will not work without timestamps being enabled in the client OS. In windows timestamps are DISABLED by default.'
|
||||
esac
|
||||
}
|
||||
pktws_curl_test_update_vary()
|
||||
@@ -1206,7 +1275,7 @@ pktws_curl_test_update_vary()
|
||||
# $5,$6,... - strategy
|
||||
|
||||
local testf=$1 sec=$2 domain=$3 desync=$4 proto splits= pos fake ret=1
|
||||
local fake1=- fake2=- fake3=-
|
||||
local fake1=- fake2=- fake3=- fake4=-
|
||||
|
||||
shift; shift; shift; shift
|
||||
|
||||
@@ -1215,18 +1284,27 @@ pktws_curl_test_update_vary()
|
||||
test_has_fake $desync && {
|
||||
fake1="--dpi-desync-fake-$proto=0x00000000"
|
||||
[ "$sec" = 0 ] || {
|
||||
fake2="--dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=! --dpi-desync-fake-tls-mod=rnd,rndsni,dupsid"
|
||||
fake3="--dpi-desync-fake-tls-mod=rnd,dupsid,rndsni,padencap"
|
||||
fake2='--dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=! --dpi-desync-fake-tls-mod=rnd,rndsni,dupsid'
|
||||
# this splits actual fake to '1603' and modified standard fake from offset 2
|
||||
fake3='--dpi-desync-fake-tls=0x1603 --dpi-desync-fake-tls=!+2 --dpi-desync-fake-tls-mod=rnd,dupsid,rndsni --dpi-desync-fake-tcp-mod=seq'
|
||||
fake4='--dpi-desync-fake-tls-mod=rnd,dupsid,rndsni,padencap'
|
||||
}
|
||||
}
|
||||
if test_has_fakedsplit $desync ; then
|
||||
splits="method+2 midsld"
|
||||
[ "$sec" = 0 ] || splits="1 midsld"
|
||||
# do not send fake first
|
||||
fake1='--dpi-desync-fakedsplit-mod=altorder=1'
|
||||
elif test_has_split $desync ; then
|
||||
splits="method+2 midsld"
|
||||
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
|
||||
fi
|
||||
for fake in '' "$fake1" "$fake2" "$fake3" ; do
|
||||
test_has_hostfakesplit $desync && {
|
||||
fake1="--dpi-desync-hostfakesplit-mod=altorder=1"
|
||||
fake2="--dpi-desync-hostfakesplit-midhost=midsld"
|
||||
fake3="--dpi-desync-hostfakesplit-mod=altorder=1 --dpi-desync-hostfakesplit-midhost=midsld"
|
||||
}
|
||||
for fake in '' "$fake1" "$fake2" "$fake3" "$fake4" ; do
|
||||
[ "$fake" = "-" ] && continue
|
||||
if [ -n "$splits" ]; then
|
||||
for pos in $splits ; do
|
||||
@@ -1253,7 +1331,7 @@ pktws_check_domain_http_bypass_()
|
||||
# $3 - domain
|
||||
|
||||
local ok ttls s f f2 e desync pos fooling frag sec="$2" delta orig splits
|
||||
local need_split need_disorder need_fakedsplit need_fakeddisorder need_fake need_wssize
|
||||
local need_split need_disorder need_fakedsplit need_hostfakesplit need_fakeddisorder need_fake need_wssize
|
||||
local splits_http='method+2 midsld method+2,midsld'
|
||||
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1'
|
||||
|
||||
@@ -1298,39 +1376,56 @@ pktws_check_domain_http_bypass_()
|
||||
done
|
||||
|
||||
need_fakedsplit=1
|
||||
need_hostfakesplit=1
|
||||
need_fakeddisorder=1
|
||||
need_fake=1
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit hostfakesplit fake,hostfakesplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
|
||||
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
|
||||
[ "$need_hostfakesplit" = 0 ] && contains "$desync" hostfakesplit && continue
|
||||
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
|
||||
ok=0
|
||||
for ttl in $ttls; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=$ttl $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
need_wssize=0
|
||||
break
|
||||
}
|
||||
# orig-ttl=1 with start/cutoff limiter drops empty ACK packet in response to SYN,ACK. it does not reach DPI or server.
|
||||
# missing ACK is transmitted in the first data packet of TLS/HTTP proto
|
||||
for f in '' '--orig-ttl=1 --orig-mod-start=s1 --orig-mod-cutoff=d1'; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=$ttl $f $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
need_wssize=0
|
||||
[ "$SCANLEVEL" = force ] || break
|
||||
}
|
||||
done
|
||||
[ "$ok" = 1 ] && break
|
||||
done
|
||||
# only skip tests if TTL succeeded. do not skip if TTL failed but fooling succeeded
|
||||
[ $ok = 1 -a "$SCANLEVEL" != force ] && {
|
||||
[ "$desync" = fake ] && need_fake=0
|
||||
[ "$desync" = fakedsplit ] && need_fakedsplit=0
|
||||
[ "$desync" = hostfakesplit ] && need_hostfakesplit=0
|
||||
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
|
||||
}
|
||||
f=
|
||||
[ "$UNAME" = "OpenBSD" ] || f="badsum"
|
||||
f="$f badseq datanoack md5sig"
|
||||
f="$f badseq datanoack ts md5sig"
|
||||
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
|
||||
for fooling in $f; do
|
||||
ok=0
|
||||
f2=
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && {
|
||||
warn_fool $fooling $desync
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
ok=1
|
||||
}
|
||||
[ "$fooling" = badseq ] && {
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && continue
|
||||
# --dpi-desync-badseq-increment=0 leaves modified by default ack increment
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling --dpi-desync-badseq-increment=0 $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
}
|
||||
[ "$fooling" = md5sig ] && {
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && continue
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling --dup=1 --dup-cutoff=n2 --dup-fooling=md5sig $e && {
|
||||
@@ -1395,18 +1490,30 @@ pktws_check_domain_http_bypass_()
|
||||
|
||||
need_fakedsplit=1
|
||||
need_fakeddisorder=1
|
||||
need_hostfakesplit=1
|
||||
need_fake=1
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit hostfakesplit fake,hostfakesplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
|
||||
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
|
||||
[ "$need_hostfakesplit" = 0 ] && contains "$desync" hostfakesplit && continue
|
||||
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
|
||||
ok=0
|
||||
for orig in '' 1 2 3; do
|
||||
for delta in 1 2 3 4 5; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync ${orig:+--orig-autottl=+$orig} --dpi-desync-ttl=1 --dpi-desync-autottl=-$delta $e && ok=1
|
||||
# orig-ttl=1 with start/cutoff limiter drops empty ACK packet in response to SYN,ACK. it does not reach DPI or server.
|
||||
# missing ACK is transmitted in the first data packet of TLS/HTTP proto
|
||||
for delta in 1 2 3 4 5; do
|
||||
for f in '' '--orig-ttl=1 --orig-mod-start=s1 --orig-mod-cutoff=d1'; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=1 --dpi-desync-autottl=-$delta $f $e && ok=1
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && break
|
||||
done
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && break
|
||||
done
|
||||
[ "$SCANLEVEL" = force ] && {
|
||||
for orig in 1 2 3; do
|
||||
for delta in 1 2 3 4 5; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync ${orig:+--orig-autottl=+$orig} --dpi-desync-ttl=1 --dpi-desync-autottl=-$delta $e && ok=1
|
||||
done
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && break
|
||||
done
|
||||
}
|
||||
[ "$ok" = 1 ] &&
|
||||
{
|
||||
echo "WARNING ! although autottl worked it requires testing on multiple domains to find out reliable delta"
|
||||
@@ -1416,6 +1523,7 @@ pktws_check_domain_http_bypass_()
|
||||
[ "$SCANLEVEL" = force ] || {
|
||||
[ "$desync" = fake ] && need_fake=0
|
||||
[ "$desync" = fakedsplit ] && need_fakedsplit=0
|
||||
[ "$desync" = hostfakesplit ] && need_hostfakesplit=0
|
||||
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
|
||||
}
|
||||
}
|
||||
@@ -1624,17 +1732,19 @@ check_domain_prolog()
|
||||
|
||||
local code
|
||||
|
||||
[ "$SIMULATE" = 1 ] && return 0
|
||||
|
||||
echo
|
||||
echo \* $1 ipv$IPV $3
|
||||
|
||||
echo "- checking without DPI bypass"
|
||||
curl_test $1 $3 && {
|
||||
report_append "ipv${IPV} $3 $1 : working without bypass"
|
||||
report_append "$3" "$1 ipv${IPV}" "working without bypass"
|
||||
[ "$SCANLEVEL" = force ] || return 1
|
||||
}
|
||||
code=$?
|
||||
curl_has_reason_to_continue $code || {
|
||||
report_append "ipv${IPV} $3 $1 : test aborted, no reason to continue. curl code $(curl_translate_code $code)"
|
||||
report_append "$3" "$1 ipv${IPV}" "test aborted, no reason to continue. curl code $(curl_translate_code $code)"
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
@@ -1818,6 +1928,7 @@ ask_params()
|
||||
[ -n "$dom" ] && DOMAINS="$dom"
|
||||
}
|
||||
}
|
||||
DOMAINS_COUNT="$(echo "$DOMAINS" | wc -w | trim)"
|
||||
|
||||
local IPVS_def=4
|
||||
[ -n "$IPVS" ] || {
|
||||
@@ -2197,6 +2308,18 @@ cleanup
|
||||
echo
|
||||
echo \* SUMMARY
|
||||
report_print
|
||||
[ "$DOMAINS_COUNT" -gt 1 ] && {
|
||||
echo
|
||||
echo \* COMMON
|
||||
result_intersection_print
|
||||
echo
|
||||
[ "$SCANLEVEL" = force ] || {
|
||||
echo "blockcheck optimizes test sequence. To save time some strategies can be skipped if their test is considered useless."
|
||||
echo "That's why COMMON intersection can miss strategies that would work for all domains."
|
||||
echo "Use \"force\" scan level to test all strategies and generate trustable intersection."
|
||||
echo "Current scan level was \"$SCANLEVEL\"".
|
||||
}
|
||||
}
|
||||
echo
|
||||
echo "Please note this SUMMARY does not guarantee a magic pill for you to copy/paste and be happy."
|
||||
echo "Understanding how strategies work is very desirable."
|
||||
|
||||
@@ -297,10 +297,10 @@ minsleep()
|
||||
|
||||
replace_char()
|
||||
{
|
||||
local a=$1
|
||||
local b=$2
|
||||
local a="$1"
|
||||
local b="$2"
|
||||
shift; shift
|
||||
echo "$@" | tr $a $b
|
||||
echo "$@" | tr "$a" "$b"
|
||||
}
|
||||
|
||||
replace_str()
|
||||
@@ -318,6 +318,12 @@ setup_md5()
|
||||
exists $MD5 || MD5=md5
|
||||
}
|
||||
|
||||
md5f()
|
||||
{
|
||||
setup_md5
|
||||
$MD5 | cut -d ' ' -f1
|
||||
}
|
||||
|
||||
setup_random()
|
||||
{
|
||||
[ -n "$RCUT" ] && return
|
||||
@@ -330,7 +336,6 @@ random()
|
||||
{
|
||||
# $1 - min, $2 - max
|
||||
local r rs
|
||||
setup_md5
|
||||
setup_random
|
||||
if [ -c /dev/urandom ]; then
|
||||
read rs </dev/urandom
|
||||
@@ -338,7 +343,7 @@ random()
|
||||
rs="$RANDOM$RANDOM$(date)"
|
||||
fi
|
||||
# shells use signed int64
|
||||
r=1$(echo $rs | $MD5 | sed 's/[^0-9]//g' | $RCUT)
|
||||
r=1$(echo $rs | md5f | sed 's/[^0-9]//g' | $RCUT)
|
||||
echo $(( ($r % ($2-$1+1)) + $1 ))
|
||||
}
|
||||
|
||||
|
||||
@@ -703,7 +703,7 @@ removable_pkgs_openwrt()
|
||||
for pkg in $PKGS2; do
|
||||
check_package_exists_openwrt $pkg && PKGS="${PKGS:+$PKGS }$pkg"
|
||||
done
|
||||
PKGS="ipset iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra ip6tables-mod-nat ip6tables-extra kmod-nft-queue gzip coreutils-sort coreutils-sleep curl $PKGS"
|
||||
PKGS="ipset iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra iptables-mod-u32 ip6tables-mod-nat ip6tables-extra kmod-nft-queue gzip coreutils-sort coreutils-sleep curl $PKGS"
|
||||
}
|
||||
|
||||
openwrt_fix_broken_apk_uninstall_scripts()
|
||||
@@ -744,7 +744,7 @@ check_prerequisites_openwrt()
|
||||
iptables)
|
||||
pkg_iptables=iptables
|
||||
check_package_exists_openwrt iptables-zz-legacy && pkg_iptables=iptables-zz-legacy
|
||||
PKGS="$PKGS ipset $pkg_iptables iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra"
|
||||
PKGS="$PKGS ipset $pkg_iptables iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra iptables-mod-u32"
|
||||
check_package_exists_openwrt ip6tables-zz-legacy && pkg_iptables=ip6tables-zz-legacy
|
||||
[ "$DISABLE_IPV6" = 1 ] || PKGS="$PKGS $pkg_iptables ip6tables-mod-nat ip6tables-extra"
|
||||
;;
|
||||
|
||||
@@ -112,6 +112,10 @@ unprepare_tpws_fw()
|
||||
unprepare_tpws_fw4
|
||||
}
|
||||
|
||||
ipt_mark_filter()
|
||||
{
|
||||
[ -n "$FILTER_MARK" ] && echo "-m mark --mark $FILTER_MARK/$FILTER_MARK"
|
||||
}
|
||||
|
||||
ipt_print_op()
|
||||
{
|
||||
@@ -136,7 +140,7 @@ _fw_tpws4()
|
||||
|
||||
ipt_print_op $1 "$2" "tpws (port $3)"
|
||||
|
||||
rule="$2 $IPSET_EXCLUDE dst $IPBAN_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3"
|
||||
rule="$(ipt_mark_filter) $2 $IPSET_EXCLUDE dst $IPBAN_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3"
|
||||
for i in $4 ; do
|
||||
ipt_add_del $1 PREROUTING -t nat -i $i $rule
|
||||
done
|
||||
@@ -164,7 +168,7 @@ _fw_tpws6()
|
||||
|
||||
ipt_print_op $1 "$2" "tpws (port $3)" 6
|
||||
|
||||
rule="$2 $IPSET_EXCLUDE6 dst $IPBAN_EXCLUDE6 dst"
|
||||
rule="$(ipt_mark_filter) $2 $IPSET_EXCLUDE6 dst $IPBAN_EXCLUDE6 dst"
|
||||
for i in $4 ; do
|
||||
_dnat6_target $i DNAT6
|
||||
[ -n "$DNAT6" -a "$DNAT6" != "-" ] && ipt6_add_del $1 PREROUTING -t nat -i $i $rule -j DNAT --to [$DNAT6]:$3
|
||||
@@ -202,7 +206,7 @@ _fw_nfqws_post4()
|
||||
|
||||
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)"
|
||||
|
||||
rule="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
rule="$(ipt_mark_filter) -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
|
||||
@@ -223,7 +227,7 @@ _fw_nfqws_post6()
|
||||
|
||||
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" 6
|
||||
|
||||
rule="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
rule="$(ipt_mark_filter) -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
|
||||
|
||||
@@ -312,6 +312,10 @@ nft_filter_apply_ipset_target()
|
||||
nft_filter_apply_ipset_target6 $2
|
||||
}
|
||||
|
||||
nft_mark_filter()
|
||||
{
|
||||
[ -n "$FILTER_MARK" ] && echo "mark and $FILTER_MARK != 0"
|
||||
}
|
||||
|
||||
nft_script_add_ifset_element()
|
||||
{
|
||||
@@ -403,9 +407,10 @@ _nft_fw_tpws4()
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2"
|
||||
local mark_filter=$(nft_mark_filter)
|
||||
nft_print_op "$filter" "tpws (port $2)" 4
|
||||
nft_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||
nft_insert_rule dnat_pre iifname @lanif $filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||
nft_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif} $mark_filter $filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||
nft_insert_rule dnat_pre iifname @lanif $mark_filter $filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
|
||||
prepare_route_localnet
|
||||
}
|
||||
}
|
||||
@@ -418,10 +423,11 @@ _nft_fw_tpws6()
|
||||
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" DNAT6 i
|
||||
local mark_filter=$(nft_mark_filter)
|
||||
nft_print_op "$filter" "tpws (port $port)" 6
|
||||
nft_insert_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $FW_EXTRA_POST dnat ip6 to [::1]:$port
|
||||
nft_insert_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6} $mark_filter $filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $FW_EXTRA_POST dnat ip6 to [::1]:$port
|
||||
[ -n "$3" ] && {
|
||||
nft_insert_rule dnat_pre $filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $FW_EXTRA_POST dnat ip6 to iifname map @link_local:$port
|
||||
nft_insert_rule dnat_pre $mark_filter $filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $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
|
||||
@@ -468,7 +474,7 @@ _nft_fw_nfqws_post4()
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
|
||||
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4
|
||||
rule="${3:+oifname @wanif }$filter ip daddr != @nozapret"
|
||||
rule="${3:+oifname @wanif} $(nft_mark_filter) $filter ip daddr != @nozapret"
|
||||
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
||||
nft_insert_rule $chain $rule $setmark $CONNMARKER $FW_EXTRA_POST queue num $port bypass
|
||||
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||
@@ -483,7 +489,7 @@ _nft_fw_nfqws_post6()
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
|
||||
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
|
||||
rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6"
|
||||
rule="${3:+oifname @wanif6} $(nft_mark_filter) $filter ip6 daddr != @nozapret6"
|
||||
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
|
||||
nft_insert_rule $chain $rule $setmark $CONNMARKER $FW_EXTRA_POST queue num $port bypass
|
||||
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||
@@ -508,7 +514,7 @@ _nft_fw_nfqws_pre4()
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule
|
||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
|
||||
rule="${3:+iifname @wanif }$filter ip saddr != @nozapret"
|
||||
rule="${3:+iifname @wanif} $filter ip saddr != @nozapret"
|
||||
nft_insert_rule $(get_prechain) $rule $CONNMARKER $FW_EXTRA_POST queue num $port bypass
|
||||
}
|
||||
}
|
||||
@@ -521,7 +527,7 @@ _nft_fw_nfqws_pre6()
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule
|
||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
|
||||
rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6"
|
||||
rule="${3:+iifname @wanif6} $filter ip6 saddr != @nozapret6"
|
||||
nft_insert_rule $(get_prechain) $rule $CONNMARKER $FW_EXTRA_POST queue num $port bypass
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@ GZIP_LISTS=1
|
||||
DESYNC_MARK=0x40000000
|
||||
DESYNC_MARK_POSTNAT=0x20000000
|
||||
|
||||
# do not pass outgoing traffic to tpws/nfqws not marked with this bit
|
||||
# this setting allows to write your own rules to limit traffic that should be fooled
|
||||
# for example based on source IP or incoming interface name
|
||||
# no filter if not defined
|
||||
#FILTER_MARK=0x10000000
|
||||
|
||||
TPWS_SOCKS_ENABLE=0
|
||||
# tpws socks listens on this port on localhost and LAN interfaces
|
||||
TPPORT_SOCKS=987
|
||||
|
||||
@@ -526,3 +526,32 @@ install_bin: stop if no binaries found. display help text.
|
||||
winws: increase buffers for port filter
|
||||
tpws: tpws no more opens /dev/pf in OpenBSD by default. requires --enable-pf like in FreeBSD. this is migration from rdr-to to divert-to redirection scheme.
|
||||
install_easy: warn if --ipset parameter is specified
|
||||
|
||||
v71.3
|
||||
|
||||
init.d: FILTER_MARK
|
||||
nfqws: ts fooling
|
||||
blockcheck: test ts fooling
|
||||
blockcheck: auto enable tcp timestamps in windows
|
||||
tpws,nfqws: special handling of IP-like hostnames. strip :port from hostname:port
|
||||
|
||||
v71.4
|
||||
|
||||
nfqws,tpws: fix possible crashes or high memory usage if hostlist has duplicate hostnames
|
||||
init.d: custom scripts 50-discord-media, 50-stun4all
|
||||
init.d: windivert filters for discord media, stun, wireguard
|
||||
readme: hardware problems description
|
||||
|
||||
v72
|
||||
|
||||
winws: --wf-raw-part
|
||||
nfqws: --dpi-desync=hostfakesplit
|
||||
nfqws: --dpi-desync-fake-tcp-mod=seq
|
||||
nfqws: --dpi-desync-fake-tls=!+offset , --dpi-desync-fake-xxx=[+offset]@filename
|
||||
nfqws: --dpi-desync-fakedsplit-mod=altorder for fakedsplit/fakeddisorder
|
||||
nfqws: --dpi-desync-hostfakesplit-mod=altorder
|
||||
nfqws: fakedsplit/fakeddisorder normalize fake split pattern offset to reasm offset
|
||||
nfqws: optimize ipv4 ip_id. apply ip_id on all OS the same way.
|
||||
blockcheck: print PRETTY_NAME and some OPENWRT_xxx from /etc/os-release
|
||||
blockcheck: new strategies
|
||||
blockcheck: curl test simulation : SIMULATE=1
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
в простыню [readme.md](readme.md).
|
||||
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод,
|
||||
которому сопротивляется окружающая среда, которому автоматически не
|
||||
которому оказывается активное противодействие и поэтому автоматически не
|
||||
гарантирована работоспособность в любых условиях и на любых ресурсах, требуется
|
||||
настройка под специфические условия у вашего провайдера. Условия могут меняться
|
||||
со временем, и методика может начинать или переставать работать, может
|
||||
@@ -52,6 +52,18 @@
|
||||
1. Скачайте последний [tar.gz релиз](https://github.com/bol-van/zapret/releases) в /tmp, распакуйте его, затем удалите архив.
|
||||
Для openwrt и прошивок используйте вариант `openwrt-embedded`.
|
||||
Для экономия места в /tmp можно качать через curl в stdout и сразу распаковывать.
|
||||
Пример под openwrt для версии zapret 71.4 (для других URL отличается) :
|
||||
```
|
||||
$ curl -Lo - https://github.com/bol-van/zapret/releases/download/v71.4/zapret-v71.4-openwrt-embedded.tar.gz | tar -zx
|
||||
$ wget -O - https://github.com/bol-van/zapret/releases/download/v71.4/zapret-v71.4-openwrt-embedded.tar.gz | tar -zx
|
||||
```
|
||||
Пример под традиционный linux для версии zapret 71.4 (для других URL отличается) :
|
||||
```
|
||||
$ curl -Lo - https://github.com/bol-van/zapret/releases/download/v71.4/zapret-v71.4.tar.gz | tar -zx
|
||||
$ wget -O - https://github.com/bol-van/zapret/releases/download/v71.4/zapret-v71.4.tar.gz | tar -zx
|
||||
```
|
||||
curl должен быть предварительно установлен. Но он в любом случае понадобится далее.
|
||||
Вариант с wget будет работать только если установленный wget поддерживает https.
|
||||
|
||||
2. Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и
|
||||
сам zapret. Гарантированно уберет zapret скрипт `uninstall_easy.sh`.
|
||||
@@ -129,10 +141,14 @@
|
||||
или `tpws` и запомнить найденные стратегии для дальнейшего применения.
|
||||
|
||||
Следует понимать, что скрипт проверяет доступность только конкретного
|
||||
домена, который вы вводите в начале. Вероятно, все остальные домены
|
||||
блокированы подобным образом, **но не факт**. В большинстве случаев можно
|
||||
объединить несколько стратегий в одну универсальную, и это **крайне
|
||||
желательно**. Необходимо понимать как работают стратегии. zapret **не может
|
||||
домена, который вы вводите в начале, конкретной программой curl.
|
||||
У разных клиентов есть свой фингерпринт. У броузеров один, у curl другой.
|
||||
Может применяться или не применяться многопакетный TLS с постквантовой криптографией (kyber).
|
||||
От этого может зависеть работоспособность стратегий.
|
||||
Обычно остальные домены блокированы подобным образом, **но не факт**.
|
||||
Бывают специальные блокировки. Некоторые параметры требуют тюнинга под "общий знаменатель".
|
||||
В большинстве случаев можно объединить несколько стратегий в одну универсальную, и это **крайне
|
||||
желательно**, но это требует понимания как работают стратегии. zapret **не может
|
||||
пробить блокировку по IP адресу**. Для проверки нескольких доменов вводите
|
||||
их через пробел.
|
||||
|
||||
@@ -143,19 +159,7 @@
|
||||
> направления (IP сервера). скрипт не всегда может выдать вам в итогах
|
||||
> оптимальную стратегию, которую надо просто переписать в настройки. В
|
||||
> некоторых случаях надо реально думать что происходит, анализируя результат
|
||||
> на разных стратегиях. Если вы применяете большой TTL, чтобы достать до
|
||||
> магистрала, то не лишним будет добавить дополнительный ограничитель
|
||||
> `--dpi-desync-fooling`, чтобы не сломать сайты на более коротких
|
||||
> дистанциях. `md5sig` наиболее совместим, но работает **только** на linux
|
||||
> серверах. `badseq` может работать только на https и не работать на http.
|
||||
> Чтобы выяснить какие дополнительные ограничители работают, смотрите
|
||||
> результат теста аналогичных стратегий без TTL с каждым из этих
|
||||
> ограничителей.
|
||||
>
|
||||
> При использовании `autottl` следует протестировать как можно больше разных
|
||||
> доменов. Эта техника может на одних провайдерах работать стабильно, на
|
||||
> других потребуется выяснить при каких параметрах она стабильна, на третьих
|
||||
> полный хаос, и проще отказаться.
|
||||
> на разных стратегиях.
|
||||
>
|
||||
> Далее, имея понимание что работает на http, https, quic нужно
|
||||
> сконструировать параметры запуска `tpws` и/или `nfqws` с использованием
|
||||
@@ -202,8 +206,8 @@
|
||||
> Но здесь совсем "копи-пастный" вариант. Чем больше вы объедините стратегий и
|
||||
> сократите их общее количество, тем будет лучше.
|
||||
>
|
||||
> Если вам не нужно дурение отдельных протоколов, лучше всего будет их
|
||||
> убрать из системы перехвата трафика через параметры `TPWS_PORTS`,
|
||||
> Если вам не нужно дурение отдельных протоколов, лучше всего будет убрать
|
||||
> лишние порты из системы перехвата трафика через параметры `TPWS_PORTS`,
|
||||
> `NFQWS_PORTS_TCP`, `NFQWS_PORTS_UDP` и убрать соответствующие им профили
|
||||
> мультистратегии.
|
||||
>
|
||||
@@ -230,6 +234,15 @@
|
||||
> В этом примере `wssize` будет применяться всегда к порту tcp `443` вне
|
||||
> зависимости от параметра `MODE_FILTER`. Хостлист будет игнорироваться,
|
||||
> если таковой имеется. К http применять `wssize` вредно и бессмысленно.
|
||||
>
|
||||
> Иногда требуется дописать к стратегиям свои собственные параметры.
|
||||
> Например, нужно изменить количество повторов фейков или задать свой фейк.
|
||||
> Это делается через шелл-переменные `PKTWS_EXTRA`, `TPWS_EXTRA`.
|
||||
>
|
||||
> ```PKTWS_EXTRA="--dpi-desync-repeats=10 --dpi-desync-fake-tls=/tmp/tls.bin" ./blockcheck.sh```
|
||||
>
|
||||
> Перебор всех комбинаций может привести к ожиданию неделями, поэтому выбран разумный
|
||||
> костяк проверки, на который вы можете навешивать свои кустомизации.
|
||||
|
||||
7. Запустите скрипт облегченной установки - `install_easy.sh` Выберите `nfqws`
|
||||
и/или `tpws`, затем согласитесь на редактирование параметров. Откроется
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
## Немного разъяснений
|
||||
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод, которому сопротивляется окружающая среда,
|
||||
которому автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах,
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод, которому оказывается активное противодействие и поэтому
|
||||
автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах,
|
||||
требуется настройка под специфические условия у вашего провайдера. Условия могут меняться со временем,
|
||||
и методика может начинать или переставать работать, может потребоваться повторный анализ ситуации.
|
||||
Могут обнаруживаться отдельные ресурсы, которые заблокированы иначе, и которые не работают или перестали работать.
|
||||
@@ -30,24 +30,7 @@
|
||||
|
||||
Будем считать, что у вас есть windows 7 или выше. Задача - обойти блокировки с самой системы.
|
||||
|
||||
> [!NOTE]
|
||||
> Есть решение самое простое, а есть "как положено".
|
||||
|
||||
## САМОЕ ПРОСТОЕ РЕШЕНИЕ
|
||||
|
||||
_"Совсем ничего не могу, все очень сложно, дайте мне таблетку."_ ©Простой пользователь
|
||||
|
||||
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
|
||||
2) Запустите `zapret-winws/preset_russia.cmd` от имени администратора. Возможно, заведется сразу.
|
||||
|
||||
> То же самое с ограничителем по автоматически создаваемому хост-листу `preset_russia_autohostlist.cmd`.
|
||||
> Что такое `autohostlist` - читайте [readme.md](./readme.md). Проще говоря, мы обходим только то, что долго и упорно не хочет открываться.
|
||||
> Сначала не будет, но надо пытаться много раз, и тогда сработает, а дальше будет всегда срабатывать.
|
||||
> Остальное не будет ломаться. Использовать только, если первый вариант тоже работает.
|
||||
|
||||
Не помогла _"таблетка"_ ? Это вовсе не значит, что ничего не получится. Но придется делать по нормальному.
|
||||
|
||||
## НЕ ПОМОГЛО, КАК ТЕПЕРЬ ЭТО УДАЛИТЬ
|
||||
## Я ЧТО-ТО ДЕЛАЛ, НЕ ПОМОГЛО, КАК ТЕПЕРЬ ЭТО УДАЛИТЬ
|
||||
|
||||
Если вы не устанавливали zapret как службу или запланированную задачу (а это требует редактирования cmd файлов),
|
||||
достаточно закрыть окно с winws и запустить windivert_delete.cmd.
|
||||
@@ -55,14 +38,17 @@ _"Совсем ничего не могу, все очень сложно, да
|
||||
После чего можно удалить папку с zapret. На этом деинсталляция закончена.
|
||||
Если же вы устанавливали zapret как службу, то вы наверняка знаете как ее удалить.
|
||||
|
||||
## РЕШЕНИЕ "КАК ПОЛОЖЕНО"
|
||||
Если вдруг среди того, на что вы нажимали, есть слова "general", "alt", ".bat", "автозапуск", или же есть файлы, которые отсутствуют
|
||||
в оригинальных репозиториях, то это сборка. Вы не получите ответа как ее удалить от разработчика zapret.
|
||||
Спрашивайте самих сборщиков. Разработчик не предоставляет простого решения, этим занимаются сборщики, но они и сами отвечают за свои продукты.
|
||||
|
||||
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
|
||||
## Настройка
|
||||
|
||||
2) Если у вас Windows 7 x64, однократно запустите `win7/install_win7.cmd`. Батник заменит файлы windivert на совместимую с Windows 7 версию.
|
||||
1. Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
|
||||
|
||||
> [!WARNING]
|
||||
> Для 32-битных систем Windows нет готового полного варианта.
|
||||
2. Если у вас Windows 7 x64, однократно запустите `win7/install_win7.cmd`. Батник заменит файлы windivert на совместимую с Windows 7 версию.
|
||||
|
||||
> Для 32-битных систем Windows нет готового полного варианта.
|
||||
|
||||
> На windows 11 arm64 выполните `arm64/install_arm64.cmd` от имени администратора и перезагрузите компьютер.
|
||||
> Читайте [docs/windows.md](./windows.md)
|
||||
@@ -72,15 +58,15 @@ _"Совсем ничего не могу, все очень сложно, да
|
||||
> более-менее научились с ним дружить.
|
||||
> Если проблема имеет место , используйте исключения. Если не помогает - отключайте антивирус совсем.
|
||||
|
||||
3) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
|
||||
3. Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
|
||||
|
||||
4) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
4. Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
|
||||
5) Запустите `blockcheck\blockcheck.cmd`. blockcheck в начале проверяет **DNS**.
|
||||
Если выводятся сообщения о подмене адресов, то нужно будет решить проблему с **DNS**.
|
||||
blockcheck перейдет в этом случае на **DoH** _(DNS over HTTPS)_ и будет пытаться получить и использовать реальные IP адреса.
|
||||
Но если вы не настроите решение этой проблемы, обход будет работать только для тех программ,
|
||||
которые сами реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
5. Запустите `blockcheck\blockcheck.cmd`. blockcheck в начале проверяет **DNS**.
|
||||
Если выводятся сообщения о подмене адресов, то нужно будет решить проблему с **DNS**.
|
||||
blockcheck перейдет в этом случае на **DoH** _(DNS over HTTPS)_ и будет пытаться получить и использовать реальные IP адреса.
|
||||
Но если вы не настроите решение этой проблемы, обход будет работать только для тех программ,
|
||||
которые сами реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
|
||||
> Решение проблемы DNS выходит за рамки проекта. Обычно она решается либо заменой DNS серверов
|
||||
> от провайдера на публичные (`1.1.1.1`, `8.8.8.8`), либо в случае перехвата провайдером обращений
|
||||
@@ -92,35 +78,29 @@ blockcheck перейдет в этом случае на **DoH** _(DNS over HTT
|
||||
>
|
||||
> Тут все разжевано как и где это включается : https://hackware.ru/?p=13707
|
||||
|
||||
6) blockcheck позволяет выявить рабочую стратегию обхода блокировок.
|
||||
Лог скрипта будет сохранен в `blockcheck\blockcheck.log`.
|
||||
Запомните/перепишите найденные стратегии.
|
||||
6. blockcheck позволяет выявить рабочую стратегию обхода блокировок.
|
||||
Лог скрипта будет сохранен в `blockcheck\blockcheck.log`.
|
||||
Запомните/перепишите найденные стратегии.
|
||||
|
||||
> [!WARNING]
|
||||
> Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
|
||||
> Вероятно, все остальные домены блокированы подобным образом, но не факт.
|
||||
Следует понимать, что скрипт проверяет доступность только конкретного
|
||||
домена, который вы вводите в начале, конкретной программой curl.
|
||||
У разных клиентов есть свой фингерпринт. У броузеров один, у curl другой.
|
||||
Может применяться или не применяться многопакетный TLS с постквантовой криптографией (kyber).
|
||||
От этого может зависеть работоспособность стратегий.
|
||||
Обычно остальные домены блокированы подобным образом, **но не факт**.
|
||||
Бывают специальные блокировки. Некоторые параметры требуют тюнинга под "общий знаменатель".
|
||||
В большинстве случаев можно объединить несколько стратегий в одну универсальную, и это **крайне
|
||||
желательно**, но это требует понимания как работают стратегии. zapret **не может
|
||||
пробить блокировку по IP адресу**. Для проверки нескольких доменов вводите их через пробел.
|
||||
|
||||
> [!TIP]
|
||||
> В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
|
||||
|
||||
> Необходимо понимать [как работают стратегии](./readme.md/#nfqws).
|
||||
> zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
|
||||
>
|
||||
> Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
|
||||
> с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
|
||||
> которые еще и включаются в работу хаотичным образом или образом, зависящим от направления (IP сервера).
|
||||
> blockcheck не всегда может выдать вам в итогах оптимальную стратегию, которую надо просто переписать в настройки.
|
||||
> В некоторых случаях надо реально думать что происходит, анализируя результат на разных стратегиях.
|
||||
> Если вы применяете большой TTL, чтобы достать до магистрала, то не лишним будет добавить дополнительный ограничитель
|
||||
> `--dpi-desync-fooling`, чтобы не сломать сайты на более коротких дистанциях.
|
||||
> _md5sig_ наиболее совместим, но работатет только на linux серверах.
|
||||
> badseq может работать только на https и не работать на http.
|
||||
> Чтобы выяснить какие дополнительные ограничители работают, смотрите результат теста аналогичных стратегий без TTL
|
||||
> с каждым из этих ограничителей.
|
||||
>
|
||||
> При использовании autottl следует протестировать как можно больше разных доменов. Эта техника
|
||||
> может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
|
||||
> она стабильна, на третьих полный хаос, и проще отказаться.
|
||||
> Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у
|
||||
> вас может быть несколько маршрутов с различной длиной по ХОПам, с DPI на
|
||||
> разных хопах. Приходится преодолевать целый зоопарк DPI, которые еще и
|
||||
> включаются в работу хаотичным образом или образом, зависящим от
|
||||
> направления (IP сервера). скрипт не всегда может выдать вам в итогах
|
||||
> оптимальную стратегию, которую надо просто переписать в настройки. В
|
||||
> некоторых случаях надо реально думать что происходит, анализируя результат
|
||||
> на разных стратегиях.
|
||||
>
|
||||
> Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
|
||||
> с использованием мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md#множественные-стратегии).
|
||||
@@ -183,12 +163,21 @@ blockcheck перейдет в этом случае на **DoH** _(DNS over HTT
|
||||
>
|
||||
> В этих примерах wssize будет применяться всегда к порту tcp 443, а хостлист будет игнорироваться.
|
||||
> К http применять wssize вредно и бессмысленно.
|
||||
>
|
||||
> Иногда требуется дописать к стратегиям свои собственные параметры.
|
||||
> Например, нужно изменить количество повторов фейков или задать свой фейк.
|
||||
> Это делается через шелл-переменные `PKTWS_EXTRA`, `TPWS_EXTRA`. Пользуйтесь шеллом `cygwin/cygwin-admin.cmd`.
|
||||
>
|
||||
> ```PKTWS_EXTRA="--dpi-desync-repeats=10 --dpi-desync-fake-tls=/tmp/tls.bin" blockcheck```
|
||||
>
|
||||
> Перебор всех комбинаций может привести к ожиданию неделями, поэтому выбран разумный
|
||||
> костяк проверки, на который вы можете навешивать свои кустомизации.
|
||||
|
||||
7) Протестируйте найденные стратегии на winws. Winws следует брать из zapret-winws.
|
||||
Для этого откройте командную строку windows от имени администратора в директории zapret-winws.
|
||||
Проще всего это сделать через `_CMD_ADMIN.cmd`. Он сам поднимет права и зайдет в нужную директорию.
|
||||
7. Протестируйте найденные стратегии на winws. Winws следует брать из zapret-winws.
|
||||
Для этого откройте командную строку windows от имени администратора в директории zapret-winws.
|
||||
Проще всего это сделать через `_CMD_ADMIN.cmd`. Он сам поднимет права и зайдет в нужную директорию.
|
||||
|
||||
8) Обеспечьте удобную загрузку обхода блокировок.
|
||||
8. Обеспечьте удобную загрузку обхода блокировок.
|
||||
|
||||
> Есть 2 варианта. Ручной запуск через ярлык или автоматический при старте системы, вне контекста текущего пользователя.
|
||||
> Последний вариант разделяется на запуск через планировщик задач и через службы windows.
|
||||
@@ -203,11 +192,11 @@ blockcheck перейдет в этом случае на **DoH** _(DNS over HTT
|
||||
>
|
||||
> Аналогично настраиваются и службы windows. Смотрите `service_*.cmd`
|
||||
|
||||
9) Если ломаются отдельные незаблокированные ресурсы, нужно пользоваться ограничивающим
|
||||
ipset или хост листом. Читайте основной талмуд [readme.md](./readme.md) ради подробностей.
|
||||
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
|
||||
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
|
||||
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
|
||||
9. Если ломаются отдельные незаблокированные ресурсы, нужно пользоваться ограничивающим
|
||||
ipset или хост листом. Читайте основной талмуд [readme.md](./readme.md) ради подробностей.
|
||||
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
|
||||
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
|
||||
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
|
||||
|
||||
> [!CAUTION]
|
||||
> Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# zapret v71.2
|
||||
# zapret v72
|
||||
|
||||
# SCAMMER WARNING
|
||||
|
||||
@@ -136,107 +136,117 @@ 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.
|
||||
@<config_file> ; read file for options. must be the only argument. other options are ignored.
|
||||
|
||||
--debug=0|1
|
||||
--dry-run ; verify parameters and exit with code 0 if successful
|
||||
--version ; print version and exit
|
||||
--comment ; any text (ignored)
|
||||
--dry-run ; verify parameters and exit with code 0 if successful
|
||||
--version ; print version and exit
|
||||
--comment ; any text (ignored)
|
||||
--qnum=<nfqueue_number>
|
||||
--daemon ; daemonize
|
||||
--pidfile=<filename> ; write pid to file
|
||||
--user=<username> ; drop root privs
|
||||
--uid=uid[:gid1,gid2,...] ; drop root privs
|
||||
--bind-fix4 ; apply outgoing interface selection fix for generated ipv4 packets
|
||||
--bind-fix6 ; apply outgoing interface selection fix for generated ipv6 packets
|
||||
--wsize=<window_size>[:<scale_factor>] ; set window size. 0 = do not modify. OBSOLETE !
|
||||
--wssize=<window_size>[:<scale_factor>] ; set window size for server. 0 = do not modify. default scale_factor = 0.
|
||||
--wssize-cutoff=[n|d|s]N ; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--ctrack-timeouts=S:E:F[:U] ; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default 60:300:60:60
|
||||
--ctrack-disable=[0|1] ; 1 or no argument disables conntrack
|
||||
--ipcache-lifetime=<int> ; time in seconds to keep cached hop count and domain name (default 7200). 0 = no expiration
|
||||
--ipcache-hostname=[0|1] ; 1 or no argument enables ip->hostname caching
|
||||
--hostcase ; change Host: => host:
|
||||
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
||||
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
||||
--domcase ; mix domain case : Host: TeSt.cOm
|
||||
--methodeol ; add '\n' before method and remove space after Host:
|
||||
--synack-split=[syn|synack|acksyn] ; perform TCP split handshake : send SYN only, SYN+ACK or ACK+SYN
|
||||
--orig-ttl=<int> ; set TTL for original packets
|
||||
--orig-ttl6=<int> ; set ipv6 hop limit for original packets. by default ttl value is used
|
||||
--orig-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: +5:3-64. "0:0-0" or "-" disables autottl.
|
||||
--orig-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --orig-autottl for ipv6 only
|
||||
--orig-mod-start=[n|d|s]N ; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--orig-mod-cutoff=[n|d|s]N ; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--dup=<int> ; duplicate original packets. send N dups before original.
|
||||
--dup-replace=[0|1] ; 1 or no argument means do not send original, only dups
|
||||
--dup-ttl=<int> ; set TTL for dups
|
||||
--dup-ttl6=<int> ; set ipv6 hop limit for dups. by default ttl value is used
|
||||
--dup-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: -1:3-64. "0:0-0" or "-" disables autottl.
|
||||
--dup-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --dup-autottl for ipv6 only
|
||||
--dup-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dup-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment for dup. default -10000
|
||||
--dup-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment for dup. default -66000
|
||||
--dup-start=[n|d|s]N ; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--dup-cutoff=[n|d|s]N ; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
|
||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
||||
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
||||
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used.
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: -1:3-20. "0:0-0" or "-" disables autottl.
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --dpi-desync-autottl for ipv6 only
|
||||
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
||||
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; comma separated list of split positions
|
||||
; markers: method,host,endhost,sld,endsld,midsld,sniext
|
||||
; full list is only used by multisplit and multidisorder
|
||||
; fakedsplit/fakeddisorder use first l7-protocol-compatible parameter if present, first abs value otherwise
|
||||
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; use sequence overlap before first sent original split segment
|
||||
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap
|
||||
--dpi-desync-fakedsplit-pattern=<filename>|0xHEX ; fake pattern for fakedsplit/fakeddisorder
|
||||
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
|
||||
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
||||
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
|
||||
--dpi-desync-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment. default -66000
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
||||
--dpi-desync-fake-http=<filename>|0xHEX ; file containing fake http request
|
||||
--dpi-desync-fake-tls=<filename>|0xHEX|! ; file containing fake TLS ClientHello (for https). '!' = standard fake
|
||||
--dpi-desync-fake-tls-mod=mod[,mod] ; comma separated list of TLS fake mods. available mods : none,rnd,rndsni,sni=<sni>,dupsid,padencap
|
||||
--dpi-desync-fake-unknown=<filename>|0xHEX ; file containing unknown protocol fake payload
|
||||
--dpi-desync-fake-syndata=<filename>|0xHEX ; file containing SYN data payload
|
||||
--dpi-desync-fake-quic=<filename>|0xHEX ; file containing fake QUIC Initial
|
||||
--dpi-desync-fake-wireguard=<filename>|0xHEX ; file containing fake wireguard handshake initiation
|
||||
--dpi-desync-fake-dht=<filename>|0xHEX ; file containing fake DHT (d1..e)
|
||||
--dpi-desync-fake-discord=<filename>|0xHEX ; file containing fake Discord voice connection initiation packet (IP Discovery)
|
||||
--dpi-desync-fake-stun=<filename>|0xHEX ; file containing fake STUN message
|
||||
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown udp protocol fake payload
|
||||
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
|
||||
--dpi-desync-udplen-pattern=<filename>|0xHEX ; udp tail fill pattern
|
||||
--dpi-desync-start=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply if not prefixed with `^`, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-domains=<domain_list> ; comma separated fixed domain list
|
||||
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply if not prefixed with `^`, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-exclude-domains=<domain_list> ; comma separated fixed domain list
|
||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
--new ; begin new strategy (new profile)
|
||||
--skip ; do not use this profile
|
||||
--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. 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=<proto> ; L6-L7 protocol filter. multiple comma separated values allowed. proto: http tls quic wireguard dht discord stun unknown
|
||||
--filter-ssid=ssid1[,ssid2,ssid3,...] ; per profile wifi SSID filter
|
||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-ip=<ip_list> ; comma separated fixed subnet list
|
||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-exclude-ip=<ip_list> ; comma separated fixed subnet list
|
||||
--daemon ; daemonize
|
||||
--pidfile=<filename> ; write pid to file
|
||||
--user=<username> ; drop root privs
|
||||
--uid=uid[:gid1,gid2,...] ; drop root privs
|
||||
--bind-fix4 ; apply outgoing interface selection fix for generated ipv4 packets
|
||||
--bind-fix6 ; apply outgoing interface selection fix for generated ipv6 packets
|
||||
--wsize=<window_size>[:<scale_factor>] ; set window size. 0 = do not modify. OBSOLETE !
|
||||
--wssize=<window_size>[:<scale_factor>] ; set window size for server. 0 = do not modify. default scale_factor = 0.
|
||||
--wssize-cutoff=[n|d|s]N ; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--ctrack-timeouts=S:E:F[:U] ; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default 60:300:60:60
|
||||
--ctrack-disable=[0|1] ; 1 or no argument disables conntrack
|
||||
--ipcache-lifetime=<int> ; time in seconds to keep cached hop count and domain name (default 7200). 0 = no expiration
|
||||
--ipcache-hostname=[0|1] ; 1 or no argument enables ip->hostname caching
|
||||
--hostcase ; change Host: => host:
|
||||
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
||||
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
||||
--domcase ; mix domain case : Host: TeSt.cOm
|
||||
--methodeol ; add '\n' before method and remove space after Host:
|
||||
--synack-split=[syn|synack|acksyn] ; perform TCP split handshake : send SYN only, SYN+ACK or ACK+SYN
|
||||
--orig-ttl=<int> ; set TTL for original packets
|
||||
--orig-ttl6=<int> ; set ipv6 hop limit for original packets. by default ttl value is used
|
||||
--orig-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: +5:3-64. "0:0-0" or "-" disables autottl.
|
||||
--orig-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --orig-autottl for ipv6 only
|
||||
--orig-mod-start=[n|d|s]N ; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--orig-mod-cutoff=[n|d|s]N ; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--dup=<int> ; duplicate original packets. send N dups before original.
|
||||
--dup-replace=[0|1] ; 1 or no argument means do not send original, only dups
|
||||
--dup-ttl=<int> ; set TTL for dups
|
||||
--dup-ttl6=<int> ; set ipv6 hop limit for dups. by default ttl value is used
|
||||
--dup-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: -1:3-64. "0:0-0" or "-" disables autottl.
|
||||
--dup-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --dup-autottl for ipv6 only
|
||||
--dup-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dup-ts-increment=<int|0xHEX> ; ts fooling TSval signed increment for dup. default -600000
|
||||
--dup-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment for dup. default -10000
|
||||
--dup-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment for dup. default -66000
|
||||
--dup-start=[n|d|s]N ; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--dup-cutoff=[n|d|s]N ; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit hostfakesplit fakeddisorder ipfrag2 udplen tamper
|
||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
||||
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
||||
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used.
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: -1:3-20. "0:0-0" or "-" disables autottl.
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --dpi-desync-autottl for ipv6 only
|
||||
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
||||
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; comma separated list of split positions
|
||||
; markers: method,host,endhost,sld,endsld,midsld,sniext
|
||||
; full list is only used by multisplit and multidisorder
|
||||
; fakedsplit/fakeddisorder use first l7-protocol-compatible parameter if present, first abs value otherwise
|
||||
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; use sequence overlap before first sent original split segment
|
||||
--dpi-desync-split-seqovl-pattern=[+ofs]@<filename>|0xHEX ; pattern for the fake part of overlap
|
||||
--dpi-desync-fakedsplit-pattern=[+ofs]@<filename>|0xHEX ; fake pattern for fakedsplit/fakeddisorder
|
||||
--dpi-desync-fakedsplit-mod=mod[,mod] ; mods can be none,altorder=0|1|2|3 + 0|8|16
|
||||
--dpi-desync-hostfakesplit-midhost=marker+N|marker-N ; additionally split real hostname at specified marker. must be within host..endhost or won't be splitted.
|
||||
--dpi-desync-hostfakesplit-mod=mod[,mod] ; can be none, host=<hostname>, altorder=0|1
|
||||
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
|
||||
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
||||
--dpi-desync-ts-increment=<int|0xHEX> ; ts fooling TSval signed increment. default -600000
|
||||
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
|
||||
--dpi-desync-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment. default -66000
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
||||
--dpi-desync-fake-tcp-mod=mod[,mod] ; comma separated list of tcp fake mods. available mods : none,seq
|
||||
--dpi-desync-fake-http=[+ofs]@<filename>|0xHEX ; file containing fake http request
|
||||
--dpi-desync-fake-tls=[+ofs]@<filename>|0xHEX|![+offset] ; file containing fake TLS ClientHello (for https). '!' = standard fake
|
||||
--dpi-desync-fake-tls-mod=mod[,mod] ; comma separated list of TLS fake mods. available mods : none,rnd,rndsni,sni=<sni>,dupsid,padencap
|
||||
--dpi-desync-fake-unknown=[+ofs]@<filename>|0xHEX ; file containing unknown protocol fake payload
|
||||
--dpi-desync-fake-syndata=[+ofs]@<filename>|0xHEX ; file containing SYN data payload
|
||||
--dpi-desync-fake-quic=[+ofs]@<filename>|0xHEX ; file containing fake QUIC Initial
|
||||
--dpi-desync-fake-wireguard=[+ofs]@<filename>|0xHEX ; file containing fake wireguard handshake initiation
|
||||
--dpi-desync-fake-dht=[+ofs]@<filename>|0xHEX ; file containing fake DHT (d1..e)
|
||||
--dpi-desync-fake-discord=[+ofs]@<filename>|0xHEX ; file containing fake Discord voice connection initiation packet (IP Discovery)
|
||||
--dpi-desync-fake-stun=[+ofs]@<filename>|0xHEX ; file containing fake STUN message
|
||||
--dpi-desync-fake-unknown-udp=[+ofs]@<filename>|0xHEX ; file containing unknown udp protocol fake payload
|
||||
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
|
||||
--dpi-desync-udplen-pattern=[+ofs]@<filename>|0xHEX ; udp tail fill pattern
|
||||
--dpi-desync-start=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply if not prefixed with `^`, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-domains=<domain_list> ; comma separated fixed domain list
|
||||
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply if not prefixed with `^`, gzip supported, multiple hostlists allowed)
|
||||
--hostlist-exclude-domains=<domain_list> ; comma separated fixed domain list
|
||||
--hostlist-auto=<filename> ; detect DPI blocks and build hostlist automatically
|
||||
--hostlist-auto-fail-threshold=<int> ; how many failed attempts cause hostname to be added to auto hostlist (default : 3)
|
||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
--new ; begin new strategy (new profile)
|
||||
--skip ; do not use this profile
|
||||
--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. 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=<proto> ; L6-L7 protocol filter. multiple comma separated values allowed. proto: http tls quic wireguard dht discord stun unknown
|
||||
--filter-ssid=ssid1[,ssid2,ssid3,...] ; per profile wifi SSID filter
|
||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-ip=<ip_list> ; comma separated fixed subnet list
|
||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-exclude-ip=<ip_list> ; comma separated fixed subnet list
|
||||
```
|
||||
|
||||
Many parameters dealing with binary data support loading from hex string prefixed by "0x" or from a file.
|
||||
Filename can be "as is" or prefixed with "@". If there's "+number" prefix before "@" it means offset of data inside the file.
|
||||
Offset must be less that data size.
|
||||
|
||||
### DPI desync attack
|
||||
|
||||
The idea is to take original message, modify it, add additional fake information in such a way that the server OS accepts original data only
|
||||
@@ -286,6 +296,12 @@ Fakes are separate generated by nfqws packets carrying false information for DPI
|
||||
* **datanoack** sends tcp fakes without ACK flag. Servers do not accept this but DPI may accept.
|
||||
This mode may break NAT and may not work with iptables if masquerade is used, even from the router itself.
|
||||
Works with nftables properly. Likely requires external IP address (some ISPs pass these packets through their NAT).
|
||||
* **ts** adds to TSval ts increment value (-600000 by default). Servers discard packets with TSval in some range.
|
||||
Practical tests suggest increment between -100 and -0x80000000.
|
||||
Timestamps are generated by client OS. In linux timestamps are enabled by default. In windows by default timestamps are disabled.
|
||||
They can be enabled with this command : `netsh interface tcp set global timestamps=enabled` .
|
||||
ts fooling requires that timestamps are enabled. They must be enabled on every client OS.
|
||||
TSecr is left unmodified.
|
||||
* **autottl** tries to automatically guess hop count to the server and compute TTL by adding some delta value that can be positive or negative.
|
||||
Positive deltas must be preceeded by unary `+` sign. Deltas without any unary sign are treated negative for old versions compatibility reasons.
|
||||
This tech relies on well known TTL default values used by OS : 64,128,255.
|
||||
@@ -307,6 +323,9 @@ Resulting order would be : `fake1 fake1 fake1 fake2 fake2 fake2 fake3 fake3 fake
|
||||
|
||||
### FAKE mods
|
||||
|
||||
By default all tcp fakes are sent with the same sequence as original packet.
|
||||
This can be changed by `--dpi-desync-fake-tcp-mod=seq`. In the latter case all fakes are sent as if they would be tcp segments of a single fake.
|
||||
|
||||
**nfqws** has built-in TLS fake. It can be customized with `--dpi-desync-fake-tls` option.
|
||||
Customized fake data can be anything - valid TLS Client Hello or arbitrary data.
|
||||
It's possible to use TLS Client Hello with any fingerprint and any SNI.
|
||||
@@ -335,8 +354,37 @@ Example : `--dpi-desync-fake-tls=iana_org.bin --dpi-desync-fake-tls-mod=rndsni -
|
||||
|
||||
* `multisplit`. split request at specified in `--dpi-desync-split-pos` positions
|
||||
* `multidisorder`. same as `multisplit` but send in reverse order
|
||||
* `fakedsplit`. split request into 2 segments adding fakes in the middle of them : fake 1st segment, 1st segment, fake 1st segment, fake 2nd segment, 2nd segment, fake 2nd segment
|
||||
* `fakeddisorder`. same as `fakedsplit` but with another order : fake 2nd segment, 2nd segment, fake 2nd segment, fake 1st segment, 1st segment, fake 1st segment
|
||||
* `fakedsplit`. sequental one position split with fake mix
|
||||
* `hostfakesplit` (altorder=0). fake host part of the request : before host, random fake host, real host (optionally split this part), random fake host repeat, after host
|
||||
* `hostfakesplit` (altorder=1). fake host part of the request : before host, random fake host, after host, real host (optionally split this part)
|
||||
* `fakedsplit`. reverse one position split with fake mix
|
||||
|
||||
`--dpi-desync-fakedsplit-mod=altorder=N` specifies number which influence to the presence of individual fakes in `fakedsplit`/`fakeddisorder`.
|
||||
|
||||
`fakedsplit` TCP segments of multi-packet messages with split pos :
|
||||
|
||||
* `altorder=0`. fake 1st segment, 1st segment, fake 1st segment, fake 2nd segment, 2nd segment, fake 2nd segment
|
||||
* `altorder=1`. 1st segment, fake 1st segment, fake 2nd segment, 2nd segment, fake 2nd segment
|
||||
* `altorder=2`. 1st segment, fake 2nd segment, 2nd segment, fake 2nd segment
|
||||
* `altorder=3`. 1st segment, fake 2nd segment, 2nd segment
|
||||
|
||||
`fakeddisorder` TCP segments of multi-packet messages with split pos :
|
||||
|
||||
* `altorder=0`. fake 2nd segment, 2nd segment, fake 2nd segment, fake 1st segment, 1st segment, fake 1st segment
|
||||
* `altorder=1`. 2nd segment, fake 2nd segment, fake 1st segment, 1st segment, fake 1st segment
|
||||
* `altorder=2`. 2nd segment, fake 1st segment, 1st segment, fake 1st segment
|
||||
* `altorder=3`. 1st segment, fake 1st segment, 1st segment
|
||||
|
||||
`fakedsplit`/`fakeddisorder` TCP segments of multi-packet messages without split pos :
|
||||
|
||||
* `altorder=0`. fake, original, fake
|
||||
* `altorder=8`. original, fake
|
||||
* `altorder=16`. original
|
||||
|
||||
Resulting `altorder=N` is the sum of two `altorder` parts mentioned above.
|
||||
|
||||
`--dpi-desync-fakedsplit-pattern` defines data payload of fakes in `fakedsplit`/`fakeddisorder`. By default pattern is simple `0x00`.
|
||||
Offset of split part + offset of current packet in multi-packet message define offset in the pattern.
|
||||
|
||||
Positions are defined by markers.
|
||||
|
||||
@@ -365,6 +413,22 @@ First relative markers are searched. If no suitable found absolute markers are s
|
||||
|
||||
For example, `--dpi-desync-split-pos=method+2,midsld,5` means `method+2` for http, `midsld` for TLS and 5 for others.
|
||||
|
||||
`--dpi-desync-fakedsplit-mod=altorder=N` switches `fakedsplit` to alternate segment ordering.
|
||||
|
||||
`hostfakesplit` only fakes hostname part of the request making it hard to destinguish between real and fake host names.
|
||||
It works for tcp protocols with host : TLS and HTTP. Real hostname can be additionally split using `--dpi-desync-hostfakesplit-midhost` marker.
|
||||
For example, `--dpi-desync-hostfakesplit-midhost=midsld`. Position must be within host range or split won't happen.
|
||||
Multi-packet queries are supported if hostname part is not already split. If it is fooling is cancelled.
|
||||
|
||||
By default fake host names are generated randomly on the fly using `[0-9a-z]` pattern. If host length is >= 7 dot is placed to simulate 3-char TLD and last 3 chars are replaces with a random known 3-char TLD.
|
||||
It's possible to set fake host template : `--dpi-desync-hostfakesplit-mod=host=<hostname>`.
|
||||
Template hostname will be expanded to the left to original hostname size with random characters from `[0-9a-z]` pattern : "www.networksolutions.com" -> "h8xmdba4tv7a8.google.com".
|
||||
If original hostname size is less than template size it will be cut : "habr.com" -> "ogle.com".
|
||||
If original hostname size is larger than template size by one, dot will be appended to the left : "www.xxx.com" => ".google.com"..
|
||||
That's why it's a good idea to use short hostnames in template : "ya.ru", "vk.com", "x.com".
|
||||
|
||||
`--dpi-desync-hostfakesplit-mod=altorder=1` switches `hostfakesplit` to alternate segment ordering. `altorder=1` sends the whole request with faked host sequentally, then real host segment.
|
||||
|
||||
### Sequence numbers overlap
|
||||
|
||||
`seqovl` adds to one of the original segment `seqovl` bytes to the beginning and decreases sequence number. For `split` - to the first segment, for `disorder` - to the beginning of the penultimate segment sent (second in the original sequence).
|
||||
@@ -693,6 +757,9 @@ Set up bridge networking.
|
||||
|
||||
### IPTABLES for nfqws
|
||||
|
||||
> [!CAUTION]
|
||||
> Starting from Linux kernel 6.17 there's CONFIG_NETFILTER_XTABLES_LEGACY parameter which is not set by default. Many distributions will likely not turn it on making iptables-legacy non working. This is part of iptables deprecation. However iptables-nft still works because their backend is based on nftables.
|
||||
|
||||
This is the common way to redirect some traffic to nfqws :
|
||||
|
||||
```
|
||||
@@ -1137,7 +1204,7 @@ If `MODE_FILTER=hostlist` all present lists are passed to **nfqws** or **tpws**.
|
||||
If all include lists are empty it works like no include lists exist at all.
|
||||
If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Just make it empty.
|
||||
|
||||
Subdomains auto apply. For example, "ru" in the list affects "*.ru" .
|
||||
Subdomains auto apply. For example, "ru" in the list affects "\*.ru" .
|
||||
`^` prefix symbol disables subdomain match.
|
||||
|
||||
**tpws** and **nfqws** automatically reload lists if their modification time or file size is changed.
|
||||
@@ -1225,6 +1292,23 @@ Don't use `<HOSTLIST>` in highly specialized profiles. Use your own filter or ho
|
||||
`<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.
|
||||
|
||||
Change loop prevention mark bit
|
||||
|
||||
`DESYNC_MARK=0x40000000`
|
||||
|
||||
Change postnat scheme mark bit
|
||||
|
||||
`DESYNC_MARK_POSTNAT=0x20000000`
|
||||
|
||||
If uncommented pass to zapret only packets marked with this bit
|
||||
|
||||
`#FILTER_MARK=0x10000000`
|
||||
|
||||
Bit must be set in your own rules.
|
||||
* iptables - in mangle PREROUTING and mangle OUTPUT before zapret rules (iptables -I _after_ zapret rules application).
|
||||
* nftables - in output and prerouting hooks with priority -102 or lower.
|
||||
|
||||
Mark criterias can be any. For example, source IP or source interface name.
|
||||
|
||||
**tpws** socks proxy mode switch
|
||||
|
||||
|
||||
363
docs/readme.md
363
docs/readme.md
@@ -1,4 +1,4 @@
|
||||
# zapret v71.2
|
||||
# zapret v72
|
||||
|
||||
# ВНИМАНИЕ, остерегайтесь мошенников
|
||||
|
||||
@@ -43,6 +43,7 @@ zapret является свободным и open source.
|
||||
- [IPTABLES ДЛЯ NFQWS](#iptables-для-nfqws)
|
||||
- [NFTABLES ДЛЯ NFQWS](#nftables-для-nfqws)
|
||||
- [FLOW OFFLOADING](#flow-offloading)
|
||||
- [ОСОБЕННОСТИ ЖЕЛЕЗОК](#особенности-железок)
|
||||
- [ДУРЕНИЕ СО СТОРОНЫ СЕРВЕРА](#дурение-со-стороны-сервера)
|
||||
- [tpws](#tpws)
|
||||
- [TCP СЕГМЕНТАЦИЯ В TPWS](#tcp-сегментация-в-tpws)
|
||||
@@ -162,106 +163,112 @@ DPI. Все больше становится внереестровых бло
|
||||
dvtws, собираемый из тех же исходников (см. [документация BSD](./bsd.md)).
|
||||
|
||||
```
|
||||
@<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
|
||||
@<config_file>|$<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
|
||||
|
||||
--debug=0|1 ; 1=выводить отладочные сообщения
|
||||
--dry-run ; проверить опции командной строки и выйти. код 0 - успешная проверка.
|
||||
--version ; вывести версию и выйти
|
||||
--comment ; любой текст (игнорируется)
|
||||
--daemon ; демонизировать прогу
|
||||
--pidfile=<file> ; сохранить PID в файл
|
||||
--user=<username> ; менять uid процесса
|
||||
--uid=uid[:gid] ; менять uid процесса
|
||||
--qnum=N ; номер очереди N
|
||||
--bind-fix4 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов
|
||||
--bind-fix6 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов
|
||||
--ctrack-timeouts=S:E:F[:U] ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60
|
||||
--ctrack-disable=[0|1] ; 1 или остутствие аргумента отключает conntrack
|
||||
--ipcache-lifetime=<int> ; время жизни записей кэша IP в секундах. 0 - без ограничений.
|
||||
--ipcache-hostname=[0|1] ; 1 или отсутствие аргумента включают кэширование имен хостов для применения в стратегиях нулевой фазы
|
||||
--wsize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)
|
||||
--wssize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !)
|
||||
--wssize-cutoff=[n|d|s]N ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--synack-split=[syn|synack|acksyn] ; выполнить tcp split handshake. вместо SYN,ACK отсылать только SYN, SYN+ACK или ACK+SYN
|
||||
--orig-ttl=<int> ; модифицировать TTL оригинального пакета
|
||||
--orig-ttl6=<int> ; модифицировать ipv6 hop limit оригинальных пакетов. если не указано, используется значение --orig-ttl
|
||||
--orig-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +5:3-64. "0:0-0" или "-" отключает функцию
|
||||
--orig-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--orig-mod-start=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--orig-mod-cutoff=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--dup=<int> ; высылать N дубликатов до оригинала
|
||||
--dup-replace=[0|1] ; 1 или отсутствие аргумента блокирует отправку оригинала. отправляются только дубликаты.
|
||||
--dup-ttl=<int> ; модифицировать TTL дубликатов
|
||||
--dup-ttl6=<int> ; модифицировать ipv6 hop limit дубликатов. если не указано, используется значение --dup-ttl
|
||||
--dup-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +1:3-64. "0:0-0" или "-" отключает функцию
|
||||
--dup-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--dup-fooling=<fooling> ; дополнительные методики как сделать, чтобы дубликат не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dup-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
||||
--dup-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
||||
--dup-start=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--dup-cutoff=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
|
||||
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
|
||||
--methodeol ; добавить перевод строки в unix стиле ('\n') перед методом и убрать пробел из Host: : "GET / ... Host: domain.com" => "\nGET / ... Host:domain.com"
|
||||
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
||||
--domcase ; домен после Host: сделать таким : TeSt.cOm
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
|
||||
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
|
||||
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
||||
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение --dpi-desync-ttl
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. "0:0-0" или "-" отключает функцию
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
||||
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации в режимах split и disorder
|
||||
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число.
|
||||
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap
|
||||
--dpi-desync-fakedsplit-pattern=<filename>|0xHEX ; чем заполнять фейки в fakedsplit/fakeddisorder
|
||||
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
||||
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
|
||||
--dpi-desync-fake-http=<filename>|0xHEX ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному www.iana.org
|
||||
--dpi-desync-fake-tls=<filename>|0xHEX|! ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному. '!' = стандартный фейк
|
||||
--dpi-desync-fake-tls-mod=mod[,mod] ; список через запятую режимов runtime модификации фейков : none,rnd,rndsni,sni=<sni>,dupsid,padencap
|
||||
--dpi-desync-fake-unknown=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт
|
||||
--dpi-desync-fake-syndata=<filename>|0xHEX ; файл, содержащий фейковый пейлоад пакета SYN для режима десинхронизации syndata
|
||||
--dpi-desync-fake-quic=<filename>|0xHEX ; файл, содержащий фейковый QUIC Initial
|
||||
--dpi-desync-fake-wireguard=<filename>|0xHEX ; файл, содержащий фейковый wireguard handshake initiation
|
||||
--dpi-desync-fake-dht=<filename>|0xHEX ; файл, содержащий фейковый пейлоад DHT протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-fake-discord=<filename>|0xHEX ; файл, содержащий фейковый пейлоад Discord протокола нахождения IP адреса для голосовых чатов для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-fake-stun=<filename>|0xHEX ; файл, содержащий фейковый пейлоад STUN протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
|
||||
--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> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются, если хост не начинается с '^'.
|
||||
; в файле должен быть хост на каждой строке.
|
||||
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; при изменении времени модификации файла он перечитывается автоматически по необходимости
|
||||
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
||||
; списков может быть множество. пустой общий лист = его отсутствие
|
||||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||||
--hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
|
||||
--hostlist-exclude-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
|
||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
||||
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
||||
--hostlist-auto-retrans-threshold=<int> ; сколько ретрансмиссий запроса считать блокировкой (по умолчанию: 3)
|
||||
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
||||
--new ; начало новой стратегии (новый профиль)
|
||||
--skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров.
|
||||
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
||||
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую.
|
||||
--filter-udp=[~]port1[-port2]|* ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает tcp. поддерживается список через запятую.
|
||||
--filter-l7=<proto> ; фильтр протокола L6-L7. поддерживается несколько значений через запятую. proto : http tls quic wireguard dht discord stun unknown
|
||||
--filter-ssid=ssid1[,ssid2,ssid3,...] ; фильтр по имени wifi сети (только для linux)
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
|
||||
--debug=0|1 ; 1=выводить отладочные сообщения
|
||||
--dry-run ; проверить опции командной строки и выйти. код 0 - успешная проверка.
|
||||
--version ; вывести версию и выйти
|
||||
--comment ; любой текст (игнорируется)
|
||||
--daemon ; демонизировать прогу
|
||||
--pidfile=<file> ; сохранить PID в файл
|
||||
--user=<username> ; менять uid процесса
|
||||
--uid=uid[:gid] ; менять uid процесса
|
||||
--qnum=N ; номер очереди N
|
||||
--bind-fix4 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv4 пакетов
|
||||
--bind-fix6 ; пытаться решить проблему неверного выбора исходящего интерфейса для сгенерированных ipv6 пакетов
|
||||
--ctrack-timeouts=S:E:F[:U] ; таймауты внутреннего conntrack в состояниях SYN, ESTABLISHED, FIN, таймаут udp. по умолчанию 60:300:60:60
|
||||
--ctrack-disable=[0|1] ; 1 или остутствие аргумента отключает conntrack
|
||||
--ipcache-lifetime=<int> ; время жизни записей кэша IP в секундах. 0 - без ограничений.
|
||||
--ipcache-hostname=[0|1] ; 1 или отсутствие аргумента включают кэширование имен хостов для применения в стратегиях нулевой фазы
|
||||
--wsize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)
|
||||
--wssize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !)
|
||||
--wssize-cutoff=[n|d|s]N ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--synack-split=[syn|synack|acksyn] ; выполнить tcp split handshake. вместо SYN,ACK отсылать только SYN, SYN+ACK или ACK+SYN
|
||||
--orig-ttl=<int> ; модифицировать TTL оригинального пакета
|
||||
--orig-ttl6=<int> ; модифицировать ipv6 hop limit оригинальных пакетов. если не указано, используется значение --orig-ttl
|
||||
--orig-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +5:3-64. "0:0-0" или "-" отключает функцию
|
||||
--orig-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--orig-mod-start=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--orig-mod-cutoff=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--dup=<int> ; высылать N дубликатов до оригинала
|
||||
--dup-replace=[0|1] ; 1 или отсутствие аргумента блокирует отправку оригинала. отправляются только дубликаты.
|
||||
--dup-ttl=<int> ; модифицировать TTL дубликатов
|
||||
--dup-ttl6=<int> ; модифицировать ipv6 hop limit дубликатов. если не указано, используется значение --dup-ttl
|
||||
--dup-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +1:3-64. "0:0-0" или "-" отключает функцию
|
||||
--dup-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--dup-fooling=<fooling> ; дополнительные методики как сделать, чтобы дубликат не дошел до сервера. none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2
|
||||
--dup-ts-increment=<int|0xHEX> ; инкремент TSval для ts. по умолчанию -600000
|
||||
--dup-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
||||
--dup-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
||||
--dup-start=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--dup-cutoff=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
|
||||
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
|
||||
--methodeol ; добавить перевод строки в unix стиле ('\n') перед методом и убрать пробел из Host: : "GET / ... Host: domain.com" => "\nGET / ... Host:domain.com"
|
||||
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
||||
--domcase ; домен после Host: сделать таким : TeSt.cOm
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit hostfakesplit fakeddisorder ipfrag2 udplen tamper
|
||||
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
|
||||
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
||||
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение --dpi-desync-ttl
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. "0:0-0" или "-" отключает функцию
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
||||
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; список через запятую маркеров для tcp сегментации в режимах split и disorder
|
||||
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; единичный маркер, определяющий величину перекрытия sequence в режимах split и disorder. для split поддерживается только положительное число.
|
||||
--dpi-desync-split-seqovl-pattern=[+ofs]@<filename>|0xHEX ; чем заполнять фейковую часть overlap
|
||||
--dpi-desync-fakedsplit-pattern=[+ofs]@<filename>|0xHEX ; чем заполнять фейки в fakedsplit/fakeddisorder
|
||||
--dpi-desync-fakedsplit-mod=mod[,mod] ; может быть none, altorder=0|1|2|3 + 0|8|16
|
||||
--dpi-desync-hostfakesplit-midhost=marker+N|marker-N ; маркер дополнительного разреза сегмента с оригинальным хостом. должен попадать в пределы хоста.
|
||||
--dpi-desync-hostfakesplit-mod=mod[,mod] ; может быть none, host=<hostname>, altorder=0|1
|
||||
--dpi-desync-ts-increment=<int|0xHEX> ; инкремент TSval для ts. по умолчанию -600000
|
||||
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
||||
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
|
||||
--dpi-desync-fake-tcp-mod=mod[,mod] ; список через запятую режимов runtime модификации tcp фейков (любых) : none, seq
|
||||
--dpi-desync-fake-http=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному www.iana.org
|
||||
--dpi-desync-fake-tls=[+ofs]@<filename>|0xHEX|![+offset] ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному. '!' = стандартный фейк
|
||||
--dpi-desync-fake-tls-mod=mod[,mod] ; список через запятую режимов runtime модификации фейков : none,rnd,rndsni,sni=<sni>,dupsid,padencap
|
||||
--dpi-desync-fake-unknown=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт
|
||||
--dpi-desync-fake-syndata=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый пейлоад пакета SYN для режима десинхронизации syndata
|
||||
--dpi-desync-fake-quic=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый QUIC Initial
|
||||
--dpi-desync-fake-wireguard=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый wireguard handshake initiation
|
||||
--dpi-desync-fake-dht=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый пейлоад DHT протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-fake-discord=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый пейлоад Discord протокола нахождения IP адреса для голосовых чатов для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-fake-stun=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый пейлоад STUN протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-fake-unknown-udp=[+ofs]@<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||
--dpi-desync-udplen-increment=<int> ; на сколько увеличивать длину udp пейлоада в режиме udplen
|
||||
--dpi-desync-udplen-pattern=[+ofs]@<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> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются, если хост не начинается с '^'.
|
||||
; в файле должен быть хост на каждой строке.
|
||||
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; при изменении времени модификации файла он перечитывается автоматически по необходимости
|
||||
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
||||
; списков может быть множество. пустой общий лист = его отсутствие
|
||||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||||
--hostlist-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
|
||||
--hostlist-exclude-domains=<domain_list> ; фиксированный список доменов через зяпятую. можно использовать # в начале для комментирования отдельных доменов.
|
||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
||||
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
||||
--hostlist-auto-retrans-threshold=<int> ; сколько ретрансмиссий запроса считать блокировкой (по умолчанию: 3)
|
||||
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
||||
--new ; начало новой стратегии (новый профиль)
|
||||
--skip ; не использовать этот профиль . полезно для временной деактивации профиля без удаления параметров.
|
||||
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
||||
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую.
|
||||
--filter-udp=[~]port1[-port2]|* ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает tcp. поддерживается список через запятую.
|
||||
--filter-l7=<proto> ; фильтр протокола L6-L7. поддерживается несколько значений через запятую. proto : http tls quic wireguard dht discord stun unknown
|
||||
--filter-ssid=ssid1[,ssid2,ssid3,...] ; фильтр по имени wifi сети (только для linux)
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-exclude-ip=<ip_list> ; фиксированный список подсетей через запятую. можно использовать # в начале для комментирования отдельных подсетей.
|
||||
```
|
||||
|
||||
`--debug` позволяет выводить подробный лог действий на консоль, в syslog или в файл. Может быть важен порядок следования
|
||||
@@ -273,6 +280,13 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
невозможна. Если вы потом удалите файл, и у процесса не будет прав на создание файла в его директории, лог больше не
|
||||
будет вестись. Вместо удаления лучше использовать truncate. В шелле это можно сделать через команду ": >filename"
|
||||
|
||||
Многие параметры, загружающие двоичные данные из файлов, поддерживают загрузку из hex-строки или из файла.
|
||||
hex строка начинается с "0x". Имя файла можно писать как есть или использовать префикс "@".
|
||||
Если перед префиксом "@" указано "+<число>", то это означает смещение полезных данных внутри файла.
|
||||
Файл может загружаться целиком с нулевой позиции, к нему могут применяться модификации, требующие полного файла (TLS),
|
||||
но передача пойдет с позиции offset. offset должен быть меньше длины файла. Если к блоку данных применяется мод,
|
||||
который уменьшает размер данных, и offset окажется не меньше новой длины данных, будет ошибка.
|
||||
|
||||
### АТАКА ДЕСИНХРОНИЗАЦИИ DPI
|
||||
|
||||
Суть ее в следующем. Берется оригинальный запрос, модифицируется, добавляется поддельная информация (фейки)
|
||||
@@ -339,6 +353,12 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP.
|
||||
Но linux NAT оно не пройдет, так что за домашним роутером эта техника скорее всего не сработает, но может сработать с него.
|
||||
Может сработать и через роутер, если подключение по проводу, и на роутере включено аппаратное ускорение.
|
||||
* `ts` прибавляет к значению TSval таймштампа tcp значение ts increment (по умолчанию -600000). Сервера отбрасывают пакеты
|
||||
с TSval в определенных пределах. По практическим тестам инкремент должен быть где-то от -100 до -0x80000000.
|
||||
timestamps генерирует клиентская ОС. В linux таймштампы включены по умолчанию, в windows выключены по умолчанию.
|
||||
Можно включить через команду `netsh interface tcp set global timestamps=enabled`.
|
||||
ts fooling требует, чтобы таймштампы были включены, иначе работать не будет. Включать надо на каждом клиентском устройстве.
|
||||
TSecr оставляется без изменений. Так же требуется, чтобы сервер понимал timestamps, но это в большинстве случаев так.
|
||||
* `autottl`. Суть режима в автоматическом определении TTL, чтобы пакет почти наверняка прошел DPI и немного не дошел до
|
||||
сервера (`--dpi-desync-autottl`). Или наоборот - TTL едва хватило, чтобы он все-таки дошел до сервера (см `--dup-autottl`, `--orig-autottl`).
|
||||
Берутся базовые значения TTL 64,128,255, смотрится входящий пакет (да, требуется направить первый входящий пакет на nfqws !).
|
||||
@@ -362,6 +382,10 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
|
||||
### МОДИФИКАЦИЯ ФЕЙКОВ
|
||||
|
||||
Любые tcp фейки отправляются с исходным sequence по умолчанию, даже если их несколько.
|
||||
Если задать `--dpi-desync-fake-tcp-mod=seq`, то несколько фейков будут отправлены с увеличением sequence number таким образом,
|
||||
как будто они являются tcp сегментами одного фейка.
|
||||
|
||||
В nfqws зашит базовый вариант фейка для TLS. Его можно переопределить опцией `--dpi-desync-fake-tls`.
|
||||
Переопределение фейков дает возможность использовать любые данные в качестве фейка для TLS.
|
||||
Можно использовать фейковый Client Hello с любым фингерпринтом и с любым SNI.
|
||||
@@ -394,17 +418,61 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
|
||||
* `multisplit`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях.
|
||||
* `multidisorder`. нарезаем запрос на указанных в `--dpi-desync-split-pos` позициях и отправляем в обратном порядке.
|
||||
* `fakedsplit`. нарезаем запрос на 2 части, обрамляя каждую часть фейками : фейк 1-й части, 1 часть, фейк 1-й части, фейк 2-й части, 2 часть, фейк 2-й части
|
||||
* `fakedsplit`. различные варианты замешивания фейков и оригиналов в прямом порядке
|
||||
* `fakeddisorder`. различные варианты замешивания фейков и оригиналов в обратном порядке
|
||||
* `hostfakesplit` (altorder=0). фейкование части запроса с хостом : оригинал до хоста, фейк хоста, оригинал хоста (+ опционально нарезка маркером midhost), фейк хоста, оригинал после хоста
|
||||
* `hostfakesplit` (altorder=1). фейкование части запроса с хостом : оригинал до хоста, фейк хоста, оригинал после хоста, оригинал хоста (+опционально нарезка маркером midhost)
|
||||
* `fakeddisorder`. аналогично `fakedsplit`, только в обратном порядке : фейк 2-й части, 2 часть, фейк 2-й части, фейк 1-й части, 1 часть, фейк 1 части.
|
||||
|
||||
Для `fakedsplit` и `fakeddisorder` предусмотрены вариации порядка следования сегментов.
|
||||
Параметр `--dpi-desync-fakedsplit-mod=altorder=N` задает число, влияющее на наличие отдельных фейков :
|
||||
|
||||
Режимы altorder для `fakedsplit` для части многопакетного запроса, где есть сплит-позиция :
|
||||
* `altorder=0`. фейк 1-й части, 1 часть, фейк 1-й части, фейк 2-й части, 2 часть, фейк 2-й части
|
||||
* `altorder=1`. 1 часть, фейк 1-й части, фейк 2-й части, 2 часть, фейк 2-й части
|
||||
* `altorder=2`. 1 часть, фейк 2-й части, 2 часть, фейк 2-й части
|
||||
* `altorder=3`. 1 часть, фейк 2-й части, 2 часть
|
||||
|
||||
Режимы altorder для `fakeddisorder` для части многопакетного запроса, где есть сплит-позиция :
|
||||
* `altorder=0`. фейк 2-й части, 2 часть, фейк 2-й части, фейк 1-й части, 1 часть, фейк 1-й части
|
||||
* `altorder=1`. 2 часть, фейк 2-й части, фейк 1-й части, 1 часть, фейк 1-й части
|
||||
* `altorder=2`. 2 часть, фейк 1-й части, 1 часть, фейк 1-й части
|
||||
* `altorder=3`. 2 часть, фейк 1-й части, 1 часть
|
||||
|
||||
Режимы altorder для `fakedsplit` и `fakeddisorder` для части многопакетного запроса, где нет сплит-позиции :
|
||||
* `altorder=0`. фейк, оригинал, фейк
|
||||
* `altorder=8`. оригинал, фейк
|
||||
* `altorder=16`. оригинал
|
||||
|
||||
Итоговое число `altorder=N` вычисляется как сумма чисел из этих двух групп. По умолчанию `altorder=0`.
|
||||
|
||||
Содержимое фейков в `fakedsplit`/`fakeddisorder` определяется параметром `--dpi-desync-fakedsplit-pattern` (по умолчанию 0x00).
|
||||
Данные фейков берутся из паттерна со смещением, соответствующим смещению отсылаемых частей.
|
||||
Данные фейков берутся из паттерна со смещением, соответствующим смещению отсылаемых частей, учитывая смещения пакетов в многопакетных запросах.
|
||||
Размеры фейков соответствуют длинам отсылаемых частей.
|
||||
Цель этих режимов - максимально усложнить выявление оригинальных данных среди фейков.
|
||||
|
||||
Использование `fakedsplit` или `fakeddisorder` на TLS kyber с md5sig fooling может привести к ошибкам "message too long", если позиция сплита мала,
|
||||
поскольку будет превышение MTU из-за md5 tcp option.
|
||||
|
||||
Режим 'hostfakesplit' имеет задачу минимального вмешательства фейком - как раз по той части запроса, на основании которой DPI принимает решение о блокировке. Конкретно - имени хоста.
|
||||
По умолчанию фейк хоста генерируется каждый раз случайно из набора `[a-z0-9]`. При длине более 7 символов за 3 символа до конца ставится точка, имитируя TLD, а последние 3 символа заполняются одним из нескольких известных TLD.
|
||||
|
||||
Можно переопределить шаблон генерации с помощью `--dpi-desync-hostfakesplit-mod=host=<hostname>`. В последнем случае справа всегда будет указанный hostname.
|
||||
Слева он будет дополнен до размера оригинального хоста как поддомен со случайными символами. Пример : "www.networksolutions.com" -> "h8xmdba4tv7a8.google.com".
|
||||
Если размер оригинального хоста меньше шаблона, шаблон будет порезан : "habr.com" -> "ogle.com".
|
||||
Если размер оригинального хоста больше шаблона на 1, получится инвалидный пустой поддомен : "www.xxx.com" => ".google.com".
|
||||
Поэтому стоит использовать максимально короткие хосты из разрешенных : "ya.ru", "vk.com".
|
||||
|
||||
`--dpi-desync-hostfakesplit-mod=altorder=1` позволяет сменить порядок следования частей на альтернативный вариант.
|
||||
`altorder=1` шлет фрагменты в таком порядке, чтобы при последовательной сборке сегментов на DPI он получил полностью собранный оригинал запроса с подмененным хостом.
|
||||
Реальный хост идет отдельным сегментом уже после. То есть в этом варианте применяется разновидность disorder. Сервер принимает фрагменты с нарушенным порядком sequence.
|
||||
|
||||
Опционально можно разрезать оригинальный фейк. Например, `--dpi-desync-hostfakesplit-midhost=midsld`. Позиция нарезки должна попадать внутрь хоста.
|
||||
Многопакетные запросы поддерживаются только, если исходная нарезка пакетов не включает позиции имени хоста. В последнем случае дурение отменяется.
|
||||
|
||||
Вариант `fakedsplit` имеет несколько альтернативных порядков нарезки - от 0 до 3. Режим задается в параметре `--dpi-desync-fakedsplit-mod=altorder=N`.
|
||||
Каждый следующий altorder убирает часть фейков.
|
||||
|
||||
Для определения позиций нарезки используются маркеры.
|
||||
|
||||
* **Абсолютный положительный маркер** - числовое смещение внутри пакета или группы пакетов от начала.
|
||||
@@ -774,7 +842,7 @@ L7 протокол становится известен обычно посл
|
||||
|
||||
> [!IMPORTANT]
|
||||
> user-mode реализация ipset создавалась не как удобная замена *nix версии, реализованной в ядре.
|
||||
> Вариант в ядре работает гораздо эффективнее. Это создавалось для систем без подд3ержки ipset в ядре.
|
||||
> Вариант в ядре работает гораздо эффективнее. Это создавалось для систем без поддержки ipset в ядре.
|
||||
> Конкретно - Windows и ядра Linux, собранные без nftables и ipset модулей ядра. Например, в android нет ipset.
|
||||
|
||||
### ФИЛЬТРАЦИЯ ПО WIFI
|
||||
@@ -809,6 +877,9 @@ wireless extensions считаются deprecated и на новых ядрах
|
||||
|
||||
### IPTABLES ДЛЯ NFQWS
|
||||
|
||||
> [!CAUTION]
|
||||
> Начиная с ядер Linux 6.17 присутствует параметр конфигурации ядра CONFIG_NETFILTER_XTABLES_LEGACY, который по умолчанию в дистрибутиве может быть "not set". Отсутствие этой настройки выключает iptables-legacy. Это часть процесса депрекации iptables. Тем не менее iptables-nft будут работать, поскольку используют backend nftables.
|
||||
|
||||
iptables для задействования атаки на первые пакеты данных в tcp соединении :
|
||||
|
||||
```
|
||||
@@ -923,6 +994,73 @@ iptables target `FLOWOFFLOAD` - это проприетарное изобрет
|
||||
Управление offload в nftables реализовано в базовом ядре linux без патчей.
|
||||
nftables - единственный способ включения offload на классическом Linux.
|
||||
|
||||
### ОСОБЕННОСТИ ЖЕЛЕЗОК
|
||||
|
||||
На устройствах mediatek замечены 2 проблемы.
|
||||
|
||||
Драйвер mediatek ethernet отбрасывает tcp и udp пакеты с неверной чексуммой на аппаратном уровне, это не отключается.
|
||||
Как следствие не будет работать fooling badsum через роутер, но будет с него.
|
||||
|
||||
Другая проблема mediatek, затрагивающая как ethernet, так и wireless, проявляется на udp, когда включен offload rx-gro-list.
|
||||
Пока отсутствует nfqueue, все хорошо. Как только nfqueue появляется, часть пакетов выпадает.
|
||||
Особенно заметно это проявляется на дурении QUIC с kyber.
|
||||
|
||||
<details>
|
||||
<summary><b>shell код лечения</b></summary>
|
||||
|
||||
```
|
||||
append_separator_list()
|
||||
{
|
||||
# $1 - var name to receive result
|
||||
# $2 - separator
|
||||
# $3 - quoter
|
||||
# $4,$5,... - elements
|
||||
local _var="$1" sep="$2" quo="$3" i
|
||||
|
||||
eval i="\$$_var"
|
||||
shift; shift; shift
|
||||
while [ -n "$1" ]; do
|
||||
if [ -n "$i" ] ; then
|
||||
i="$i$sep$quo$1$quo"
|
||||
else
|
||||
i="$quo$1$quo"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
eval $_var="\$i"
|
||||
}
|
||||
resolve_lower_devices()
|
||||
{
|
||||
# $1 - bridge interface name
|
||||
[ -d "/sys/class/net/$1" ] && {
|
||||
find "/sys/class/net/$1" -follow -maxdepth 1 -name "lower_*" |
|
||||
{
|
||||
local l lower lowers
|
||||
while read lower; do
|
||||
lower="$(basename "$lower")"
|
||||
l="${lower#lower_*}"
|
||||
[ "$l" != "$lower" ] && append_separator_list lowers ' ' '' "$l"
|
||||
done
|
||||
printf "$lowers"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# it breaks nfqueue
|
||||
lans=$(resolve_lower_devices br-lan)
|
||||
for int in $lans; do
|
||||
ethtool -K $int rx-gro-list off
|
||||
done
|
||||
```
|
||||
</details>
|
||||
|
||||
Этот код нужно вызывать после вставания интерфейса LAN, когда все bridge members уже занесены в bridge.
|
||||
Можно использовать хук в `/etc/hotplug.d/iface`. Должен быть установлен `ethtool`.
|
||||
|
||||
Проблемы mediatek были подтверждены на MT7621 (TP-Link Archer C6U v1) и MT7981 (Xiaomi AX3000T).
|
||||
Другие чипсеты могут быть так же подвержены проблеме, а могут и не быть. Более широкой статистики нет.
|
||||
|
||||
|
||||
### ДУРЕНИЕ СО СТОРОНЫ СЕРВЕРА
|
||||
|
||||
Это тоже возможно.
|
||||
@@ -1502,7 +1640,7 @@ LISTS_RELOAD=- отключает перезагрузку листов.
|
||||
Файл есть, но несмотря на это дурится все, кроме exclude.
|
||||
Если вам нужен именно такой режим - не обязательно удалять `zapret-hosts-users.txt`. Достаточно сделать его пустым.
|
||||
|
||||
Поддомены учитываются автоматически. Например, строчка "ru" вносит в список "*.ru". Строчка "*.ru" в списке не сработает.
|
||||
Поддомены учитываются автоматически. Например, строчка "ru" вносит в список "\*.ru". Строчка "\*.ru" в списке не сработает.
|
||||
Можно использовать символ `^` в начале хоста, чтобы отказаться от автоматического учета поддоменов.
|
||||
|
||||
Список доменов РКН может быть получен скриптами
|
||||
@@ -1665,6 +1803,8 @@ SECURE_DNS=0|1 - принудительно выключить или включ
|
||||
DOH_SERVERS - список URL DoH через пробел для автоматического выбора работающего сервера
|
||||
DOH_SERVER - конкретный DoH URL, отказ от поиска
|
||||
UNBLOCKED_DOM - незаблокированный домен, который используется для тестов IP block
|
||||
SIMULATE=1 - включить режим симуляции для отладки логики скрипта. отключаются реальные запросы через curl, заменяются рандомным результатом.
|
||||
SIM_SUCCESS_RATE=<percent> - вероятность успеха симуляции в процентах
|
||||
```
|
||||
|
||||
Пример запуска с переменными:\
|
||||
@@ -1833,6 +1973,21 @@ nfqws начнет получать адреса пакетов из локал
|
||||
То есть на этом профиле не происходит автоматическое добавление заблокированных доменов.
|
||||
Но если на другом профиле что-то будет добавлено, то этот профиль примет изменения автоматически.
|
||||
|
||||
***Изменение бита mark для предотвращения зацикливания***\
|
||||
`DESYNC_MARK=0x40000000`
|
||||
|
||||
***Изменение бита mark для пометки пакетов, проходящих по POSTNAT схеме (только nftables)***\
|
||||
`DESYNC_MARK_POSTNAT=0x20000000`
|
||||
|
||||
***Если раскоментировано, пометка пакетов, которые должны быть обработаны zapret.***\
|
||||
`#FILTER_MARK=0x10000000`
|
||||
|
||||
Бит должен быть установлен вашими собственными правилами.
|
||||
* Для iptables - в цепочках mangle PREROUTING и mangle OUTPUT перед правилами zapret (iptables -I _после_ применения правил zapret).
|
||||
* Для nftables - в хуках output и prerouting с приоритетом -102 или ниже.
|
||||
|
||||
Критерии пометки любые. Например, IP адрес или интерфейс источника. Это ответ на вопрос "как мне сделать, чтобы телик не ходил через zapret или чтобы через него ходил только мой комп".
|
||||
|
||||
***Включение стандартной опции tpws в режиме socks***\
|
||||
`TPWS_SOCKS_ENABLE=0`
|
||||
|
||||
|
||||
@@ -47,7 +47,9 @@ Task of `iptables` is done inside `winws` through `windivert` filters. `Windiver
|
||||
--wf-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||
--wf-tcp=[~]port1[-port2] ; TCP port filter. ~ means negation. multiple comma separated values allowed.
|
||||
--wf-udp=[~]port1[-port2] ; UDP port filter. ~ means negation. multiple comma separated values allowed.
|
||||
--wf-raw=<filter>|@<filename> ; raw windivert filter string or filename
|
||||
--wf-raw-part=<filter>|@<filename> ; partial raw windivert filter string or filename
|
||||
--wf-filter-lan=0|1 ; add excluding filter for non-global IP (default : 1)
|
||||
--wf-raw=<filter>|@<filename> ; full raw windivert filter string or filename. replaces --wf-tcp,--wf-udp,--wf-raw-part
|
||||
--wf-save=<filename> ; save windivert filter string to a file and exit
|
||||
--ssid-filter=ssid1[,ssid2,ssid3,...] ; enable winws only if any of specified wifi SSIDs connected
|
||||
--nlm-filter=net1[,net2,net3,...] ; enable winws only if any of specified NLM network is connected. names and GUIDs are accepted.
|
||||
@@ -60,6 +62,12 @@ Interface indexes can be discovered using this command : `netsh int ip show int`
|
||||
|
||||
If you can't find index this way use `winws --debug` to see index there. Subinterface index is almost always 0 and you can omit it.
|
||||
|
||||
`--wf-raw-part` specifies partial windivert filter. Multiple filter parts are supported. They can also be combined with `--wf-tcp`,`--wf-udp`.
|
||||
|
||||
`--wf-raw` specifies full windivert filter that replaces `--wf-tcp`,`--wf-udp`,`--wf-raw-part`.
|
||||
|
||||
Kernel filtering with windivert language is much more effective than passing massive amount of traffic to winws. Use it if possible to save CPU resources.
|
||||
|
||||
Multiple `winws` processes are allowed. However, it's discouraged to intersect their filters.
|
||||
|
||||
`--ssid-filter` allows to enable `winws` only if specified wifi networks are connected. `winws` auto detects SSID appearance and disappearance.
|
||||
@@ -165,3 +173,9 @@ clone the code in all cmd files to support multiple tasks `winws1,winws2,winws3,
|
||||
Tasks can also be controlled from GUI `taskschd.msc`.
|
||||
|
||||
Also you can use windows services the same way with `service_*.cmd`.
|
||||
|
||||
### Windows Server
|
||||
|
||||
winws is linked against wlanapi.dll which is absent by default.
|
||||
To solve this problem run power shell as administrator and execute command `Install-WindowsFeature -Name Wireless-Networking`.
|
||||
Then reboot the system.
|
||||
|
||||
@@ -44,7 +44,7 @@ tpws в режиме socks можно запускать под более-ме
|
||||
|
||||
Это вариант пакетного фильтра nfqws для Windows, построенный на базе windivert.
|
||||
Все функции работоспособны, однако функционал ipset в ядре отсутствует. Он реализован в user mode. Фильтры по большому количеству IP адресов невозможны.
|
||||
Работа с проходящим трафиком, например в случае "расшаривания" соединения, не проверялась и не гарантируется.
|
||||
Работа с проходящим трафиком, например в случае "расшаривания" соединения, невозможна.
|
||||
Для работы с windivert требуются права администратора.
|
||||
Специфические для unix параметры, такие как `--uid`, `--user` и тд, исключены. Все остальные параметры аналогичны nfqws и dvtws.
|
||||
|
||||
@@ -63,15 +63,17 @@ secure boot могут быть проблемы из-за подписи дра
|
||||
Чтобы не писать сложные фильтры вручную, предусмотрены различные упрощенные варианты автоматического построения фильтров.
|
||||
|
||||
```
|
||||
--wf-iface=<int>[.<int>] ; числовые индексы интерфейса и суб-интерфейса
|
||||
--wf-l3=ipv4|ipv6 ; фильтр L3 протоколов. по умолчанию включены ipv4 и ipv6.
|
||||
--wf-tcp=[~]port1[-port2] ; фильтр портов для tcp. ~ означает отрицание
|
||||
--wf-udp=[~]port1[-port2] ; фильтр портов для udp. ~ означает отрицание
|
||||
--wf-raw=<filter>|@<filename> ; задать напрямую фильтр windivert из параметра или из файла. имени файла предшествует символ @.
|
||||
--wf-save=<filename> ; сохранить сконструированный фильтр windivert в файл для последующей правки вручную
|
||||
--wf-iface=<int>[.<int>] ; числовые индексы интерфейса и суб-интерфейса
|
||||
--wf-l3=ipv4|ipv6 ; фильтр L3 протоколов. по умолчанию включены ipv4 и ipv6.
|
||||
--wf-tcp=[~]port1[-port2] ; фильтр портов для tcp. ~ означает отрицание
|
||||
--wf-udp=[~]port1[-port2] ; фильтр портов для udp. ~ означает отрицание
|
||||
--wf-raw-part=<filter>|@<filename> ; частичный windivert фильтр из параметра или из файла. имени файла предшествует символ @. может быть множество частей. сочетается с --wf-tcp,--wf-udp.
|
||||
--wf-filter-lan=0|1 ; отфильтровывать адреса назначения, не являющиеся глобальными inet адресами ipv4 или ipv6. по умолчанию - 1.
|
||||
--wf-raw=<filter>|@<filename> ; полный windivert фильтр из параметра или из файла. имени файла предшествует символ @. замещает --wf-raw-part,--wf-tcp,--wf-udp.
|
||||
--wf-save=<filename> ; сохранить сконструированный фильтр windivert в файл для последующей правки вручную
|
||||
--ssid-filter=ssid1[,ssid2,ssid3,...] ; включать winws только когда подключена любая из указанных wifi сетей
|
||||
--nlm-filter=net1[,net2,net3,...] ; включать winws только когда подключена любая из указанных сетей NLM
|
||||
--nlm-list[=all] ; вывести список сетей NLM. по умолчанию только подключенных, all - всех.
|
||||
--nlm-filter=net1[,net2,net3,...] ; включать winws только когда подключена любая из указанных сетей NLM
|
||||
--nlm-list[=all] ; вывести список сетей NLM. по умолчанию только подключенных, all - всех.
|
||||
```
|
||||
|
||||
Параметры `--wf-l3`, `--wf-tcp`, `--wf-udp` могут брать несколько значений через запятую.
|
||||
@@ -80,11 +82,19 @@ secure boot могут быть проблемы из-за подписи дра
|
||||
Некоторых типы соединений там не увидеть. В этом случае запускайте **winws** с параметром `--debug` и смотрите IfIdx там.
|
||||
SubInterface используется windivert, но практически всегда **0**, его можно не указывать. Вероятно, он нужен в редких случаях.
|
||||
|
||||
Конструктор фильтров автоматически включает входящие tcp пакеты с tcp synack и tcp rst для корректной работы функций
|
||||
Конструктор стандартных фильтров автоматически включает входящие tcp пакеты с tcp synack и tcp rst для корректной работы функций
|
||||
autottl и autohostlist. При включении autohostlist так же перенаправляются пакеты данных с http redirect с кодами 302 и 307.
|
||||
Всегда добавляется фильтр на исключение не-интернет адресов ipv4 и ipv6.
|
||||
Для сложных нестандартных сценариев могут потребоваться свои фильтры. Логично будет начать со стандартного шаблона,
|
||||
сохраненного через `--wf-save`. Нужно править файл и подсовывать его в параметре `--wf-raw`. Максимальный размер фильтра - **16 Kb**.
|
||||
Если не указаное иное, добавляется фильтр на исключение не-интернет адресов ipv4 и ipv6.
|
||||
Для сложных нестандартных сценариев могут потребоваться свои фильтры. Полный фильтр --wf-raw замещает все остальное.
|
||||
Частичные фильтры `--wf-raw-part` совместимы друг с другом и `--wf-tcp` и `--wf-udp`. Они позволяют исключить написание
|
||||
громоздких полных фильтров, сосредоточившись лишь на добавлении какого-то особенного пейлоада.
|
||||
`--wf-save` позволяет записать итоговый windivert фильтр в файл. Максимальный размер фильтра - **16 Kb**.
|
||||
|
||||
Фильтрация windivert производится в ядре. Это несравнимо легче по ресурсам, чем перенаправлять пакеты в пространство user mode,
|
||||
чтобы winws принимал решение. Поэтому пользуйтесь по максимуму возможностями windivert.
|
||||
Например, если вам нужно дурить wireguard на все порты, вам придется перенаправить все порты на winws. Или же написать windivert фильтр, который отсечет wireguard по содержимому пакета.
|
||||
Разница в нагрузке на процессор колоссальна. В первом случае - до 100% одного ядра cpu в зависимости от обьема исходящего udp трафика (привет, торрент и uTP), во втором - близко к 0.
|
||||
Кроме нагрузки на процессор еще можете порезать себе скорость, тк одно ядро не будет справляться с обработкой вашего гигабитного интернета. А на старых ноутах еще и получите самолетный вой системы охлаждения, приводящий к ее износу.
|
||||
|
||||
Можно запускать несколько процессов **winws** с разными стратегиями. Однако, не следует делать пересекающиеся фильтры.
|
||||
|
||||
@@ -257,3 +267,9 @@ _zapret-winws_ - это отдельный комплект для повсед
|
||||
Все батники требуется запускать от имени администратора.
|
||||
|
||||
Управлять задачами можно так же из графической программы управления планировщиком `taskschd.msc`
|
||||
|
||||
## Особенности Windows Server
|
||||
|
||||
winws слинкован с wlanapi.dll, который по умолчанию не установлен в windows server.
|
||||
Для решения этой проблемы запустите power shell под администратором и выполните команду `Install-WindowsFeature -Name Wireless-Networking`.
|
||||
После чего перезагрузите систему.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---dpi-desync=tamper}"
|
||||
@@ -10,20 +11,20 @@ zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - add, 0 - stop
|
||||
|
||||
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_DESYNC_DHT"
|
||||
local opt="--qnum=$QNUM_DHT4ALL $NFQWS_OPT_DESYNC_DHT"
|
||||
do_nfqws $1 $DNUM_DHT4ALL "$opt"
|
||||
}
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local f uf4 uf6
|
||||
local first_packet_only="$ipt_connbytes 1:1"
|
||||
local f uf4 uf6
|
||||
local first_packet_only="$ipt_connbytes 1:1"
|
||||
|
||||
f='-p udp -m length --length 109:407 -m u32 --u32'
|
||||
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 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL
|
||||
fw_nfqws_post $1 "$f $uf4 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
@@ -32,6 +33,6 @@ zapret_custom_firewall_nft()
|
||||
local f
|
||||
local first_packet_only="$nft_connbytes 1"
|
||||
|
||||
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
|
||||
f="meta length 109-407 meta l4proto udp @ih,0,16 0x6431"
|
||||
nft_fw_nfqws_post "$f $first_packet_only" "$f $first_packet_only" $QNUM_DHT4ALL
|
||||
}
|
||||
|
||||
36
init.d/custom.d.examples.linux/50-discord-media
Normal file
36
init.d/custom.d.examples.linux/50-discord-media
Normal file
@@ -0,0 +1,36 @@
|
||||
# this custom script runs desync to all discord media packets
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_DISCORD_MEDIA="${NFQWS_OPT_DESYNC_DISCORD_MEDIA:---dpi-desync=fake --dpi-desync-repeats=2}"
|
||||
DISCORD_MEDIA_PORT_RANGE="${DISCORD_MEDIA_PORT_RANGE:-50000-50099}"
|
||||
|
||||
alloc_dnum DNUM_DISCORD_MEDIA
|
||||
alloc_qnum QNUM_DISCORD_MEDIA
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - add, 0 - stop
|
||||
|
||||
local opt="--qnum=$QNUM_DISCORD_MEDIA $NFQWS_OPT_DESYNC_DISCORD_MEDIA"
|
||||
do_nfqws $1 $DNUM_DISCORD_MEDIA "$opt"
|
||||
}
|
||||
# size = 156 (8 udp header + 148 payload) && payload starts with 0x01000000
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local DISABLE_IPV6=1
|
||||
local port_range=$(replace_char - : $DISCORD_MEDIA_PORT_RANGE)
|
||||
local f="-p udp --dport $port_range -m u32 --u32"
|
||||
# this is simplified test to skip writing monstrous rule. instead of checking 64 bytes for zeroes only check 2 dwords for zero
|
||||
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x52&&0>>22&0x3C@8=0x00010046&&0>>22&0x3C@16=0&&0>>22&0x3C@76=0" '' $QNUM_DISCORD_MEDIA
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
local DISABLE_IPV6=1
|
||||
local f="udp dport $DISCORD_MEDIA_PORT_RANGE udp length == 82 @ih,0,32 0x00010046 @ih,64,128 0x00000000000000000000000000000000 @ih,192,128 0x00000000000000000000000000000000 @ih,320,128 0x00000000000000000000000000000000 @ih,448,128 0x00000000000000000000000000000000"
|
||||
nft_fw_nfqws_post "$f" '' $QNUM_DISCORD_MEDIA
|
||||
}
|
||||
31
init.d/custom.d.examples.linux/50-stun4all
Normal file
31
init.d/custom.d.examples.linux/50-stun4all
Normal file
@@ -0,0 +1,31 @@
|
||||
# this custom script runs desync to all stun packets
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---dpi-desync=fake --dpi-desync-repeats=2}"
|
||||
|
||||
alloc_dnum DNUM_STUN4ALL
|
||||
alloc_qnum QNUM_STUN4ALL
|
||||
|
||||
zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - add, 0 - stop
|
||||
|
||||
local opt="--qnum=$QNUM_STUN4ALL $NFQWS_OPT_DESYNC_STUN"
|
||||
do_nfqws $1 $DNUM_STUN4ALL "$opt"
|
||||
}
|
||||
# size = 156 (8 udp header + 148 payload) && payload starts with 0x01000000
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local f='-p udp -m u32 --u32'
|
||||
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=28:65535&&0>>22&0x3C@12=0x2112A442&&0>>22&0x3C@8&0xC0000003=0" "$f 44>>16=28:65535&&52=0x2112A442&&48&0xC0000003=0" $QNUM_STUN4ALL
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
local f="udp length >= 28 @ih,32,32 0x2112A442 @ih,0,2 0 @ih,30,2 0"
|
||||
nft_fw_nfqws_post "$f" "$f" $QNUM_STUN4ALL
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
# this custom script runs desync to all wireguard handshake initiation packets
|
||||
# NOTE: this works for original wireguard and may not work for 3rd party implementations such as xray
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---dpi-desync=fake}"
|
||||
NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---dpi-desync=fake --dpi-desync-repeats=2}"
|
||||
|
||||
alloc_dnum DNUM_WG4ALL
|
||||
alloc_qnum QNUM_WG4ALL
|
||||
@@ -10,7 +12,7 @@ zapret_custom_daemons()
|
||||
{
|
||||
# $1 - 1 - add, 0 - stop
|
||||
|
||||
local opt="--qnum=$QNUM_WG4ALL $NFQWS_OPT_DESYNC_WG"
|
||||
local opt="--qnum=$QNUM_WG4ALL $NFQWS_OPT_DESYNC_WG"
|
||||
do_nfqws $1 $DNUM_WG4ALL "$opt"
|
||||
}
|
||||
# size = 156 (8 udp header + 148 payload) && payload starts with 0x01000000
|
||||
@@ -18,13 +20,13 @@ zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - run, 0 - stop
|
||||
|
||||
local f='-p udp -m u32 --u32'
|
||||
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x9c&&0>>22&0x3C@8=0x01000000" "$f 44>>16=0x9c&&48=0x01000000" $QNUM_WG4ALL
|
||||
local f='-p udp -m u32 --u32'
|
||||
fw_nfqws_post $1 "$f 0>>22&0x3C@4>>16=0x9c&&0>>22&0x3C@8=0x01000000" "$f 44>>16=0x9c&&48=0x01000000" $QNUM_WG4ALL
|
||||
}
|
||||
zapret_custom_firewall_nft()
|
||||
{
|
||||
# stop logic is not required
|
||||
|
||||
local f="udp length 156 @th,64,32 0x01000000"
|
||||
nft_fw_nfqws_post "$f" "$f" $QNUM_WG4ALL
|
||||
local f="udp length 156 @ih,0,32 0x01000000"
|
||||
nft_fw_nfqws_post "$f" "$f" $QNUM_WG4ALL
|
||||
}
|
||||
|
||||
14
init.d/windivert.filter.examples/README.txt
Normal file
14
init.d/windivert.filter.examples/README.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Цель этих фильтров - отсекать полезную нагрузку в режиме ядра, не насилуя процессор перенаправлением целого потока на winws.
|
||||
Задействуются через `winws --wf-raw-part=@filename`. Может быть несколько частичных фильтров. Они могут сочетаться с --wf-tcp и --wf-udp.
|
||||
Однако, язык фильтров windivert не содержит операций с битовыми полями, сдвигов и побитовой логики.
|
||||
Поэтому фильтры получились более слабыми, способными передавать неправильную нагрузку.
|
||||
Дофильтрация производится силами winws.
|
||||
|
||||
Описание языка фильтров : https://reqrypt.org/windivert-doc.html#filter_language
|
||||
Пример инстанса для пробития медиапотоков в discord : `winws --wf-raw-part=@windivert_part.discord_media.txt --wf-raw-part=@windivert_part.stun.txt --filter-l7=stun,discord --dpi-desync=fake`
|
||||
|
||||
|
||||
These filters are invoked using `winws --wf-raw-part=@filename`. Multiple filter parts are supported. They can be combined with --wf-tcp and --wf-udp.
|
||||
Filters are kernel mode and save great amount of CPU.
|
||||
However windivert cannot filter by bit fields, lacks shift and bitwise logic operations.
|
||||
Filters are relaxed and can pass wrong payloads. Finer filtering is done by winws.
|
||||
@@ -0,0 +1,20 @@
|
||||
outbound and ip and
|
||||
udp.DstPort>=50000 and udp.DstPort<=50099 and
|
||||
udp.PayloadLength=74 and
|
||||
udp.Payload32[0]=0x00010046 and
|
||||
udp.Payload32[2]=0 and
|
||||
udp.Payload32[3]=0 and
|
||||
udp.Payload32[4]=0 and
|
||||
udp.Payload32[5]=0 and
|
||||
udp.Payload32[6]=0 and
|
||||
udp.Payload32[7]=0 and
|
||||
udp.Payload32[8]=0 and
|
||||
udp.Payload32[9]=0 and
|
||||
udp.Payload32[10]=0 and
|
||||
udp.Payload32[11]=0 and
|
||||
udp.Payload32[12]=0 and
|
||||
udp.Payload32[13]=0 and
|
||||
udp.Payload32[14]=0 and
|
||||
udp.Payload32[15]=0 and
|
||||
udp.Payload32[16]=0 and
|
||||
udp.Payload32[17]=0
|
||||
3
init.d/windivert.filter.examples/windivert_part.stun.txt
Normal file
3
init.d/windivert.filter.examples/windivert_part.stun.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
outbound and
|
||||
udp.PayloadLength>=20 and
|
||||
udp.Payload32[1]=0x2112A442 and udp.Payload[0]<0x40
|
||||
@@ -0,0 +1,3 @@
|
||||
outbound and
|
||||
udp.PayloadLength=148 and
|
||||
udp.Payload[0]=0x01
|
||||
@@ -29,6 +29,7 @@ void ConntrackClearHostname(t_ctrack *track)
|
||||
{
|
||||
free(track->hostname);
|
||||
track->hostname = NULL;
|
||||
track->hostname_is_ip = false;
|
||||
}
|
||||
static void ConntrackClearTrack(t_ctrack *track)
|
||||
{
|
||||
|
||||
@@ -83,12 +83,15 @@ typedef struct
|
||||
bool b_cutoff; // mark for deletion
|
||||
bool b_wssize_cutoff, b_desync_cutoff, b_dup_cutoff, b_orig_mod_cutoff;
|
||||
|
||||
uint16_t ip_id;
|
||||
|
||||
t_l7proto l7proto;
|
||||
bool l7proto_discovered;
|
||||
char *hostname;
|
||||
bool hostname_is_ip;
|
||||
bool hostname_discovered;
|
||||
bool hostname_ah_check; // should perform autohostlist checks
|
||||
|
||||
|
||||
t_reassemble reasm_orig;
|
||||
struct rawpacket_tailhead delayed;
|
||||
} t_ctrack;
|
||||
|
||||
@@ -118,6 +118,7 @@ static void fill_tcphdr(
|
||||
uint16_t nsport, uint16_t ndport,
|
||||
uint16_t nwsize, uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint32_t ts_increment,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
uint16_t data_len)
|
||||
@@ -165,13 +166,13 @@ static void fill_tcphdr(
|
||||
*(uint32_t*)(tcpopt+t+14)=random();
|
||||
t+=18;
|
||||
}
|
||||
if (timestamps || (fooling & FOOL_TS))
|
||||
if (timestamps)
|
||||
{
|
||||
tcpopt[t] = 8; // kind
|
||||
tcpopt[t+1] = 10; // len
|
||||
// forge only TSecr if orig timestamp is present
|
||||
*(uint32_t*)(tcpopt+t+2) = timestamps ? timestamps[0] : -1;
|
||||
*(uint32_t*)(tcpopt+t+6) = (timestamps && !(fooling & FOOL_TS)) ? timestamps[1] : -1;
|
||||
memcpy(tcpopt+t+2,timestamps,8);
|
||||
// forge TSval, keep TSecr
|
||||
if (fooling & FOOL_TS) *(uint32_t*)(tcpopt+t+2) = net32_add(*(uint32_t*)(tcpopt+t+2),ts_increment);
|
||||
t+=10;
|
||||
}
|
||||
if (scale_factor!=SCALE_NONE)
|
||||
@@ -242,6 +243,7 @@ bool prepare_tcp_segment4(
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t fooling,
|
||||
uint32_t ts_increment,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
@@ -257,7 +259,7 @@ bool prepare_tcp_segment4(
|
||||
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
||||
|
||||
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_TCP, DF, ttl, tos, ip_id);
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,sack,nmss,nseq,nack_seq,src->sin_port,dst->sin_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment,len);
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,sack,nmss,nseq,nack_seq,src->sin_port,dst->sin_port,nwsize,scale_factor,timestamps,ts_increment,badseq_increment,badseq_ack_increment,len);
|
||||
|
||||
memcpy(payload,data,len);
|
||||
tcp4_fix_checksum(tcp,ip_payload_len,&ip->ip_src,&ip->ip_dst);
|
||||
@@ -279,6 +281,7 @@ bool prepare_tcp_segment6(
|
||||
uint8_t ttl,
|
||||
uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
uint32_t ts_increment,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
@@ -343,7 +346,7 @@ bool prepare_tcp_segment6(
|
||||
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
||||
|
||||
fill_ip6hdr(ip6, &src->sin6_addr, &dst->sin6_addr, ip_payload_len, proto, ttl, flow_label);
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,sack,nmss,nseq,nack_seq,src->sin6_port,dst->sin6_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment,len);
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,sack,nmss,nseq,nack_seq,src->sin6_port,dst->sin6_port,nwsize,scale_factor,timestamps,ts_increment,badseq_increment,badseq_ack_increment,len);
|
||||
|
||||
memcpy(payload,data,len);
|
||||
tcp6_fix_checksum(tcp,transport_payload_len,&ip6->ip6_src,&ip6->ip6_dst);
|
||||
@@ -368,15 +371,16 @@ bool prepare_tcp_segment(
|
||||
uint16_t ip_id,
|
||||
uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
uint32_t ts_increment,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
return (src->sa_family==AF_INET && dst->sa_family==AF_INET) ?
|
||||
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,sack,nmss,nseq,nack_seq,nwsize,scale_factor,timestamps,DF,ttl,tos,ip_id,fooling,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,sack,nmss,nseq,nack_seq,nwsize,scale_factor,timestamps,DF,ttl,tos,ip_id,fooling,ts_increment,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
(src->sa_family==AF_INET6 && dst->sa_family==AF_INET6) ?
|
||||
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,sack,nmss,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,flow_label,fooling,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,sack,nmss,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,flow_label,fooling,ts_increment,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
false;
|
||||
}
|
||||
|
||||
@@ -416,7 +420,7 @@ bool prepare_udp_segment4(
|
||||
|
||||
memcpy(payload,data,len);
|
||||
if (padding)
|
||||
fill_pattern(payload+len,padlen,padding,padding_size);
|
||||
fill_pattern(payload+len,padlen,padding,padding_size,0);
|
||||
else
|
||||
memset(payload+len,0,padlen);
|
||||
udp4_fix_checksum(udp,ip_payload_len,&ip->ip_src,&ip->ip_dst);
|
||||
@@ -505,7 +509,7 @@ bool prepare_udp_segment6(
|
||||
|
||||
memcpy(payload,data,len);
|
||||
if (padding)
|
||||
fill_pattern(payload+len,padlen,padding,padding_size);
|
||||
fill_pattern(payload+len,padlen,padding,padding_size,0);
|
||||
else
|
||||
memset(payload+len,0,padlen);
|
||||
udp6_fix_checksum(udp,transport_payload_len,&ip6->ip6_src,&ip6->ip6_dst);
|
||||
|
||||
@@ -81,6 +81,7 @@ bool prepare_tcp_segment4(
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t fooling,
|
||||
uint32_t ts_increment,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
@@ -97,6 +98,7 @@ bool prepare_tcp_segment6(
|
||||
uint8_t ttl,
|
||||
uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
uint32_t ts_increment,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
@@ -116,6 +118,7 @@ bool prepare_tcp_segment(
|
||||
uint16_t ip_id,
|
||||
uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
uint32_t ts_increment,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
|
||||
2460
nfq/desync.c
2460
nfq/desync.c
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@ enum dpi_desync_mode {
|
||||
DESYNC_FAKEDDISORDER,
|
||||
DESYNC_MULTISPLIT,
|
||||
DESYNC_MULTIDISORDER,
|
||||
DESYNC_HOSTFAKESPLIT,
|
||||
DESYNC_IPFRAG2,
|
||||
DESYNC_HOPBYHOP,
|
||||
DESYNC_DESTOPT,
|
||||
|
||||
@@ -124,6 +124,61 @@ void expand_bits(void *target, const void *source, unsigned int source_bitlen, u
|
||||
if ((bitlen &= 7)) ((uint8_t*)target)[bytelen] = ((uint8_t*)source)[bytelen] & (~((1 << (8-bitlen)) - 1));
|
||||
}
|
||||
|
||||
// " [fd00::1]" => "fd00::1"
|
||||
// "[fd00::1]:8000" => "fd00::1"
|
||||
// "127.0.0.1" => "127.0.0.1"
|
||||
// " 127.0.0.1:8000" => "127.0.0.1"
|
||||
// " vk.com:8000" => "vk.com"
|
||||
// return value: true - host is ip addr
|
||||
bool strip_host_to_ip(char *host)
|
||||
{
|
||||
size_t l;
|
||||
char *h,*p;
|
||||
uint8_t addr[16];
|
||||
|
||||
for (h = host ; *h==' ' || *h=='\t' ; h++);
|
||||
l = strlen(h);
|
||||
if (l>=2)
|
||||
{
|
||||
if (*h=='[')
|
||||
{
|
||||
// ipv6 ?
|
||||
for (p=++h ; *p && *p!=']' ; p++);
|
||||
if (*p==']')
|
||||
{
|
||||
l = p-h;
|
||||
memmove(host,h,l);
|
||||
host[l]=0;
|
||||
return inet_pton(AF_INET6, host, addr)>0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inet_pton(AF_INET6, h, addr)>0)
|
||||
{
|
||||
// ipv6 ?
|
||||
if (host!=h)
|
||||
{
|
||||
l = strlen(h);
|
||||
memmove(host,h,l);
|
||||
host[l]=0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ipv4 ?
|
||||
for (p=h ; *p && *p!=':' ; p++);
|
||||
l = p-h;
|
||||
if (host!=h) memmove(host,h,l);
|
||||
host[l]=0;
|
||||
return inet_pton(AF_INET, host, addr)>0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ntop46(const struct sockaddr *sa, char *str, size_t len)
|
||||
{
|
||||
if (!len) return;
|
||||
@@ -283,10 +338,18 @@ bool parse_hex_str(const char *s, uint8_t *pbuf, size_t *size)
|
||||
return true;
|
||||
}
|
||||
|
||||
void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize)
|
||||
void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize,size_t offset)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
if (offset%=patsize)
|
||||
{
|
||||
size = patsize-offset;
|
||||
size = bufsize>size ? size : bufsize;
|
||||
memcpy(buf,pattern+offset,size);
|
||||
buf += size;
|
||||
bufsize -= size;
|
||||
}
|
||||
while (bufsize)
|
||||
{
|
||||
size = bufsize>patsize ? patsize : bufsize;
|
||||
|
||||
@@ -33,6 +33,8 @@ bool append_to_list_file(const char *filename, const char *s);
|
||||
|
||||
void expand_bits(void *target, const void *source, unsigned int source_bitlen, unsigned int target_bytelen);
|
||||
|
||||
bool strip_host_to_ip(char *host);
|
||||
|
||||
void print_sockaddr(const struct sockaddr *sa);
|
||||
void ntop46(const struct sockaddr *sa, char *str, size_t len);
|
||||
void ntop46_port(const struct sockaddr *sa, char *str, size_t len);
|
||||
@@ -68,7 +70,7 @@ static inline uint32_t pntoh32(const uint8_t *p) {
|
||||
}
|
||||
|
||||
bool parse_hex_str(const char *s, uint8_t *pbuf, size_t *size);
|
||||
void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize);
|
||||
void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize,size_t offset);
|
||||
|
||||
int fprint_localtime(FILE *F);
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ bool LoadAllHostLists()
|
||||
|
||||
|
||||
|
||||
static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
||||
static bool SearchHostList(hostlist_pool *hostlist, const char *host, bool no_match_subdomains)
|
||||
{
|
||||
if (hostlist)
|
||||
{
|
||||
@@ -195,6 +195,7 @@ static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
||||
}
|
||||
else
|
||||
DLOG("negative\n");
|
||||
if (no_match_subdomains) break;
|
||||
p = strchr(p, '.');
|
||||
if (p) p++;
|
||||
bHostFull = false;
|
||||
@@ -220,7 +221,7 @@ bool HostlistsReloadCheckForProfile(const struct desync_profile *dp)
|
||||
return HostlistsReloadCheck(&dp->hl_collection) && HostlistsReloadCheck(&dp->hl_collection_exclude);
|
||||
}
|
||||
// return : true = apply fooling, false = do not apply
|
||||
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
struct hostlist_item *item;
|
||||
|
||||
@@ -233,7 +234,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
||||
LIST_FOREACH(item, hostlists_exclude, next)
|
||||
{
|
||||
DLOG("[%s] exclude ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
if (SearchHostList(item->hfile->hostlist, host, no_match_subdomains))
|
||||
{
|
||||
if (excluded) *excluded = true;
|
||||
return false;
|
||||
@@ -245,7 +246,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
||||
LIST_FOREACH(item, hostlists, next)
|
||||
{
|
||||
DLOG("[%s] include ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
if (SearchHostList(item->hfile->hostlist, host, no_match_subdomains))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -255,10 +256,10 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
||||
|
||||
|
||||
// return : true = apply fooling, false = do not apply
|
||||
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
DLOG("* hostlist check for profile %d\n",dp->n);
|
||||
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, excluded, bSkipReloadCheck);
|
||||
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, no_match_subdomains, excluded, bSkipReloadCheck);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ bool AppendHostList(hostlist_pool **hostlist, const char *filename);
|
||||
bool LoadAllHostLists();
|
||||
bool NonEmptyHostlist(hostlist_pool **hostlist);
|
||||
// return : true = apply fooling, false = do not apply
|
||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck);
|
||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
||||
void HostlistsDebug();
|
||||
|
||||
1695
nfq/nfqws.c
1695
nfq/nfqws.c
File diff suppressed because it is too large
Load Diff
15
nfq/params.c
15
nfq/params.c
@@ -20,6 +20,7 @@ const char *progname = "nfqws";
|
||||
#error UNKNOWN_SYSTEM_TIME
|
||||
#endif
|
||||
|
||||
const char * tld[6] = { "com","org","net","edu","gov","biz" };
|
||||
|
||||
int DLOG_FILE(FILE *F, const char *format, va_list args)
|
||||
{
|
||||
@@ -227,6 +228,7 @@ void dp_init(struct desync_profile *dp)
|
||||
dp->fake_syndata_size = 16;
|
||||
dp->wscale=-1; // default - dont change scale factor (client)
|
||||
dp->desync_ttl6 = dp->dup_ttl6 = dp->orig_mod_ttl6 = 0xFF; // unused
|
||||
dp->desync_ts_increment = dp->dup_ts_increment = TS_INCREMENT_DEFAULT;
|
||||
dp->desync_badseq_increment = dp->dup_badseq_increment = BADSEQ_INCREMENT_DEFAULT;
|
||||
dp->desync_badseq_ack_increment = dp->dup_badseq_ack_increment = BADSEQ_ACK_INCREMENT_DEFAULT;
|
||||
dp->wssize_cutoff_mode = dp->desync_start_mode = dp->desync_cutoff_mode = dp->dup_start_mode = dp->dup_cutoff_mode = dp->orig_mod_start_mode = dp->orig_mod_cutoff_mode = 'n'; // packet number by default
|
||||
@@ -240,11 +242,11 @@ bool dp_fake_defaults(struct desync_profile *dp)
|
||||
{
|
||||
struct blob_item *item;
|
||||
if (blob_collection_empty(&dp->fake_http))
|
||||
if (!blob_collection_add_blob(&dp->fake_http,fake_http_request_default,strlen(fake_http_request_default),0))
|
||||
if (!blob_collection_add_blob(&dp->fake_http,fake_http_request_default,strlen(fake_http_request_default),0,0))
|
||||
return false;
|
||||
if (blob_collection_empty(&dp->fake_tls))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_tls,fake_tls_clienthello_default,sizeof(fake_tls_clienthello_default),4+sizeof(((struct fake_tls_mod*)0)->sni))))
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_tls,fake_tls_clienthello_default,sizeof(fake_tls_clienthello_default),4+sizeof(((struct fake_tls_mod*)0)->sni),0)))
|
||||
return false;
|
||||
if (!(item->extra2 = malloc(sizeof(struct fake_tls_mod))))
|
||||
return false;
|
||||
@@ -252,13 +254,13 @@ bool dp_fake_defaults(struct desync_profile *dp)
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_unknown))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_unknown,NULL,256,0)))
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_unknown,NULL,256,0,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
}
|
||||
if (blob_collection_empty(&dp->fake_quic))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_quic,NULL,620,0)))
|
||||
if (!(item=blob_collection_add_blob(&dp->fake_quic,NULL,620,0,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
item->data[0] = 0x40;
|
||||
@@ -268,7 +270,7 @@ bool dp_fake_defaults(struct desync_profile *dp)
|
||||
{
|
||||
if (blob_collection_empty(*fake))
|
||||
{
|
||||
if (!(item=blob_collection_add_blob(*fake,NULL,64,0)))
|
||||
if (!(item=blob_collection_add_blob(*fake,NULL,64,0,0)))
|
||||
return false;
|
||||
memset(item->data,0,item->size);
|
||||
}
|
||||
@@ -296,6 +298,8 @@ struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
|
||||
}
|
||||
static void dp_clear_dynamic(struct desync_profile *dp)
|
||||
{
|
||||
free(dp->fsplit_pattern);
|
||||
|
||||
hostlist_collection_destroy(&dp->hl_collection);
|
||||
hostlist_collection_destroy(&dp->hl_collection_exclude);
|
||||
ipset_collection_destroy(&dp->ips_collection);
|
||||
@@ -370,6 +374,7 @@ void cleanup_params(struct params_s *params)
|
||||
#ifdef __CYGWIN__
|
||||
strlist_destroy(¶ms->ssid_filter);
|
||||
strlist_destroy(¶ms->nlm_filter);
|
||||
strlist_destroy(¶ms->wf_raw_part);
|
||||
#else
|
||||
free(params->user); params->user=NULL;
|
||||
#endif
|
||||
|
||||
36
nfq/params.h
36
nfq/params.h
@@ -28,6 +28,8 @@
|
||||
#define BADSEQ_INCREMENT_DEFAULT -10000
|
||||
#define BADSEQ_ACK_INCREMENT_DEFAULT -66000
|
||||
|
||||
#define TS_INCREMENT_DEFAULT -600000
|
||||
|
||||
#define IPFRAG_UDP_DEFAULT 8
|
||||
#define IPFRAG_TCP_DEFAULT 32
|
||||
|
||||
@@ -66,6 +68,8 @@
|
||||
|
||||
#define MAX_GIDS 64
|
||||
|
||||
extern const char * tld[6];
|
||||
|
||||
enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG, LOG_TARGET_ANDROID };
|
||||
|
||||
struct fake_tls_mod_cache
|
||||
@@ -74,9 +78,23 @@ struct fake_tls_mod_cache
|
||||
};
|
||||
struct fake_tls_mod
|
||||
{
|
||||
char sni[64];
|
||||
char sni[128];
|
||||
uint32_t mod;
|
||||
};
|
||||
struct hostfakesplit_mod
|
||||
{
|
||||
char host[128];
|
||||
size_t host_size;
|
||||
int ordering;
|
||||
};
|
||||
struct fakedsplit_mod
|
||||
{
|
||||
int ordering;
|
||||
};
|
||||
struct tcp_mod
|
||||
{
|
||||
bool seq;
|
||||
};
|
||||
|
||||
typedef enum {SS_NONE=0,SS_SYN,SS_SYNACK,SS_ACKSYN} t_synack_split;
|
||||
|
||||
@@ -100,7 +118,7 @@ struct desync_profile
|
||||
// multisplit
|
||||
struct proto_pos splits[MAX_SPLITS];
|
||||
int split_count;
|
||||
struct proto_pos seqovl;
|
||||
struct proto_pos seqovl,hostfakesplit_midhost;
|
||||
|
||||
char dup_start_mode, dup_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||
bool dup_replace;
|
||||
@@ -108,7 +126,7 @@ struct desync_profile
|
||||
unsigned int dup_repeats;
|
||||
uint8_t dup_ttl, dup_ttl6;
|
||||
uint32_t dup_fooling_mode;
|
||||
uint32_t dup_badseq_increment, dup_badseq_ack_increment;
|
||||
uint32_t dup_ts_increment, dup_badseq_increment, dup_badseq_ack_increment;
|
||||
autottl dup_autottl, dup_autottl6;
|
||||
|
||||
char orig_mod_start_mode, orig_mod_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||
@@ -121,15 +139,20 @@ struct desync_profile
|
||||
uint8_t desync_ttl, desync_ttl6;
|
||||
autottl desync_autottl, desync_autottl6;
|
||||
uint32_t desync_fooling_mode;
|
||||
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
||||
uint32_t desync_ts_increment, desync_badseq_increment, desync_badseq_ack_increment;
|
||||
|
||||
struct blob_collection_head fake_http,fake_tls,fake_unknown,fake_unknown_udp,fake_quic,fake_wg,fake_dht,fake_discord,fake_stun;
|
||||
uint8_t fake_syndata[FAKE_MAX_TCP],seqovl_pattern[FAKE_MAX_TCP],fsplit_pattern[FAKE_MAX_TCP],udplen_pattern[FAKE_MAX_UDP];
|
||||
size_t fake_syndata_size;
|
||||
uint8_t fake_syndata[FAKE_MAX_TCP],seqovl_pattern[FAKE_MAX_TCP],udplen_pattern[FAKE_MAX_UDP];
|
||||
uint8_t *fsplit_pattern;
|
||||
size_t fake_syndata_size, fsplit_pattern_size;
|
||||
|
||||
struct fake_tls_mod tls_mod_last;
|
||||
struct blob_item *tls_fake_last;
|
||||
|
||||
struct hostfakesplit_mod hfs_mod;
|
||||
struct fakedsplit_mod fs_mod;
|
||||
struct tcp_mod tcp_mod;
|
||||
|
||||
int udplen_increment;
|
||||
|
||||
bool filter_ipv4,filter_ipv6;
|
||||
@@ -198,6 +221,7 @@ struct params_s
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
struct str_list_head ssid_filter,nlm_filter;
|
||||
struct str_list_head wf_raw_part;
|
||||
#else
|
||||
bool droproot;
|
||||
char *user;
|
||||
|
||||
22
nfq/pools.c
22
nfq/pools.c
@@ -12,7 +12,7 @@
|
||||
HASH_DEL(*ppool, elem); \
|
||||
free(elem); \
|
||||
}
|
||||
|
||||
|
||||
#define ADD_STR_POOL(etype, ppool, keystr, keystr_len) \
|
||||
etype *elem; \
|
||||
if (!(elem = (etype*)malloc(sizeof(etype)))) \
|
||||
@@ -25,7 +25,7 @@
|
||||
memcpy(elem->str, keystr, keystr_len); \
|
||||
elem->str[keystr_len] = 0; \
|
||||
oom = false; \
|
||||
HASH_ADD_KEYPTR(hh, *ppool, elem->str, strlen(elem->str), elem); \
|
||||
HASH_ADD_KEYPTR(hh, *ppool, elem->str, keystr_len, elem); \
|
||||
if (oom) \
|
||||
{ \
|
||||
free(elem->str); \
|
||||
@@ -33,9 +33,12 @@
|
||||
return false; \
|
||||
}
|
||||
#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \
|
||||
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
|
||||
elem->flags = flg;
|
||||
|
||||
etype *elem_find; \
|
||||
HASH_FIND(hh, *ppool, keystr, keystr_len, elem_find); \
|
||||
if (!elem_find) { \
|
||||
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
|
||||
elem->flags = flg; \
|
||||
}
|
||||
|
||||
#undef uthash_nonfatal_oom
|
||||
#define uthash_nonfatal_oom(elt) ut_oom_recover(elt)
|
||||
@@ -576,8 +579,9 @@ struct blob_item *blob_collection_add(struct blob_collection_head *head)
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve)
|
||||
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve, size_t offset)
|
||||
{
|
||||
if (offset>=size) return NULL;
|
||||
struct blob_item *entry = calloc(1,sizeof(struct blob_item));
|
||||
if (!entry) return NULL;
|
||||
if (!(entry->data = malloc(size+size_reserve)))
|
||||
@@ -588,6 +592,7 @@ struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, co
|
||||
if (data) memcpy(entry->data,data,size);
|
||||
entry->size = size;
|
||||
entry->size_buf = size+size_reserve;
|
||||
entry->offset = offset;
|
||||
|
||||
// insert to the end
|
||||
struct blob_item *itemc,*iteml=LIST_FIRST(head);
|
||||
@@ -629,6 +634,7 @@ static void ipcache_item_init(ip_cache_item *item)
|
||||
{
|
||||
ipcache_item_touch(item);
|
||||
item->hostname = NULL;
|
||||
item->hostname_is_ip = false;
|
||||
item->hops = 0;
|
||||
}
|
||||
static void ipcache_item_destroy(ip_cache_item *item)
|
||||
@@ -690,7 +696,7 @@ static void ipcache4Print(ip_cache4 *ipcache)
|
||||
{
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET, &ipc->key.addr, s_ip, sizeof(s_ip));
|
||||
printf("%s iface=%s : hops %u hostname=%s now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last));
|
||||
printf("%s iface=%s : hops %u hostname=%s hostname_is_ip=%u now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, ipc->data.hostname ? ipc->data.hostname : "", ipc->data.hostname_is_ip, (unsigned long long)(now-ipc->data.last));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,7 +754,7 @@ static void ipcache6Print(ip_cache6 *ipcache)
|
||||
{
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET6, &ipc->key.addr, s_ip, sizeof(s_ip));
|
||||
printf("%s iface=%s : hops %u hostname=%s now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last));
|
||||
printf("%s iface=%s : hops %u hostname=%s hostname_is_ip=%u now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, ipc->data.hostname ? ipc->data.hostname : "", ipc->data.hostname_is_ip, (unsigned long long)(now-ipc->data.last));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,13 +157,14 @@ struct blob_item {
|
||||
uint8_t *data; // main data blob
|
||||
size_t size; // main data blob size
|
||||
size_t size_buf;// main data blob allocated size
|
||||
size_t offset; // optional offset to useful data
|
||||
void *extra; // any data without size
|
||||
void *extra2; // any data without size
|
||||
LIST_ENTRY(blob_item) next;
|
||||
};
|
||||
LIST_HEAD(blob_collection_head, blob_item);
|
||||
struct blob_item *blob_collection_add(struct blob_collection_head *head);
|
||||
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve);
|
||||
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve, size_t offset);
|
||||
void blob_collection_destroy(struct blob_collection_head *head);
|
||||
bool blob_collection_empty(const struct blob_collection_head *head);
|
||||
|
||||
@@ -182,6 +183,7 @@ typedef struct ip_cache_item
|
||||
{
|
||||
time_t last;
|
||||
char *hostname;
|
||||
bool hostname_is_ip;
|
||||
uint8_t hops;
|
||||
} ip_cache_item;
|
||||
typedef struct ip_cache4
|
||||
|
||||
@@ -123,6 +123,61 @@ void expand_bits(void *target, const void *source, unsigned int source_bitlen, u
|
||||
if ((bitlen &= 7)) ((uint8_t*)target)[bytelen] = ((uint8_t*)source)[bytelen] & (~((1 << (8-bitlen)) - 1));
|
||||
}
|
||||
|
||||
// " [fd00::1]" => "fd00::1"
|
||||
// "[fd00::1]:8000" => "fd00::1"
|
||||
// "127.0.0.1" => "127.0.0.1"
|
||||
// " 127.0.0.1:8000" => "127.0.0.1"
|
||||
// " vk.com:8000" => "vk.com"
|
||||
// return value: true - host is ip addr
|
||||
bool strip_host_to_ip(char *host)
|
||||
{
|
||||
size_t l;
|
||||
char *h,*p;
|
||||
uint8_t addr[16];
|
||||
|
||||
for (h = host ; *h==' ' || *h=='\t' ; h++);
|
||||
l = strlen(h);
|
||||
if (l>=2)
|
||||
{
|
||||
if (*h=='[')
|
||||
{
|
||||
// ipv6 ?
|
||||
for (p=++h ; *p && *p!=']' ; p++);
|
||||
if (*p==']')
|
||||
{
|
||||
l = p-h;
|
||||
memmove(host,h,l);
|
||||
host[l]=0;
|
||||
return inet_pton(AF_INET6, host, addr)>0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inet_pton(AF_INET6, h, addr)>0)
|
||||
{
|
||||
// ipv6 ?
|
||||
if (host!=h)
|
||||
{
|
||||
l = strlen(h);
|
||||
memmove(host,h,l);
|
||||
host[l]=0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ipv4 ?
|
||||
for (p=h ; *p && *p!=':' ; p++);
|
||||
l = p-h;
|
||||
if (host!=h) memmove(host,h,l);
|
||||
host[l]=0;
|
||||
return inet_pton(AF_INET, host, addr)>0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ntop46(const struct sockaddr *sa, char *str, size_t len)
|
||||
{
|
||||
if (!len) return;
|
||||
|
||||
@@ -31,6 +31,8 @@ bool append_to_list_file(const char *filename, const char *s);
|
||||
|
||||
void expand_bits(void *target, const void *source, unsigned int source_bitlen, unsigned int target_bytelen);
|
||||
|
||||
bool strip_host_to_ip(char *host);
|
||||
|
||||
void ntop46(const struct sockaddr *sa, char *str, size_t len);
|
||||
void ntop46_port(const struct sockaddr *sa, char *str, size_t len);
|
||||
void print_sockaddr(const struct sockaddr *sa);
|
||||
|
||||
@@ -170,7 +170,7 @@ bool LoadAllHostLists()
|
||||
|
||||
|
||||
|
||||
static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
||||
static bool SearchHostList(hostlist_pool *hostlist, const char *host, bool no_match_subdomains)
|
||||
{
|
||||
if (hostlist)
|
||||
{
|
||||
@@ -195,6 +195,7 @@ static bool SearchHostList(hostlist_pool *hostlist, const char *host)
|
||||
}
|
||||
else
|
||||
VPRINT("negative\n");
|
||||
if (no_match_subdomains) break;
|
||||
p = strchr(p, '.');
|
||||
if (p) p++;
|
||||
bHostFull = false;
|
||||
@@ -220,7 +221,7 @@ bool HostlistsReloadCheckForProfile(const struct desync_profile *dp)
|
||||
return HostlistsReloadCheck(&dp->hl_collection) && HostlistsReloadCheck(&dp->hl_collection_exclude);
|
||||
}
|
||||
// return : true = apply fooling, false = do not apply
|
||||
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
struct hostlist_item *item;
|
||||
|
||||
@@ -233,7 +234,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
||||
LIST_FOREACH(item, hostlists_exclude, next)
|
||||
{
|
||||
VPRINT("[%s] exclude ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
if (SearchHostList(item->hfile->hostlist, host, no_match_subdomains))
|
||||
{
|
||||
if (excluded) *excluded = true;
|
||||
return false;
|
||||
@@ -245,7 +246,7 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
||||
LIST_FOREACH(item, hostlists, next)
|
||||
{
|
||||
VPRINT("[%s] include ", item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
if (SearchHostList(item->hfile->hostlist, host, no_match_subdomains))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -255,10 +256,10 @@ static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, con
|
||||
|
||||
|
||||
// return : true = apply fooling, false = do not apply
|
||||
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
VPRINT("* hostlist check for profile %d\n",dp->n);
|
||||
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, excluded, bSkipReloadCheck);
|
||||
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, no_match_subdomains, excluded, bSkipReloadCheck);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ bool AppendHostList(hostlist_pool **hostlist, const char *filename);
|
||||
bool LoadAllHostLists();
|
||||
bool NonEmptyHostlist(hostlist_pool **hostlist);
|
||||
// return : true = apply fooling, false = do not apply
|
||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool no_match_subdomains, bool *excluded, bool bSkipReloadCheck);
|
||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
||||
void HostlistsDebug();
|
||||
|
||||
16
tpws/pools.c
16
tpws/pools.c
@@ -25,7 +25,7 @@
|
||||
memcpy(elem->str, keystr, keystr_len); \
|
||||
elem->str[keystr_len] = 0; \
|
||||
oom = false; \
|
||||
HASH_ADD_KEYPTR(hh, *ppool, elem->str, strlen(elem->str), elem); \
|
||||
HASH_ADD_KEYPTR(hh, *ppool, elem->str, keystr_len, elem); \
|
||||
if (oom) \
|
||||
{ \
|
||||
free(elem->str); \
|
||||
@@ -33,9 +33,12 @@
|
||||
return false; \
|
||||
}
|
||||
#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \
|
||||
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
|
||||
elem->flags = flg;
|
||||
|
||||
etype *elem_find; \
|
||||
HASH_FIND(hh, *ppool, keystr, keystr_len, elem_find); \
|
||||
if (!elem_find) { \
|
||||
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
|
||||
elem->flags = flg; \
|
||||
}
|
||||
|
||||
#undef uthash_nonfatal_oom
|
||||
#define uthash_nonfatal_oom(elt) ut_oom_recover(elt)
|
||||
@@ -616,6 +619,7 @@ static void ipcache_item_init(ip_cache_item *item)
|
||||
{
|
||||
ipcache_item_touch(item);
|
||||
item->hostname = NULL;
|
||||
item->hostname_is_ip = false;
|
||||
}
|
||||
static void ipcache_item_destroy(ip_cache_item *item)
|
||||
{
|
||||
@@ -675,7 +679,7 @@ static void ipcache4Print(ip_cache4 *ipcache)
|
||||
{
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET, &ipc->key.addr, s_ip, sizeof(s_ip));
|
||||
printf("%s : hostname=%s now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last));
|
||||
printf("%s : hostname=%s hostname_is_ip=%u now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", ipc->data.hostname_is_ip, (unsigned long long)(now-ipc->data.last));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,7 +736,7 @@ static void ipcache6Print(ip_cache6 *ipcache)
|
||||
{
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET6, &ipc->key.addr, s_ip, sizeof(s_ip));
|
||||
printf("%s : hostname=%s now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", (unsigned long long)(now-ipc->data.last));
|
||||
printf("%s : hostname=%s hostname_is_ip=%u now=last+%llu\n", s_ip, ipc->data.hostname ? ipc->data.hostname : "", ipc->data.hostname_is_ip, (unsigned long long)(now-ipc->data.last));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,7 @@ typedef struct ip_cache_item
|
||||
{
|
||||
time_t last;
|
||||
char *hostname;
|
||||
bool hostname_is_ip;
|
||||
} ip_cache_item;
|
||||
typedef struct ip_cache4
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ static void TLSDebug(const uint8_t *tls,size_t sz)
|
||||
TLSDebugHandshake(tls+5,sz-5);
|
||||
}
|
||||
|
||||
bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname)
|
||||
bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname, bool hostname_is_ip)
|
||||
{
|
||||
if (!params.cache_hostname) return true;
|
||||
|
||||
@@ -109,11 +109,12 @@ bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, c
|
||||
DLOG_ERR("ipcache_put_hostname: out of memory\n");
|
||||
return false;
|
||||
}
|
||||
VPRINT("hostname cached: %s\n", hostname);
|
||||
ipc->hostname_is_ip = hostname_is_ip;
|
||||
VPRINT("hostname cached (is_ip=%u): %s\n", hostname_is_ip, hostname);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len)
|
||||
static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr *a6, char *hostname, size_t hostname_buf_len, bool *hostname_is_ip)
|
||||
{
|
||||
if (!params.cache_hostname)
|
||||
{
|
||||
@@ -128,15 +129,16 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
}
|
||||
if (ipc->hostname)
|
||||
{
|
||||
VPRINT("got cached hostname: %s\n", ipc->hostname);
|
||||
VPRINT("got cached hostname (is_ip=%u): %s\n", ipc->hostname_is_ip, ipc->hostname);
|
||||
snprintf(hostname,hostname_buf_len,"%s",ipc->hostname);
|
||||
if (hostname_is_ip) *hostname_is_ip = ipc->hostname_is_ip;
|
||||
}
|
||||
else
|
||||
*hostname = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto)
|
||||
static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto)
|
||||
{
|
||||
bool bHostlistsEmpty;
|
||||
|
||||
@@ -167,11 +169,11 @@ static bool dp_match(struct desync_profile *dp, const struct sockaddr *dest, con
|
||||
return true;
|
||||
else if (hostname)
|
||||
// if hostlists are present profile matches only if hostname is known and satisfy profile hostlists
|
||||
return HostlistCheck(dp, hostname, NULL, true);
|
||||
return HostlistCheck(dp, hostname, bNoSubdom, NULL, true);
|
||||
|
||||
return false;
|
||||
}
|
||||
static struct desync_profile *dp_find(struct desync_profile_list_head *head, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto)
|
||||
static struct desync_profile *dp_find(struct desync_profile_list_head *head, const struct sockaddr *dest, const char *hostname, bool bNoSubdom, t_l7proto l7proto)
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
if (params.debug)
|
||||
@@ -182,7 +184,7 @@ static struct desync_profile *dp_find(struct desync_profile_list_head *head, con
|
||||
}
|
||||
LIST_FOREACH(dpl, head, next)
|
||||
{
|
||||
if (dp_match(&dpl->dp,dest,hostname,l7proto))
|
||||
if (dp_match(&dpl->dp,dest,hostname,bNoSubdom,l7proto))
|
||||
{
|
||||
VPRINT("desync profile %d matches\n",dpl->dp.n);
|
||||
return &dpl->dp;
|
||||
@@ -198,11 +200,11 @@ void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest)
|
||||
if (!ctrack->hostname)
|
||||
{
|
||||
char host[256];
|
||||
if (ipcache_get_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , host, sizeof(host)) && *host)
|
||||
if (ipcache_get_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , host, sizeof(host), &ctrack->hostname_is_ip) && *host)
|
||||
if (!(ctrack->hostname=strdup(host)))
|
||||
DLOG_ERR("hostname dup : out of memory");
|
||||
}
|
||||
ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->l7proto);
|
||||
ctrack->dp = dp_find(¶ms.desync_profiles, dest, ctrack->hostname, ctrack->hostname_is_ip, ctrack->l7proto);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +215,7 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
|
||||
uint8_t *p, *pp, *pHost = NULL;
|
||||
size_t method_len = 0, pos, tpos, orig_size=*size;
|
||||
const char *method;
|
||||
bool bHaveHost = false;
|
||||
bool bHaveHost = false, bHostIsIp = false;
|
||||
char *pc, Host[256];
|
||||
t_l7proto l7proto;
|
||||
|
||||
@@ -271,8 +273,9 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
|
||||
|
||||
if (bHaveHost)
|
||||
{
|
||||
bHostIsIp = strip_host_to_ip(Host);
|
||||
VPRINT("request hostname: %s\n", Host);
|
||||
if (!ipcache_put_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , Host))
|
||||
if (!ipcache_put_hostname(dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL , Host, bHostIsIp))
|
||||
DLOG_ERR("ipcache_put_hostname: out of memory");
|
||||
}
|
||||
|
||||
@@ -293,6 +296,7 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
|
||||
DLOG_ERR("strdup hostname : out of memory\n");
|
||||
return;
|
||||
}
|
||||
ctrack->hostname_is_ip = bHostIsIp;
|
||||
ctrack->hostname_discovered = true;
|
||||
}
|
||||
|
||||
@@ -312,7 +316,7 @@ void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,
|
||||
if (bHaveHost && !ctrack->b_host_checked)
|
||||
{
|
||||
bool bHostExcluded;
|
||||
ctrack->b_host_matches = HostlistCheck(ctrack->dp, Host, &bHostExcluded, false);
|
||||
ctrack->b_host_matches = HostlistCheck(ctrack->dp, Host, bHostIsIp, &bHostExcluded, false);
|
||||
ctrack->b_host_checked = true;
|
||||
if (!ctrack->b_host_matches)
|
||||
ctrack->b_ah_check = !bHostExcluded;
|
||||
@@ -542,7 +546,7 @@ static void auto_hostlist_reset_fail_counter(struct desync_profile *dp, const ch
|
||||
}
|
||||
}
|
||||
|
||||
static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname, const char *client_ip_port, t_l7proto l7proto)
|
||||
static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname, bool bNoSubdom, const char *client_ip_port, t_l7proto l7proto)
|
||||
{
|
||||
hostfail_pool *fail_counter;
|
||||
|
||||
@@ -566,7 +570,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
|
||||
|
||||
VPRINT("auto hostlist (profile %d) : rechecking %s to avoid duplicates\n", dp->n, hostname);
|
||||
bool bExcluded=false;
|
||||
if (!HostlistCheck(dp, hostname, &bExcluded, false) && !bExcluded)
|
||||
if (!HostlistCheck(dp, hostname, bNoSubdom, &bExcluded, false) && !bExcluded)
|
||||
{
|
||||
VPRINT("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename);
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename);
|
||||
@@ -626,7 +630,7 @@ void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t *segment
|
||||
// received not http reply. do not monitor this connection anymore
|
||||
VPRINT("incoming unknown HTTP data detected for hostname %s\n", ctrack->hostname);
|
||||
}
|
||||
if (bFail) auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto);
|
||||
if (bFail) auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto);
|
||||
}
|
||||
if (!bFail) auto_hostlist_reset_fail_counter(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto);
|
||||
}
|
||||
@@ -651,7 +655,7 @@ void rst_in(t_ctrack *ctrack, const struct sockaddr *client)
|
||||
{
|
||||
VPRINT("incoming RST detected for hostname %s\n", ctrack->hostname);
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : incoming RST", ctrack->hostname, ctrack->dp->n, client_ip_port, l7proto_str(ctrack->l7proto));
|
||||
auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto);
|
||||
auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -674,7 +678,7 @@ void hup_out(t_ctrack *ctrack, const struct sockaddr *client)
|
||||
// local leg dropped connection after first request. probably due to timeout.
|
||||
VPRINT("local leg closed connection after first request (timeout ?). hostname: %s\n", ctrack->hostname);
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : client closed connection without server reply", ctrack->hostname, ctrack->dp->n, client_ip_port, l7proto_str(ctrack->l7proto));
|
||||
auto_hostlist_failed(ctrack->dp, ctrack->hostname, client_ip_port, ctrack->l7proto);
|
||||
auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,13 @@ typedef struct
|
||||
bool bTamperInCutoff;
|
||||
bool b_host_checked,b_host_matches,b_ah_check;
|
||||
bool hostname_discovered;
|
||||
bool hostname_is_ip;
|
||||
char *hostname;
|
||||
struct desync_profile *dp; // desync profile cache
|
||||
} t_ctrack;
|
||||
|
||||
void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest);
|
||||
bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname);
|
||||
bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname, bool hostname_is_ip);
|
||||
|
||||
void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *segment,size_t segment_buffer_size,size_t *size, size_t *multisplit_pos, int *multisplit_count, uint8_t *split_flags);
|
||||
void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t *segment,size_t segment_buffer_size,size_t *size);
|
||||
|
||||
@@ -495,7 +495,7 @@ static bool connect_remote_conn(tproxy_conn_t *conn)
|
||||
int mss=0;
|
||||
|
||||
if (conn->track.hostname)
|
||||
if (!ipcache_put_hostname(conn->dest.sa_family==AF_INET ? &((struct sockaddr_in*)&conn->dest)->sin_addr : NULL, conn->dest.sa_family==AF_INET6 ? &((struct sockaddr_in6*)&conn->dest)->sin6_addr : NULL , conn->track.hostname))
|
||||
if (!ipcache_put_hostname(conn->dest.sa_family==AF_INET ? &((struct sockaddr_in*)&conn->dest)->sin_addr : NULL, conn->dest.sa_family==AF_INET6 ? &((struct sockaddr_in6*)&conn->dest)->sin6_addr : NULL , conn->track.hostname, conn->track.hostname_is_ip))
|
||||
DLOG_ERR("ipcache_put_hostname: out of memory");
|
||||
apply_desync_profile(&conn->track, (struct sockaddr *)&conn->dest);
|
||||
|
||||
@@ -507,7 +507,7 @@ static bool connect_remote_conn(tproxy_conn_t *conn)
|
||||
if (conn->track.hostname)
|
||||
{
|
||||
bool bHostExcluded;
|
||||
conn->track.b_host_matches = HostlistCheck(conn->track.dp, conn->track.hostname, &bHostExcluded, false);
|
||||
conn->track.b_host_matches = HostlistCheck(conn->track.dp, conn->track.hostname, conn->track.hostname_is_ip, &bHostExcluded, false);
|
||||
conn->track.b_host_checked = true;
|
||||
if (!conn->track.b_host_matches)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user