mirror of
https://github.com/bol-van/zapret.git
synced 2025-08-10 01:02:03 +03:00
Compare commits
34 Commits
729ded0c61
...
v71
Author | SHA1 | Date | |
---|---|---|---|
|
20f91cb7ab | ||
|
4becc07572 | ||
|
a39c18737b | ||
|
ed7b743fe2 | ||
|
d3b0b3e0b1 | ||
|
ba040769a7 | ||
|
0ced50e393 | ||
|
f3abd6815a | ||
|
4572799750 | ||
|
696167509a | ||
|
2374df6d74 | ||
|
ab06d6b640 | ||
|
60efab1cc6 | ||
|
71aebbb4d3 | ||
|
c993f117a2 | ||
|
b2f0c46388 | ||
|
2b095f863f | ||
|
a141dff374 | ||
|
b34bfda8b5 | ||
|
c1046a20db | ||
|
24b93cca7e | ||
|
4f0fdb24f2 | ||
|
6d52b49b98 | ||
|
4b632313e2 | ||
|
22f3ecaec1 | ||
|
2a23bc99f6 | ||
|
8a1d7c7abd | ||
|
ba712f308d | ||
|
9ace0328ad | ||
|
5c6f79799a | ||
|
a84d015b1e | ||
|
2d90a28dbc | ||
|
3c77bab002 | ||
|
8f27725d6a |
@@ -1042,6 +1042,7 @@ curl_test()
|
||||
}
|
||||
ws_curl_test()
|
||||
{
|
||||
|
||||
# $1 - ws start function
|
||||
# $2 - test function
|
||||
# $3 - domain
|
||||
@@ -1061,7 +1062,7 @@ tpws_curl_test()
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
# $3,$4,$5, ... - tpws params
|
||||
echo - checking tpws $3 $4 $5 $6 $7 $8 $9${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||
echo - $1 $2 : tpws $3 $4 $5 $6 $7 $8 $9${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||
local ALL_PROXY="socks5://127.0.0.1:$SOCKS_PORT"
|
||||
ws_curl_test tpws_start "$@"${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||
local testf=$1 dom=$2 strategy code=$?
|
||||
@@ -1078,11 +1079,14 @@ pktws_curl_test()
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
# $3,$4,$5, ... - nfqws/dvtws params
|
||||
echo - checking $PKTWSD ${WF:+$WF }$3 $4 $5 $6 $7 $8 $9${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
ws_curl_test pktws_start "$@"${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
local testf=$1 dom=$2 strategy code=$?
|
||||
local testf=$1 dom=$2 strategy code
|
||||
|
||||
shift; shift;
|
||||
echo - $testf $dom : $PKTWSD ${WF:+$WF }${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }$@${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
ws_curl_test pktws_start $testf $dom ${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }"$@"${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
|
||||
code=$?
|
||||
[ "$code" = 0 ] && {
|
||||
shift; shift;
|
||||
strategy="$@"
|
||||
strategy_append_extra_pktws
|
||||
report_append "ipv${IPV} $dom $testf : $PKTWSD ${WF:+$WF }$strategy"
|
||||
@@ -1092,11 +1096,11 @@ pktws_curl_test()
|
||||
|
||||
strategy_append_extra_pktws()
|
||||
{
|
||||
strategy="${strategy:+$strategy${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}}"
|
||||
strategy="${strategy:+${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }$strategy${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}}"
|
||||
}
|
||||
strategy_append_extra_tpws()
|
||||
{
|
||||
strategy="${strategy:+$strategy${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}}"
|
||||
strategy="${strategy:+${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }$strategy${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}}"
|
||||
}
|
||||
|
||||
xxxws_curl_test_update()
|
||||
@@ -1189,15 +1193,19 @@ pktws_curl_test_update_vary()
|
||||
# $4 - desync mode
|
||||
# $5,$6,... - strategy
|
||||
|
||||
local testf=$1 sec=$2 domain=$3 desync=$4 proto zerofake= tlsmod= splits= pos fake ret=1
|
||||
local testf=$1 sec=$2 domain=$3 desync=$4 proto splits= pos fake ret=1
|
||||
local fake1=- fake2=- fake3=-
|
||||
|
||||
shift; shift; shift; shift
|
||||
|
||||
proto=http
|
||||
[ "$sec" = 0 ] || proto=tls
|
||||
test_has_fake $desync && {
|
||||
zerofake="--dpi-desync-fake-$proto=0x00000000"
|
||||
[ "$sec" = 0 ] || tlsmod="--dpi-desync-fake-tls-mod=rnd,dupsid,rndsni,padencap"
|
||||
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"
|
||||
}
|
||||
}
|
||||
if test_has_fakedsplit $desync ; then
|
||||
splits="method+2 midsld"
|
||||
@@ -1206,7 +1214,8 @@ pktws_curl_test_update_vary()
|
||||
splits="method+2 midsld"
|
||||
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
|
||||
fi
|
||||
for fake in '' $zerofake $tlsmod ; do
|
||||
for fake in '' "$fake1" "$fake2" "$fake3" ; do
|
||||
[ "$fake" = "-" ] && continue
|
||||
if [ -n "$splits" ]; then
|
||||
for pos in $splits ; do
|
||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" --dpi-desync-split-pos=$pos $fake && {
|
||||
@@ -1231,14 +1240,14 @@ pktws_check_domain_http_bypass_()
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local ok ttls s f f2 e desync pos fooling frag sec="$2" delta splits
|
||||
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 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'
|
||||
|
||||
[ "$sec" = 0 ] && {
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase' '--methodeol'; do
|
||||
pktws_curl_test_update $1 $3 $s
|
||||
pktws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
}
|
||||
|
||||
@@ -1303,10 +1312,21 @@ pktws_check_domain_http_bypass_()
|
||||
f="$f badseq datanoack md5sig"
|
||||
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
|
||||
for fooling in $f; do
|
||||
ok=0
|
||||
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" = 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 && {
|
||||
warn_fool $fooling $desync
|
||||
echo "HINT ! To avoid possible 1 sec server response delay use --dup-ttl or --dup-autottl and block ICMP time exceeded"
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
}
|
||||
done
|
||||
done
|
||||
@@ -1369,8 +1389,11 @@ pktws_check_domain_http_bypass_()
|
||||
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
|
||||
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
|
||||
ok=0
|
||||
for delta in 1 2 3 4 5; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=1 --dpi-desync-autottl=$delta $e && ok=1
|
||||
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 ] &&
|
||||
{
|
||||
@@ -1415,13 +1438,15 @@ pktws_check_domain_http3_bypass_()
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
|
||||
local f desync frag tests rep
|
||||
local f desync frag tests rep fake
|
||||
|
||||
for rep in '' 2 5 10 20; do
|
||||
pktws_curl_test_update $1 $2 --dpi-desync=fake ${rep:+--dpi-desync-repeats=$rep} && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
for fake in '' "--dpi-desync-fake-quic=$ZAPRET_BASE/files/fake/quic_initial_www_google_com.bin"; do
|
||||
for rep in '' 2 5 10 20; do
|
||||
pktws_curl_test_update $1 $2 --dpi-desync=fake ${fake:+$fake }${rep:+--dpi-desync-repeats=$rep} && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
done
|
||||
|
||||
[ "$IPV" = 6 ] && {
|
||||
|
@@ -490,8 +490,15 @@ nfqws: --dup*
|
||||
nfqws: --orig*
|
||||
nfqws: ipcache of hop count and host names
|
||||
nfqws: --ctrack-disable
|
||||
nfqws: --synack-split
|
||||
nfqws: --autottl=- or --autottl=0:0-0 disable autottl. previous "0" does not work anymore.
|
||||
tpws: ipcache of host names
|
||||
nfqws,tpws: set 1024 repeat limit to fakes and dups
|
||||
nfqws,tpws: do more before daemonize
|
||||
nfqws,tpws: accept multiple gids in --gid
|
||||
nfqws,tpws: display "android" in version string if built for android
|
||||
init.d: remove --ipset parameter prohibition
|
||||
init.d, blockcheck: drop time exceeded icmp for nfqws-related connections
|
||||
blockcheck: some dup and orig-ttl mods
|
||||
blockcheck: PKTWS_EXTRA_PRE
|
||||
blockcheck: report test function and domain every test
|
||||
|
@@ -1,9 +1,10 @@
|
||||
# zapret v70.7
|
||||
# zapret v71
|
||||
|
||||
# SCAMMER WARNING
|
||||
|
||||
This software is free and open source under [MIT license](./LICENSE.txt).
|
||||
If anyone demands you to download this software only from their webpage, telegram channel, forces you to delete links, videos, makes copyright claims, you are dealing with scammers.
|
||||
However, [donations](#donations) are welcome.
|
||||
|
||||
# Multilanguage/Мультиязычный README
|
||||
___
|
||||
@@ -23,9 +24,12 @@ ___
|
||||
- [TCP segmentation](#tcp-segmentation)
|
||||
- [Sequence numbers overlap](#sequence-numbers-overlap)
|
||||
- [ipv6 specific modes](#ipv6-specific-modes)
|
||||
- [Original modding](#original-modding)
|
||||
- [Duplicates](#duplicates)
|
||||
- [Server reply reaction](#server-reply-reaction)
|
||||
- [SYNDATA mode](#syndata-mode)
|
||||
- [DPI desync combos](#dpi-desync-combos)
|
||||
- [IP cache](#ip-cache)
|
||||
- [CONNTRACK](#conntrack)
|
||||
- [Reassemble](#reassemble)
|
||||
- [UDP support](#udp-support)
|
||||
@@ -34,6 +38,8 @@ ___
|
||||
- [Virtual machines](#virtual-machines)
|
||||
- [IPTABLES for nfqws](#iptables-for-nfqws)
|
||||
- [NFTABLES for nfqws](#nftables-for-nfqws)
|
||||
- [Flow offloading](#flow-offloading)
|
||||
- [Server side fooling](#server-side-fooling)
|
||||
- [tpws](#tpws)
|
||||
- [TCP segmentation in tpws](#tcp-segmentation-in-tpws)
|
||||
- [TLSREC](#tlsrec)
|
||||
@@ -139,24 +145,45 @@ nfqws takes the following parameters:
|
||||
--daemon ; daemonize
|
||||
--pidfile=<filename> ; write pid to file
|
||||
--user=<username> ; drop root privs
|
||||
--uid=uid[:gid] ; 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
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for ipv6 only
|
||||
--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 ?)
|
||||
@@ -257,10 +284,13 @@ 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).
|
||||
* **autottl** tries to automatically guess TTL value that allows DPI to receive fakes and does not allow them to reach the server.
|
||||
This tech relies on well known TTL values used by OS : 64,128,255. nfqws takes first incoming packet (YES, you need to redirect it too),
|
||||
guesses path length and decreases by `delta` value (default 1). If resulting value is outside the range (min,max - default 3,20)
|
||||
then its normalized to min or max. If the path shorter than the value then autottl fails and falls back to the fixed value.
|
||||
* **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.
|
||||
nfqws needs first incoming packet to see it's TTL. You must redirect it too.
|
||||
If resulting value TTL is outside the range (min,max) then its normalized to min or max.
|
||||
If delta is negative and TTL is longer than guessed hop count or delta is positive and TTL is shorter than guessed hop count
|
||||
then autottl fails and falls back to the fixed value.
|
||||
This can help if multiple DPIs exists on backbone channels, not just near the ISP.
|
||||
Can fail if inbound and outbound paths are not symmetric.
|
||||
|
||||
@@ -356,6 +386,44 @@ For example, `hopbyhop,multisplit` means split original tcp packet into several
|
||||
With `hopbyhop,ipfrag2` header sequence will be : `ipv6,hop-by-hop,fragment,tcp/udp`.
|
||||
`ipfrag1` mode may not always work without special preparations. See "IP Fragmentation" notices.
|
||||
|
||||
### Original modding
|
||||
|
||||
Parameters `--orig-ttl` and `--orig-ttl6` allow to set TTL on original packets.
|
||||
All further packet manipulations, e.g. segmentation, take modded original as data source and inherit modded TTL.
|
||||
|
||||
`--orig-autottl` and `--orig-autottl6` work the same way as `dpi-desync-autottl`, but on original packets.
|
||||
Delta should have unary `+` sign to produce TTL longer than guessed hop count. Otherwise nothing will reach the server.
|
||||
Example : `--orig-autottl=+5:3-64`.
|
||||
|
||||
`--orig-mod-start` and `--orig-mod-cutoff` specify start and end conditions for original modding. The work the same way as
|
||||
`--dpi-desync-start` and `--dpi-desync-cutoff`.
|
||||
|
||||
This function can be useful when DPI hunts for fakes and blocks suspicious connections.
|
||||
DPI can compute TTL difference between packets and fire block trigger if it exceedes some threshold.
|
||||
|
||||
### Duplicates
|
||||
|
||||
Duplicates are copies of original packets which are sent before them. Duplicates are enabled by `--dup=N`, where N is dup count.
|
||||
`--dup-replace` disables sending of original.
|
||||
|
||||
Dups are sent only when original would also be sent without reconstruction.
|
||||
For example, if TCP segmentation happens, original is actually dropped and is being replaced by artificially constructed new packets.
|
||||
Dups are not sent in this case.
|
||||
|
||||
All dup fooling modes are available : `--dup-ttl`. `--dup-ttl6`, `--dup-fooling`.
|
||||
You decide whether these packets need to reach the server and in what form, according to the intended strategy.
|
||||
|
||||
`--dup-autottl` and `--dup-autottl6` work the same way as `dpi-desync-autottl`.
|
||||
Delta can be preceeded by unary `+` or `-` sign.
|
||||
Example : `--dup-autottl=-2:3-64`.
|
||||
|
||||
`--dup-start` and `--dup-cutoff` specify start and end conditions for dupping. The work the same way as
|
||||
`--dpi-desync-start` and `--dpi-desync-cutoff`.
|
||||
|
||||
This function can help if DPI compares some characteristics of fake and original packets and block connection if they differ some way.
|
||||
Fooled duplicates can convince DPI that the whole session has an anomaly.
|
||||
For example, all connection is protected by MD5 signature, not individual packets.
|
||||
|
||||
### Server reply reaction
|
||||
|
||||
There are DPIs that analyze responses from the server, particularly the certificate from the ServerHello that contain domain name(s). The ClientHello delivery confirmation is an ACK packet from the server with ACK sequence number corresponding to the length of the ClientHello+1.
|
||||
@@ -377,12 +445,26 @@ Without extra parameter payload is 16 zero bytes.
|
||||
|
||||
`--dpi-desync` takes up to 3 comma separated modes.
|
||||
|
||||
* 0 phase modes work during the connection establishement : `synack`, `syndata` `--wsize`, `--wssize`. [hostlist](((#multiple-strategies))) filters are not applicable.
|
||||
* 0 phase modes work during the connection establishement : `synack`, `syndata` `--wsize`, `--wssize`. [hostlist](#multiple-strategies) filters are applicable only if [`--ipcache-hostname`](#ip-cache) is enabled.
|
||||
* In the 1st phase fakes are sent before original data : `fake`, `rst`, `rstack`.
|
||||
* In the 2nd phase original data is sent in a modified way (for example `fakedsplit` or `ipfrag2`).
|
||||
|
||||
Modes must be specified in phase ascending order.
|
||||
|
||||
### IP cache
|
||||
|
||||
`ipcache` is the structure in the process memory that stores some information by IP address and interface name key.
|
||||
This information can be used as missing data. Currently it's used in the following cases :
|
||||
|
||||
1. IP,interface => hop count . This is used to apply autottl at 0 phase since the first session packet. If the record is absent autottl will not be applied immediately. Second time it will be applied immediately using cached hop count.
|
||||
|
||||
2. IP => hostname . Hostname is cached to be used in 0 phase strategies. Mode is disabled by default and can be enabled by `ipcache-hostname` parameter.
|
||||
This tech is experimental. There's no one-to-one correspondence between IP and domain name. Multiple domains can resolve to the same IP.
|
||||
If collision happens hostname is replaced. On CDNs a domain can resolve to different IPs over time. `--ipcache-lifetime` limits how long cached record is valid. It's 2 hours by default.
|
||||
Be prepared for unexpected results that can be explained only by reading debug logs.
|
||||
|
||||
SIGUSR2 forces process to output it's ipcache to stdout.
|
||||
|
||||
### CONNTRACK
|
||||
|
||||
nfqws is equipped with minimalistic connection tracking system (conntrack)
|
||||
@@ -669,6 +751,31 @@ In `iptables` flow offloading is controlled by openwrt proprietary extension `FL
|
||||
|
||||
Flow offloading does not interfere with **tpws** and `OUTPUT` traffic. It only breaks nfqws that fools `FORWARD` traffic.
|
||||
|
||||
### Server side fooling
|
||||
|
||||
It's also possible.
|
||||
nfqws is intended for client side attacks. That's why it recognizes direct and reply traffic based on role in connection establishement.
|
||||
If it sees SYN then source IP is client IP. If it sees SYN,ACK then source ip is server IP.
|
||||
For UDP client address is considered as source IP of the first seen packet of src_ip,src_port,dst_ip,dst_port tuple.
|
||||
|
||||
This does not work correctly on the server side. Client traffic is reply traffic, server traffic is direct traffic.
|
||||
|
||||
`--wsize` works in any case. It can be used on both client and server.
|
||||
Other techs work only if nfqws treats traffic as direct traffic.
|
||||
To apply them to server originated traffic disable conntrack by `--ctrack-disable` parameter.
|
||||
If a packet is not found in conntrack it's treated as direct and techs like `multidisorder` will be applied.
|
||||
|
||||
Most of the protocols will not be recognized because protocol recognition system only reacts to client packets.
|
||||
To make things working use `--dpi-desync-any-protocol` with connbytes or packet payload limiter.
|
||||
start/cutoff are unavailable because they are conntrack based.
|
||||
|
||||
`--synack-split` removes standard SYN,ACK packet and replaces it with one SYN packet, SYN then ACK separate packets or ACK then SYN separate packets.
|
||||
Client sends SYN,ACK in reply which usually only server does.
|
||||
This makes some DPI's to treat connection establishement roles wrong. They stop to block.
|
||||
See [split handshake](https://nmap.org/misc/split-handshake.pdf).
|
||||
|
||||
On server side traffic should be redirected to nfqws using source port numbers and original connbytes direction.
|
||||
|
||||
|
||||
## tpws
|
||||
|
||||
@@ -705,6 +812,8 @@ tpws is transparent proxy.
|
||||
--local-tcp-user-timeout=<seconds> ; set tcp user timeout for local leg (default : 10, 0 = system default)
|
||||
--remote-tcp-user-timeout=<seconds> ; set tcp user timeout for remote leg (default : 20, 0 = system default)
|
||||
--fix-seg=<int> ; recover failed TCP segmentation at the cost of slowdown. wait up to N msec.
|
||||
--ipcache-lifetime=<int> ; time in seconds to keep cached domain name (default 7200). 0 = no expiration
|
||||
--ipcache-hostname=[0|1] ; 1 or no argument enables ip->hostname caching
|
||||
--no-resolve ; disable socks5 remote dns
|
||||
--resolver-threads=<int> ; number of resolver worker threads
|
||||
--maxconn=<max_connections> ; max number of local legs
|
||||
@@ -755,7 +864,7 @@ tpws is transparent proxy.
|
||||
--daemon ; daemonize
|
||||
--pidfile=<filename> ; write pid to file
|
||||
--user=<username> ; drop root privs
|
||||
--uid=uid[:gid] ; drop root privs
|
||||
--uid=uid[:gid1,gid2,...] ; drop root privs
|
||||
```
|
||||
|
||||
### TCP segmentation in tpws
|
||||
@@ -789,7 +898,7 @@ If you're attempting to split massive transmission with `--split-any-protocol` o
|
||||
`--mss` sets TCP_MAXSEG socket option. Client sets this value in MSS TCP option in the SYN packet.
|
||||
Server replies with it's own MSS in SYN,ACK packet. Usually servers lower their packet sizes but they still don't fit to supplied MSS. The greater MSS client sets the bigger server's packets will be.
|
||||
If it's enough to split TLS 1.2 ServerHello, it may fool DPI that checks certificate domain name.
|
||||
This scheme may significantly lower speed. Hostlist filter is possible only in socks mode if client uses remote resolving (firefox `network.proxy.socks_remote_dns`).
|
||||
This scheme may significantly lower speed. Hostlist filter is possible only in socks mode if client uses remote resolving (firefox `network.proxy.socks_remote_dns`) or if `ipcache-hostname` is enabled.
|
||||
`--mss` is not required for TLS1.3. If TLS1.3 is negotiable then MSS make things only worse. Use only if nothing better is available. Works only in Linux, not BSD or MacOS.
|
||||
|
||||
### Other tamper options
|
||||
@@ -1270,6 +1379,10 @@ With other values or if the parameter is commented out, the rules will not be ap
|
||||
This is useful if you have a firewall management system, in the settings of which you should tie the rules.
|
||||
Not applicable to `OpenWRT` if used with `firewall3+iptables`.
|
||||
|
||||
`FILTER_TTL_EXPIRED_ICMP=1` blocks icmp time exceeded messages in response to connections handled by nfqws.
|
||||
Linux closes socket if it receives this icmp in response to SYN packet. Similar mechanism exists for datagram sockets.
|
||||
It's better to disable this if you do not expect problems caused by icmp.
|
||||
|
||||
The following settings are not relevant for openwrt :
|
||||
|
||||
If your system works as a router, then you need to enter the names of the internal and external interfaces:
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
zapret является свободным и open source.
|
||||
Всякий, кто понуждает вас скачивать zapret только с его ресурса, требует удалить ссылки, видео, файлы, обосновывая эти требования авторскими правами, сам нарушает [лицензию](./LICENSE.txt).
|
||||
Однако, это не исключает [добровольные пожертвования](#поддержать-разработчика).
|
||||
|
||||
# Multilanguage README
|
||||
|
||||
@@ -41,6 +42,7 @@ zapret является свободным и open source.
|
||||
- [IPTABLES ДЛЯ NFQWS](#iptables-для-nfqws)
|
||||
- [NFTABLES ДЛЯ NFQWS](#nftables-для-nfqws)
|
||||
- [FLOW OFFLOADING](#flow-offloading)
|
||||
- [ДУРЕНИЕ СО СТОРОНЫ СЕРВЕРА](#дурение-со-стороны-сервера)
|
||||
- [tpws](#tpws)
|
||||
- [TCP СЕГМЕНТАЦИЯ В TPWS](#tcp-сегментация-в-tpws)
|
||||
- [TLSREC](#tlsrec)
|
||||
@@ -179,18 +181,19 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
--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. delta=0 отключает функцию
|
||||
--orig-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
|
||||
--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. delta=0 отключает функцию
|
||||
--dup-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
|
||||
--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
|
||||
@@ -205,8 +208,8 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
--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. delta=0 отключает функцию.
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; переопределение предыдущего параметра для ipv6
|
||||
--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
|
||||
@@ -884,6 +887,32 @@ iptables target `FLOWOFFLOAD` - это проприетарное изобрет
|
||||
Управление offload в nftables реализовано в базовом ядре linux без патчей.
|
||||
nftables - единственный способ включения offload на классическом Linux.
|
||||
|
||||
### ДУРЕНИЕ СО СТОРОНЫ СЕРВЕРА
|
||||
|
||||
Это тоже возможно.
|
||||
nfqws рассчитан на атаку со стороны клиента, поэтому он распознает прямой и обратный трафик на основании роли в установлении tcp соединения.
|
||||
Если проходит SYN, то source IP - это клиент. Если проходит SYN,ACK , то source IP - это сервер.
|
||||
Для UDP клиентом считается source IP первого прошедшего пакета по двум связкам ip-port.
|
||||
На сервере трафиком клиента будет считаться принятый трафик, а трафиком сервера - исходящий.
|
||||
|
||||
`--wsize` работает в любом случае, он может использоваться как на клиенте, так и на сервере.
|
||||
Остальные техники работают только если nfqws считает трафик трафиком клиента.
|
||||
Поэтому для их применения по исходящему с сервера трафику conntrack нужно выключить параметром `--ctrack-disable`.
|
||||
Если пакет не найден в conntrack, по нему идет работа как по пакету клиента.
|
||||
|
||||
Большинство протоколов опознаваться не будет, потому что система их опознавания рассчитана на содержание пакетов от клиента.
|
||||
Чтобы задействовать техники типа `fake` или `multisplit` нужно использовать `--dpi-desync-any-protocol` с ограничителем connbytes или
|
||||
с ограничителем на основании содержания пакета или его заголовков.
|
||||
start/cutoff недоступны, поскольку завязаны на conntrack.
|
||||
|
||||
Техника `synack-split` позволяет разбить tcp сегмент SYN,ACK на отдельные части с SYN и с ACK.
|
||||
В ответ на это клиент шлет SYN,ACK , что обычно характеризует сервер.
|
||||
У некоторых DPI от этого может ломаться алгоритм, и они перестают блокировать запрещенный контент.
|
||||
Здесь [подробное описание](https://nmap.org/misc/split-handshake.pdf) что есть split handshake.
|
||||
|
||||
Перенаправление трафика обычно идет по номеру source портов и направлению original.
|
||||
original - это исходящий с системы трафик, reply - входящий.
|
||||
|
||||
|
||||
## tpws
|
||||
|
||||
@@ -1592,8 +1621,10 @@ SKIP_DNSCHECK=1 - отказ от проверки DNS
|
||||
SKIP_IPBLOCK=1 - отказ от тестов блокировки по порту или IP
|
||||
SKIP_TPWS=1 - отказ от тестов tpws
|
||||
SKIP_PKTWS=1 - отказ от тестов nfqws/dvtws/winws
|
||||
PKTWS_EXTRA, TPWS_EXTRA - дополнительные параметры nfqws/dvtws/winws и tpws
|
||||
PKTWS_EXTRA, TPWS_EXTRA - дополнительные параметры nfqws/dvtws/winws и tpws, указываемые после основной стратегии
|
||||
PKTWS_EXTRA_1 .. PKTWS_EXTRA_9, TPWS_EXTRA_1 .. TPWS_EXTRA_9 - отдельно дополнительные параметры, содержащие пробелы
|
||||
PKTWS_EXTRA_PRE - дополнительные параметры для nfqws/dvtws/winws, указываемые перед основной стратегией
|
||||
PKTWS_EXTRA_PRE_1 .. PKTWS_EXTRA_PRE_9 - отдельно дополнительные параметры, содержащие пробелы
|
||||
SECURE_DNS=0|1 - принудительно выключить или включить DoH
|
||||
DOH_SERVERS - список URL DoH через пробел для автоматического выбора работающего сервера
|
||||
DOH_SERVER - конкретный DoH URL, отказ от поиска
|
||||
|
@@ -261,7 +261,7 @@ typedef struct
|
||||
int8_t delta;
|
||||
uint8_t min, max;
|
||||
} autottl;
|
||||
#define AUTOTTL_ENABLED(a) (!!(a).delta)
|
||||
#define AUTOTTL_ENABLED(a) ((a).delta || (a).min || (a).max)
|
||||
|
||||
uint8_t hop_count_guess(uint8_t ttl);
|
||||
uint8_t autottl_eval(uint8_t hop_count, const autottl *attl);
|
||||
|
77
nfq/desync.c
77
nfq/desync.c
@@ -1110,6 +1110,9 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
uint32_t desync_fwmark = fwmark | params.desync_fwmark;
|
||||
extract_endpoints(dis->ip, dis->ip6, dis->tcp, NULL, &src, &dst);
|
||||
timestamps = tcp_find_timestamps(dis->tcp);
|
||||
DF = ip_has_df(dis->ip);
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
|
||||
if (replay)
|
||||
{
|
||||
@@ -1185,23 +1188,28 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
//ConntrackPoolDump(¶ms.conntrack);
|
||||
|
||||
if (dp->wsize && tcp_synack_segment(dis->tcp))
|
||||
if (tcp_synack_segment(dis->tcp))
|
||||
{
|
||||
tcp_rewrite_winsize(dis->tcp, dp->wsize, dp->wscale);
|
||||
verdict=VERDICT_MODIFY;
|
||||
if (dp->wsize)
|
||||
{
|
||||
tcp_rewrite_winsize(dis->tcp, dp->wsize, dp->wscale);
|
||||
verdict=VERDICT_MODIFY;
|
||||
}
|
||||
if (dp->synack_split==SS_SYN)
|
||||
{
|
||||
DLOG("split SYNACK : clearing ACK bit\n");
|
||||
dis->tcp->th_flags &= ~TH_ACK;
|
||||
verdict=VERDICT_MODIFY;
|
||||
}
|
||||
}
|
||||
|
||||
if (bReverse)
|
||||
{
|
||||
if (ctrack)
|
||||
if (ctrack && !ctrack->incoming_ttl)
|
||||
{
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
if (!ctrack->incoming_ttl)
|
||||
{
|
||||
ctrack->incoming_ttl = ttl_orig;
|
||||
DLOG("incoming TTL %u\n",ttl_orig);
|
||||
autottl_rediscover(ctrack,dis->ip ? &dis->ip->ip_src : NULL,dis->ip6 ? &dis->ip6->ip6_src : NULL , ifin);
|
||||
}
|
||||
ctrack->incoming_ttl = ttl_orig;
|
||||
DLOG("incoming TTL %u\n",ttl_orig);
|
||||
autottl_rediscover(ctrack,dis->ip ? &dis->ip->ip_src : NULL,dis->ip6 ? &dis->ip6->ip6_src : NULL , ifin);
|
||||
}
|
||||
|
||||
// process reply packets for auto hostlist mode
|
||||
@@ -1281,6 +1289,51 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
}
|
||||
|
||||
if ((dp->synack_split==SS_SYNACK || dp->synack_split==SS_ACKSYN) && tcp_synack_segment(dis->tcp))
|
||||
{
|
||||
// reconstruct required
|
||||
|
||||
dis->tcp->th_flags &= ~TH_ACK;
|
||||
tcp_fix_checksum(dis->tcp,dis->transport_len, dis->ip, dis->ip6);
|
||||
|
||||
char ss[2],i;
|
||||
if (dp->synack_split==SS_SYNACK)
|
||||
{
|
||||
ss[0] = 'S';
|
||||
ss[1] = 'A';
|
||||
}
|
||||
else
|
||||
{
|
||||
ss[0] = 'A';
|
||||
ss[1] = 'S';
|
||||
}
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_ACK, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, SCALE_NONE, timestamps,
|
||||
DF,ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||
FOOL_NONE,0,0,NULL, 0, pkt1, &pkt1_len))
|
||||
{
|
||||
DLOG_ERR("cannot prepare split SYNACK ACK part\n");
|
||||
goto send_orig;
|
||||
}
|
||||
for (int i=0;i<2;i++)
|
||||
{
|
||||
switch(ss[i])
|
||||
{
|
||||
case 'S':
|
||||
DLOG("split SYNACK : SYN\n");
|
||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
||||
goto send_orig;
|
||||
break;
|
||||
case 'A':
|
||||
DLOG("split SYNACK : ACK\n");
|
||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
goto send_orig;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return VERDICT_DROP;
|
||||
}
|
||||
|
||||
// start and cutoff limiters
|
||||
if (!process_desync_interval(dp, ctrack)) goto send_orig;
|
||||
} // !replay
|
||||
@@ -1289,10 +1342,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||
flags_orig = *((uint8_t*)dis->tcp+13);
|
||||
scale_factor = tcp_find_scale_factor(dis->tcp);
|
||||
timestamps = tcp_find_timestamps(dis->tcp);
|
||||
bSack = tcp_has_sack(dis->tcp);
|
||||
nmss = tcp_find_mss(dis->tcp);
|
||||
DF = ip_has_df(dis->ip);
|
||||
|
||||
if (!replay)
|
||||
{
|
||||
|
248
nfq/nfqws.c
248
nfq/nfqws.c
@@ -30,6 +30,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <syslog.h>
|
||||
#include <grp.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#include "win.h"
|
||||
@@ -296,8 +297,7 @@ static int nfq_main(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
sec_harden();
|
||||
if (params.droproot && !droproot(params.uid, params.gid) || !dropcaps())
|
||||
if (params.droproot && !droproot(params.uid, params.gid, params.gid_count) || !dropcaps())
|
||||
goto err;
|
||||
print_id();
|
||||
if (params.droproot && !test_list_files())
|
||||
@@ -308,6 +308,8 @@ static int nfq_main(void)
|
||||
|
||||
if (params.daemon) daemonize();
|
||||
|
||||
sec_harden();
|
||||
|
||||
if (Fpid)
|
||||
{
|
||||
if (fprintf(Fpid, "%d", getpid())<=0)
|
||||
@@ -421,7 +423,7 @@ static int dvt_main(void)
|
||||
goto exiterr;
|
||||
|
||||
|
||||
if (params.droproot && !droproot(params.uid, params.gid))
|
||||
if (params.droproot && !droproot(params.uid, params.gid, params.gid_count))
|
||||
goto exiterr;
|
||||
print_id();
|
||||
if (params.droproot && !test_list_files())
|
||||
@@ -527,13 +529,7 @@ static int win_main(const char *windivert_filter)
|
||||
WINDIVERT_ADDRESS wa;
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
if (params.daemon)
|
||||
{
|
||||
// cygwin loses current dir
|
||||
char *cwd = get_current_dir_name();
|
||||
daemonize();
|
||||
chdir(cwd);
|
||||
}
|
||||
if (params.daemon) daemonize();
|
||||
|
||||
if (*params.pidfile && !writepid(params.pidfile))
|
||||
{
|
||||
@@ -648,33 +644,6 @@ static int win_main(const char *windivert_filter)
|
||||
|
||||
|
||||
|
||||
static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
|
||||
{
|
||||
int v;
|
||||
char *p;
|
||||
|
||||
if ((p = strchr(s,':'))) *p++=0;
|
||||
v = atoi(s);
|
||||
if (v < 0 || v>65535)
|
||||
{
|
||||
DLOG_ERR("bad wsize\n");
|
||||
return false;
|
||||
}
|
||||
*wsize=(uint16_t)v;
|
||||
if (p && *p)
|
||||
{
|
||||
v = atoi(p);
|
||||
if (v < 0 || v>255)
|
||||
{
|
||||
DLOG_ERR("bad wscale\n");
|
||||
return false;
|
||||
}
|
||||
*wscale = (uint8_t)v;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !defined( __OpenBSD__) && !defined(__ANDROID__)
|
||||
static void cleanup_args()
|
||||
@@ -707,6 +676,61 @@ static void exit_clean(int code)
|
||||
exit(code);
|
||||
}
|
||||
|
||||
|
||||
static bool parse_uid(const char *opt, uid_t *uid, gid_t *gid, int *gid_count, int max_gids)
|
||||
{
|
||||
unsigned int u;
|
||||
char c, *p, *e;
|
||||
|
||||
*gid_count=0;
|
||||
if ((e = strchr(optarg,':'))) *e++=0;
|
||||
if (sscanf(opt,"%u",&u)!=1) return false;
|
||||
*uid = (uid_t)u;
|
||||
for (p=e ; p ; )
|
||||
{
|
||||
if ((e = strchr(p,',')))
|
||||
{
|
||||
c=*e;
|
||||
*e=0;
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
if (sscanf(p,"%u",&u)!=1) return false;
|
||||
if (*gid_count>=max_gids) return false;
|
||||
gid[(*gid_count)++] = (gid_t)u;
|
||||
}
|
||||
if (e) *e++=c;
|
||||
p = e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
|
||||
{
|
||||
int v;
|
||||
char *p;
|
||||
|
||||
if ((p = strchr(s,':'))) *p++=0;
|
||||
v = atoi(s);
|
||||
if (v < 0 || v>65535)
|
||||
{
|
||||
DLOG_ERR("bad wsize\n");
|
||||
return false;
|
||||
}
|
||||
*wsize=(uint16_t)v;
|
||||
if (p && *p)
|
||||
{
|
||||
v = atoi(p);
|
||||
if (v < 0 || v>255)
|
||||
{
|
||||
DLOG_ERR("bad wscale\n");
|
||||
return false;
|
||||
}
|
||||
*wscale = (uint8_t)v;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_cutoff(const char *opt, unsigned int *value, char *mode)
|
||||
{
|
||||
*mode = (*opt=='n' || *opt=='d' || *opt=='s') ? *opt++ : 'n';
|
||||
@@ -756,27 +780,33 @@ static bool parse_autottl(const char *s, autottl *t, int8_t def_delta, uint8_t d
|
||||
t->max = def_max;
|
||||
if (s)
|
||||
{
|
||||
max = t->max;
|
||||
if (*s=='+')
|
||||
// "-" means disable
|
||||
if (s[0]=='-' && s[1]==0)
|
||||
memset(t,0,sizeof(*t));
|
||||
else
|
||||
{
|
||||
neg=false;
|
||||
s++;
|
||||
} else if (*s=='-')
|
||||
s++;
|
||||
switch (sscanf(s,"%u:%u-%u",&delta,&min,&max))
|
||||
{
|
||||
case 3:
|
||||
if ((delta && !max) || max>255) return false;
|
||||
t->max=(uint8_t)max;
|
||||
case 2:
|
||||
if ((delta && !min) || min>255 || min>max) return false;
|
||||
t->min=(uint8_t)min;
|
||||
case 1:
|
||||
if (delta>127) return false;
|
||||
t->delta=(int8_t)(neg ? -delta : delta);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
max = t->max;
|
||||
if (*s=='+')
|
||||
{
|
||||
neg=false;
|
||||
s++;
|
||||
} else if (*s=='-')
|
||||
s++;
|
||||
switch (sscanf(s,"%u:%u-%u",&delta,&min,&max))
|
||||
{
|
||||
case 3:
|
||||
if ((delta && !max) || max>255) return false;
|
||||
t->max=(uint8_t)max;
|
||||
case 2:
|
||||
if ((delta && !min) || min>255 || min>max) return false;
|
||||
t->min=(uint8_t)min;
|
||||
case 1:
|
||||
if (delta>127) return false;
|
||||
t->delta=(int8_t)(neg ? -delta : delta);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -1468,7 +1498,7 @@ static void exithelp(void)
|
||||
" --pidfile=<filename>\t\t\t\t; write pid to file\n"
|
||||
#ifndef __CYGWIN__
|
||||
" --user=<username>\t\t\t\t; drop root privs\n"
|
||||
" --uid=uid[:gid]\t\t\t\t; drop root privs\n"
|
||||
" --uid=uid[:gid1,gid2,...]\t\t\t; drop root privs\n"
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
" --bind-fix4\t\t\t\t\t; apply outgoing interface selection fix for generated ipv4 packets\n"
|
||||
@@ -1516,18 +1546,19 @@ static void exithelp(void)
|
||||
" --wsize=<window_size>[:<scale_factor>]\t\t; set window size. 0 = do not modify. OBSOLETE !\n"
|
||||
" --wssize=<window_size>[:<scale_factor>]\t; set window size for server. 0 = do not modify. default scale_factor = 0.\n"
|
||||
" --wssize-cutoff=[n|d|s]N\t\t\t; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||
" --synack-split=[syn|synack|acksyn]\t\t; perform TCP split handshake : send SYN only, SYN+ACK or ACK+SYN\n"
|
||||
" --orig-ttl=<int>\t\t\t\t; set TTL for original packets\n"
|
||||
" --orig-ttl6=<int>\t\t\t\t; set ipv6 hop limit for original packets. by default ttl value is used\n"
|
||||
" --orig-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both ipv4 and ipv6. default: +%d:%u-%u\n"
|
||||
" --orig-autottl6=[<delta>[:<min>[-<max>]]]\t; overrides --orig-autottl for ipv6 only\n"
|
||||
" --orig-autottl=[<delta>[:<min>[-<max>]]|-]\t; auto ttl mode for both ipv4 and ipv6. default: +%d:%u-%u\n"
|
||||
" --orig-autottl6=[<delta>[:<min>[-<max>]]|-]\t; overrides --orig-autottl for ipv6 only\n"
|
||||
" --orig-mod-start=[n|d|s]N\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n"
|
||||
" --orig-mod-cutoff=[n|d|s]N\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||
" --dup=<int>\t\t\t\t\t; duplicate original packets. send N dups before original.\n"
|
||||
" --dup-replace=[0|1]\t\t\t\t; 1 or no argument means do not send original, only dups\n"
|
||||
" --dup-ttl=<int>\t\t\t\t; set TTL for dups\n"
|
||||
" --dup-ttl6=<int>\t\t\t\t; set ipv6 hop limit for dups. by default ttl value is used\n"
|
||||
" --dup-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both ipv4 and ipv6. default: %d:%u-%u\n"
|
||||
" --dup-autottl6=[<delta>[:<min>[-<max>]]]\t; overrides --dup-autottl for ipv6 only\n"
|
||||
" --dup-autottl=[<delta>[:<min>[-<max>]]|-]\t; auto ttl mode for both ipv4 and ipv6. default: %d:%u-%u\n"
|
||||
" --dup-autottl6=[<delta>[:<min>[-<max>]]|-]\t; overrides --dup-autottl for ipv6 only\n"
|
||||
" --dup-fooling=<mode>[,<mode>]\t\t\t; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack hopbyhop hopbyhop2\n"
|
||||
" --dup-badseq-increment=<int|0xHEX>\t\t; badseq fooling seq signed increment for dup. default %d\n"
|
||||
" --dup-badack-increment=<int|0xHEX>\t\t; badseq fooling ackseq signed increment for dup. default %d\n"
|
||||
@@ -1548,8 +1579,8 @@ static void exithelp(void)
|
||||
#endif
|
||||
" --dpi-desync-ttl=<int>\t\t\t\t; set ttl for fakes packets\n"
|
||||
" --dpi-desync-ttl6=<int>\t\t\t; set ipv6 hop limit for fake packet. by default --dpi-desync-ttl value is used.\n"
|
||||
" --dpi-desync-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both ipv4 and ipv6. default: %d:%u-%u\n"
|
||||
" --dpi-desync-autottl6=[<delta>[:<min>[-<max>]]] ; overrides --dpi-desync-autottl for ipv6 only\n"
|
||||
" --dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: %d:%u-%u\n"
|
||||
" --dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --dpi-desync-autottl for ipv6 only\n"
|
||||
" --dpi-desync-fooling=<mode>[,<mode>]\t\t; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack hopbyhop hopbyhop2\n"
|
||||
" --dpi-desync-repeats=<N>\t\t\t; send every desync packet N times\n"
|
||||
" --dpi-desync-skip-nosni=0|1\t\t\t; 1(default)=do not act on ClientHello without SNI\n"
|
||||
@@ -1633,12 +1664,14 @@ void config_from_file(const char *filename)
|
||||
void check_dp(const struct desync_profile *dp)
|
||||
{
|
||||
// only linux has connbytes limiter
|
||||
if (dp->desync_any_proto && !dp->desync_cutoff &&
|
||||
if ((dp->desync_any_proto && !dp->desync_cutoff &&
|
||||
(dp->desync_mode==DESYNC_FAKE || dp->desync_mode==DESYNC_RST || dp->desync_mode==DESYNC_RSTACK ||
|
||||
dp->desync_mode==DESYNC_FAKEDSPLIT || dp->desync_mode==DESYNC_FAKEDDISORDER || dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER))
|
||||
||
|
||||
dp->dup_repeats && !dp->dup_cutoff)
|
||||
{
|
||||
#ifdef __linux__
|
||||
DLOG_CONDUP("WARNING !!! in profile %d you are using --dpi-desync-any-protocol without --dpi-desync-cutoff\n", dp->n);
|
||||
DLOG_CONDUP("WARNING !!! in profile %d you are using --dpi-desync-any-protocol without --dpi-desync-cutoff or --dup without --dup-cutoff\n", dp->n);
|
||||
DLOG_CONDUP("WARNING !!! it's completely ok if connbytes or payload based ip/nf tables limiter is applied. Make sure it exists.\n");
|
||||
#else
|
||||
DLOG_CONDUP("WARNING !!! possible TRASH FLOOD configuration detected in profile %d\n", dp->n);
|
||||
@@ -1654,10 +1687,18 @@ void check_dp(const struct desync_profile *dp)
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
#if defined(ZAPRET_GH_VER) || defined (ZAPRET_GH_HASH)
|
||||
#ifdef __ANDROID__
|
||||
#define PRINT_VER printf("github android version %s (%s)\n\n", TOSTRING(ZAPRET_GH_VER), TOSTRING(ZAPRET_GH_HASH))
|
||||
#else
|
||||
#define PRINT_VER printf("github version %s (%s)\n\n", TOSTRING(ZAPRET_GH_VER), TOSTRING(ZAPRET_GH_HASH))
|
||||
#endif
|
||||
#else
|
||||
#ifdef __ANDROID__
|
||||
#define PRINT_VER printf("self-built android version %s %s\n\n", __DATE__, __TIME__)
|
||||
#else
|
||||
#define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum opt_indices {
|
||||
IDX_DEBUG,
|
||||
@@ -1678,6 +1719,7 @@ enum opt_indices {
|
||||
IDX_WSIZE,
|
||||
IDX_WSSIZE,
|
||||
IDX_WSSIZE_CUTOFF,
|
||||
IDX_SYNACK_SPLIT,
|
||||
IDX_CTRACK_TIMEOUTS,
|
||||
IDX_CTRACK_DISABLE,
|
||||
IDX_IPCACHE_LIFETIME,
|
||||
@@ -1798,6 +1840,7 @@ static const struct option long_options[] = {
|
||||
[IDX_WSIZE] = {"wsize", required_argument, 0, 0},
|
||||
[IDX_WSSIZE] = {"wssize", required_argument, 0, 0},
|
||||
[IDX_WSSIZE_CUTOFF] = {"wssize-cutoff", required_argument, 0, 0},
|
||||
[IDX_SYNACK_SPLIT] = {"synack-split", optional_argument, 0, 0},
|
||||
[IDX_CTRACK_TIMEOUTS] = {"ctrack-timeouts", required_argument, 0, 0},
|
||||
[IDX_CTRACK_DISABLE] = {"ctrack-disable", optional_argument, 0, 0},
|
||||
[IDX_IPCACHE_LIFETIME] = {"ipcache-lifetime", required_argument, 0, 0},
|
||||
@@ -1962,9 +2005,10 @@ int main(int argc, char **argv)
|
||||
LIST_INIT(¶ms.ssid_filter);
|
||||
LIST_INIT(¶ms.nlm_filter);
|
||||
#else
|
||||
if (can_drop_root()) // are we root ?
|
||||
if (can_drop_root())
|
||||
{
|
||||
params.uid = params.gid = 0x7FFFFFFF; // default uid:gid
|
||||
params.uid = params.gid[0] = 0x7FFFFFFF; // default uid:gid
|
||||
params.gid_count = 1;
|
||||
params.droproot = true;
|
||||
}
|
||||
#endif
|
||||
@@ -2062,26 +2106,45 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
#ifndef __CYGWIN__
|
||||
case IDX_USER:
|
||||
{
|
||||
struct passwd *pwd = getpwnam(optarg);
|
||||
if (!pwd)
|
||||
{
|
||||
struct passwd *pwd = getpwnam(optarg);
|
||||
if (!pwd)
|
||||
{
|
||||
DLOG_ERR("non-existent username supplied\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
params.uid = pwd->pw_uid;
|
||||
params.gid = pwd->pw_gid;
|
||||
params.droproot = true;
|
||||
}
|
||||
break;
|
||||
case IDX_UID:
|
||||
params.gid = 0x7FFFFFFF; // default gid. drop gid=0
|
||||
params.droproot = true;
|
||||
if (sscanf(optarg, "%u:%u", ¶ms.uid, ¶ms.gid)<1)
|
||||
{
|
||||
DLOG_ERR("--uid should be : uid[:gid]\n");
|
||||
DLOG_ERR("non-existent username supplied\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
params.uid = pwd->pw_uid;
|
||||
params.gid_count=MAX_GIDS;
|
||||
#ifdef __APPLE__
|
||||
// silence warning
|
||||
if (getgrouplist(optarg,pwd->pw_gid,(int*)params.gid,¶ms.gid_count)<0)
|
||||
#else
|
||||
if (getgrouplist(optarg,pwd->pw_gid,params.gid,¶ms.gid_count)<0)
|
||||
#endif
|
||||
{
|
||||
DLOG_ERR("getgrouplist failed. too much groups ?\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (!params.gid_count)
|
||||
{
|
||||
params.gid[0] = pwd->pw_gid;
|
||||
params.gid_count = 1;
|
||||
}
|
||||
params.droproot = true;
|
||||
break;
|
||||
}
|
||||
case IDX_UID:
|
||||
params.droproot = true;
|
||||
if (!parse_uid(optarg,¶ms.uid,params.gid,¶ms.gid_count,MAX_GIDS))
|
||||
{
|
||||
DLOG_ERR("--uid should be : uid[:gid,gid,...]\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (!params.gid_count)
|
||||
{
|
||||
params.gid[0] = 0x7FFFFFFF;
|
||||
params.gid_count = 1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case IDX_WSIZE:
|
||||
@@ -2099,6 +2162,21 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_SYNACK_SPLIT:
|
||||
dp->synack_split = SS_SYN;
|
||||
if (optarg)
|
||||
{
|
||||
if (!strcmp(optarg,"synack"))
|
||||
dp->synack_split = SS_SYNACK;
|
||||
else if (!strcmp(optarg,"acksyn"))
|
||||
dp->synack_split = SS_ACKSYN;
|
||||
else if (strcmp(optarg,"syn"))
|
||||
{
|
||||
DLOG_ERR("invalid synack-split value\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDX_CTRACK_TIMEOUTS:
|
||||
if (sscanf(optarg, "%u:%u:%u:%u", ¶ms.ctrack_t_syn, ¶ms.ctrack_t_est, ¶ms.ctrack_t_fin, ¶ms.ctrack_t_udp)<3)
|
||||
{
|
||||
|
@@ -63,6 +63,8 @@
|
||||
#define FAKE_MAX_TCP 1460
|
||||
#define FAKE_MAX_UDP 1472
|
||||
|
||||
#define MAX_GIDS 64
|
||||
|
||||
enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG };
|
||||
|
||||
struct fake_tls_mod_cache
|
||||
@@ -75,6 +77,8 @@ struct fake_tls_mod
|
||||
uint32_t mod;
|
||||
};
|
||||
|
||||
typedef enum {SS_NONE=0,SS_SYN,SS_SYNACK,SS_ACKSYN} t_synack_split;
|
||||
|
||||
struct desync_profile
|
||||
{
|
||||
int n; // number of the profile
|
||||
@@ -84,6 +88,8 @@ struct desync_profile
|
||||
char wssize_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||
unsigned int wssize_cutoff;
|
||||
|
||||
t_synack_split synack_split;
|
||||
|
||||
bool hostcase, hostnospace, domcase, methodeol;
|
||||
char hostspell[4];
|
||||
enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2;
|
||||
@@ -187,7 +193,8 @@ struct params_s
|
||||
#else
|
||||
bool droproot;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
gid_t gid[MAX_GIDS];
|
||||
int gid_count;
|
||||
#endif
|
||||
char pidfile[PATH_MAX];
|
||||
|
||||
|
19
nfq/sec.c
19
nfq/sec.c
@@ -295,8 +295,13 @@ bool can_drop_root(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool droproot(uid_t uid, gid_t gid)
|
||||
bool droproot(uid_t uid, gid_t *gid, int gid_count)
|
||||
{
|
||||
if (gid_count<1)
|
||||
{
|
||||
DLOG_ERR("droproot: no groups specified");
|
||||
return false;
|
||||
}
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_KEEPCAPS, 1L))
|
||||
{
|
||||
@@ -305,12 +310,12 @@ bool droproot(uid_t uid, gid_t gid)
|
||||
}
|
||||
#endif
|
||||
// drop all SGIDs
|
||||
if (setgroups(0,NULL))
|
||||
if (setgroups(gid_count,gid))
|
||||
{
|
||||
DLOG_PERROR("setgroups");
|
||||
return false;
|
||||
}
|
||||
if (setgid(gid))
|
||||
if (setgid(gid[0]))
|
||||
{
|
||||
DLOG_PERROR("setgid");
|
||||
return false;
|
||||
@@ -343,9 +348,13 @@ void print_id(void)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void daemonize(void)
|
||||
{
|
||||
int pid;
|
||||
#ifdef __CYGWIN__
|
||||
char *cwd = get_current_dir_name();
|
||||
#endif
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
@@ -356,6 +365,10 @@ void daemonize(void)
|
||||
else if (pid != 0)
|
||||
exit(0);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
chdir(get_current_dir_name());
|
||||
#endif
|
||||
|
||||
if (setsid() == -1)
|
||||
exit(2);
|
||||
if (chdir("/") == -1)
|
||||
|
@@ -84,7 +84,7 @@ bool dropcaps(void);
|
||||
#ifndef __CYGWIN__
|
||||
bool sec_harden(void);
|
||||
bool can_drop_root(void);
|
||||
bool droproot(uid_t uid, gid_t gid);
|
||||
bool droproot(uid_t uid, gid_t *gid, int gid_count);
|
||||
void print_id(void);
|
||||
#endif
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <time.h>
|
||||
#if !defined( __OpenBSD__) && !defined(__ANDROID__)
|
||||
@@ -18,13 +19,15 @@
|
||||
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
|
||||
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
||||
|
||||
#define FIX_SEG_DEFAULT_MAX_WAIT 50
|
||||
#define FIX_SEG_DEFAULT_MAX_WAIT 50
|
||||
|
||||
#define IPCACHE_LIFETIME 7200
|
||||
#define IPCACHE_LIFETIME 7200
|
||||
|
||||
#define MAX_GIDS 64
|
||||
|
||||
enum bindll { unwanted=0, no, prefer, force };
|
||||
|
||||
#define MAX_BINDS 32
|
||||
#define MAX_BINDS 32
|
||||
struct bind_s
|
||||
{
|
||||
char bindaddr[64],bindiface[IF_NAMESIZE];
|
||||
@@ -33,7 +36,7 @@ struct bind_s
|
||||
int bind_wait_ifup,bind_wait_ip,bind_wait_ip_ll;
|
||||
};
|
||||
|
||||
#define MAX_SPLITS 16
|
||||
#define MAX_SPLITS 16
|
||||
|
||||
enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG };
|
||||
|
||||
@@ -116,8 +119,9 @@ struct params_s
|
||||
bool droproot;
|
||||
bool daemon;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char pidfile[256];
|
||||
gid_t gid[MAX_GIDS];
|
||||
int gid_count;
|
||||
char pidfile[PATH_MAX];
|
||||
int maxconn,resolver_threads,maxfiles,max_orphan_time;
|
||||
int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf;
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
|
20
tpws/sec.c
20
tpws/sec.c
@@ -169,25 +169,24 @@ static bool set_seccomp(void)
|
||||
|
||||
bool sec_harden(void)
|
||||
{
|
||||
bool bRes = true;
|
||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
|
||||
{
|
||||
DLOG_PERROR("PR_SET_NO_NEW_PRIVS(prctl)");
|
||||
return false;
|
||||
bRes = false;
|
||||
}
|
||||
#if ARCH_NR!=0
|
||||
if (!set_seccomp())
|
||||
{
|
||||
DLOG_PERROR("seccomp");
|
||||
if (errno==EINVAL) DLOG_ERR("seccomp: this can be safely ignored if kernel does not support seccomp\n");
|
||||
return false;
|
||||
bRes = false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
return bRes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool checkpcap(uint64_t caps)
|
||||
{
|
||||
if (!caps) return true; // no special caps reqd
|
||||
@@ -270,8 +269,13 @@ bool can_drop_root(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool droproot(uid_t uid, gid_t gid)
|
||||
bool droproot(uid_t uid, gid_t *gid, int gid_count)
|
||||
{
|
||||
if (gid_count<1)
|
||||
{
|
||||
DLOG_ERR("droproot: no groups specified");
|
||||
return false;
|
||||
}
|
||||
#ifdef __linux__
|
||||
if (prctl(PR_SET_KEEPCAPS, 1L))
|
||||
{
|
||||
@@ -280,12 +284,12 @@ bool droproot(uid_t uid, gid_t gid)
|
||||
}
|
||||
#endif
|
||||
// drop all SGIDs
|
||||
if (setgroups(0,NULL))
|
||||
if (setgroups(gid_count,gid))
|
||||
{
|
||||
DLOG_PERROR("setgroups");
|
||||
return false;
|
||||
}
|
||||
if (setgid(gid))
|
||||
if (setgid(gid[0]))
|
||||
{
|
||||
DLOG_PERROR("setgid");
|
||||
return false;
|
||||
|
@@ -84,7 +84,7 @@ bool dropcaps(void);
|
||||
|
||||
bool sec_harden(void);
|
||||
bool can_drop_root();
|
||||
bool droproot(uid_t uid, gid_t gid);
|
||||
bool droproot(uid_t uid, gid_t *gid, int gid_count);
|
||||
void print_id(void);
|
||||
void daemonize(void);
|
||||
bool writepid(const char *filename);
|
||||
|
80
tpws/tpws.c
80
tpws/tpws.c
@@ -23,6 +23,7 @@
|
||||
#include <sys/resource.h>
|
||||
#include <time.h>
|
||||
#include <syslog.h>
|
||||
#include <grp.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "andr/ifaddrs.h"
|
||||
@@ -214,7 +215,7 @@ static void exithelp(void)
|
||||
" --daemon\t\t\t\t; daemonize\n"
|
||||
" --pidfile=<filename>\t\t\t; write pid to file\n"
|
||||
" --user=<username>\t\t\t; drop root privs\n"
|
||||
" --uid=uid[:gid]\t\t\t; drop root privs\n"
|
||||
" --uid=uid[:gid1,gid2,...]\t\t; drop root privs\n"
|
||||
#if defined(__FreeBSD__)
|
||||
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
|
||||
#endif
|
||||
@@ -583,6 +584,35 @@ static bool parse_ip_list(char *opt, ipset *pp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_uid(const char *opt, uid_t *uid, gid_t *gid, int *gid_count, int max_gids)
|
||||
{
|
||||
unsigned int u;
|
||||
char c, *p, *e;
|
||||
|
||||
*gid_count=0;
|
||||
if ((e = strchr(optarg,':'))) *e++=0;
|
||||
if (sscanf(opt,"%u",&u)!=1) return false;
|
||||
*uid = (uid_t)u;
|
||||
for (p=e ; p ; )
|
||||
{
|
||||
if ((e = strchr(p,',')))
|
||||
{
|
||||
c=*e;
|
||||
*e=0;
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
if (sscanf(p,"%u",&u)!=1) return false;
|
||||
if (*gid_count>=max_gids) return false;
|
||||
gid[(*gid_count)++] = (gid_t)u;
|
||||
}
|
||||
if (e) *e++=c;
|
||||
p = e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#if !defined( __OpenBSD__) && !defined(__ANDROID__)
|
||||
// no static to not allow optimizer to inline this func (save stack)
|
||||
void config_from_file(const char *filename)
|
||||
@@ -837,8 +867,9 @@ void parse_params(int argc, char *argv[])
|
||||
|
||||
if (can_drop_root())
|
||||
{
|
||||
params.uid = params.gid = 0x7FFFFFFF; // default uid:gid
|
||||
params.droproot = true;
|
||||
params.uid = params.gid[0] = 0x7FFFFFFF; // default uid:gid
|
||||
params.gid_count = 1;
|
||||
params.droproot = true;
|
||||
}
|
||||
|
||||
struct desync_profile_list *dpl;
|
||||
@@ -954,18 +985,37 @@ void parse_params(int argc, char *argv[])
|
||||
exit_clean(1);
|
||||
}
|
||||
params.uid = pwd->pw_uid;
|
||||
params.gid = pwd->pw_gid;
|
||||
params.gid_count=MAX_GIDS;
|
||||
#ifdef __APPLE__
|
||||
// silence warning
|
||||
if (getgrouplist(optarg,pwd->pw_gid,(int*)params.gid,¶ms.gid_count)<0)
|
||||
#else
|
||||
if (getgrouplist(optarg,pwd->pw_gid,params.gid,¶ms.gid_count)<0)
|
||||
#endif
|
||||
{
|
||||
DLOG_ERR("getgrouplist failed. too much groups ?\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (!params.gid_count)
|
||||
{
|
||||
params.gid[0] = pwd->pw_gid;
|
||||
params.gid_count = 1;
|
||||
}
|
||||
params.droproot = true;
|
||||
break;
|
||||
}
|
||||
case IDX_UID:
|
||||
params.gid=0x7FFFFFFF; // default git. drop gid=0
|
||||
params.droproot = true;
|
||||
if (sscanf(optarg,"%u:%u",¶ms.uid,¶ms.gid)<1)
|
||||
if (!parse_uid(optarg,¶ms.uid,params.gid,¶ms.gid_count,MAX_GIDS))
|
||||
{
|
||||
DLOG_ERR("--uid should be : uid[:gid]\n");
|
||||
DLOG_ERR("--uid should be : uid[:gid,gid,...]\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (!params.gid_count)
|
||||
{
|
||||
params.gid[0] = 0x7FFFFFFF;
|
||||
params.gid_count = 1;
|
||||
}
|
||||
break;
|
||||
case IDX_MAXCONN:
|
||||
params.maxconn = atoi(optarg);
|
||||
@@ -1273,8 +1323,7 @@ void parse_params(int argc, char *argv[])
|
||||
}
|
||||
break;
|
||||
case IDX_PIDFILE:
|
||||
strncpy(params.pidfile,optarg,sizeof(params.pidfile));
|
||||
params.pidfile[sizeof(params.pidfile)-1]='\0';
|
||||
snprintf(params.pidfile,sizeof(params.pidfile),"%s",optarg);
|
||||
break;
|
||||
case IDX_DEBUG:
|
||||
if (optarg)
|
||||
@@ -1822,10 +1871,18 @@ static const char *bindll_s[] = { "unwanted","no","prefer","force" };
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
#if defined(ZAPRET_GH_VER) || defined (ZAPRET_GH_HASH)
|
||||
#ifdef __ANDROID__
|
||||
#define PRINT_VER printf("github android version %s (%s)\n\n", TOSTRING(ZAPRET_GH_VER), TOSTRING(ZAPRET_GH_HASH))
|
||||
#else
|
||||
#define PRINT_VER printf("github version %s (%s)\n\n", TOSTRING(ZAPRET_GH_VER), TOSTRING(ZAPRET_GH_HASH))
|
||||
#endif
|
||||
#else
|
||||
#ifdef __ANDROID__
|
||||
#define PRINT_VER printf("self-built android version %s %s\n\n", __DATE__, __TIME__)
|
||||
#else
|
||||
#define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -2086,8 +2143,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
set_ulimit();
|
||||
sec_harden();
|
||||
if (params.droproot && !droproot(params.uid,params.gid))
|
||||
if (params.droproot && !droproot(params.uid,params.gid,params.gid_count))
|
||||
goto exiterr;
|
||||
#ifdef __linux__
|
||||
if (!dropcaps())
|
||||
@@ -2099,6 +2155,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (params.daemon) daemonize();
|
||||
|
||||
sec_harden();
|
||||
|
||||
if (Fpid)
|
||||
{
|
||||
if (fprintf(Fpid, "%d", getpid())<=0)
|
||||
|
Reference in New Issue
Block a user