From 494ac4b76222e145c0301f190e583c2b78ae6309 Mon Sep 17 00:00:00 2001 From: bol-van Date: Fri, 10 Dec 2021 18:54:09 +0300 Subject: [PATCH] separate nfqws options for ipv4/6 --- config | 2 + docs/readme.eng.txt | 4 +- docs/readme.txt | 4 +- init.d/openwrt/functions | 104 +++++++++++++++++++++++++------ init.d/openwrt/zapret | 32 +++++++--- init.d/sysv/functions | 130 +++++++++++++++++++++++++++++++-------- install_easy.sh | 2 +- 7 files changed, 223 insertions(+), 55 deletions(-) diff --git a/config b/config index 3bd92f4..a25f0cb 100644 --- a/config +++ b/config @@ -46,6 +46,8 @@ DESYNC_MARK=0x40000000 NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" #NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" #NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" +#NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none" +#NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none" # CHOOSE TPWS DAEMON OPTIONS. run "tpws/tpws --help" for option list TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3" diff --git a/docs/readme.eng.txt b/docs/readme.eng.txt index 167c790..c94611a 100644 --- a/docs/readme.eng.txt +++ b/docs/readme.eng.txt @@ -533,10 +533,12 @@ nfqws options for DPI desync attack: DESYNC_MARK=0x40000000 NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum --dpi-desync-fwmark=$DESYNC_MARK" -Separate nfqws options for http and https : +Separate nfqws options for http and https and ip protocol versions 4,6: NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" +NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none" +NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none" If a variable is not defined, the value NFQWS_OPT_DESYNC is taken. diff --git a/docs/readme.txt b/docs/readme.txt index 5be71ba..28b2b9a 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -776,10 +776,12 @@ TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3" DESYNC_MARK=0x40000000 NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" -Задание раздельных опций nfqws для http и https : +Задание раздельных опций nfqws для http и https и для версий ip протоколов 4,6 : NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum" +NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none" +NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none" Если какая-то из переменных не определена, берется значение NFQWS_OPT_DESYNC. diff --git a/init.d/openwrt/functions b/init.d/openwrt/functions index dfde538..e20ad69 100644 --- a/init.d/openwrt/functions +++ b/init.d/openwrt/functions @@ -23,6 +23,8 @@ IPSET_EXCLUDE6="-m set ! --match-set nozapret6" NFQWS_OPT_DESYNC_HTTP="${NFQWS_OPT_DESYNC_HTTP:-$NFQWS_OPT_DESYNC}" NFQWS_OPT_DESYNC_HTTPS="${NFQWS_OPT_DESYNC_HTTPS:-$NFQWS_OPT_DESYNC}" +NFQWS_OPT_DESYNC_HTTP6="${NFQWS_OPT_DESYNC_HTTP6:-$NFQWS_OPT_DESYNC_HTTP}" +NFQWS_OPT_DESYNC_HTTPS6="${NFQWS_OPT_DESYNC_HTTPS6:-$NFQWS_OPT_DESYNC_HTTPS}" exists() { @@ -299,16 +301,63 @@ filter_apply_port_target() fi eval $1="\"\$$1 $f\"" } +filter_apply_ipset_target4() +{ + # $1 - var name of ipv4 iptables filter + if [ "$MODE_FILTER" = "ipset" ]; then + eval $1="\"\$$1 -m set --match-set zapret dst\"" + fi +} +filter_apply_ipset_target6() +{ + # $1 - var name of ipv4 iptables filter + if [ "$MODE_FILTER" = "ipset" ]; then + eval $1="\"\$$1 -m set --match-set zapret6 dst\"" + fi +} filter_apply_ipset_target() { # $1 - var name of ipv4 iptables filter # $2 - var name of ipv6 iptables filter - if [ "$MODE_FILTER" = "ipset" ]; then - eval $1="\"\$$1 -m set --match-set zapret dst\"" - eval $2="\"\$$2 -m set --match-set zapret6 dst\"" - fi + filter_apply_ipset_target4 $1 + filter_apply_ipset_target6 $2 } +get_nfqws_qnums() +{ + # $1 - var name for ipv4 http + # $2 - var name for ipv4 https + # $3 - var name for ipv6 http + # $4 - var name for ipv6 https + local _qn=x _qns=x _qn6=x _qns6=x + + [ "$DISABLE_IPV4" = "1" ] || { + _qn=$QNUM + _qns=$_qn + [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || _qns=$(($QNUM+1)) + } + [ "$DISABLE_IPV6" = "1" ] || { + _qn6=$(($QNUM+2)) + _qns6=$(($QNUM+3)) + [ "$DISABLE_IPV4" = "1" ] || { + if [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then + _qn6=$_qn; + elif [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then + _qn6=$_qns; + fi + if [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then + _qns6=$_qn; + elif [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then + _qns6=$_qns; + fi + } + [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP6" ] && _qns6=$_qn6; + } + eval $1=$_qn + eval $2=$_qns + eval $3=$_qn6 + eval $4=$_qns6 +} create_ipset() { @@ -325,8 +374,9 @@ is_flow_offload_avail() list_nfqws_rules() { # $1 = '' for ipv4, '6' for ipv6 - ip$1tables -S POSTROUTING -t mangle | grep -E "NFQUEUE --queue-num $QNUM --queue-bypass|NFQUEUE --queue-num $(($QNUM+1)) --queue-bypass" | \ - sed -re 's/^-A POSTROUTING (.*) -j NFQUEUE.*$/\1/' -e "s/-m mark ! --mark $DESYNC_MARK\/$DESYNC_MARK//" + ip$1tables -S POSTROUTING -t mangle | \ + grep -E "NFQUEUE --queue-num $QNUM --queue-bypass|NFQUEUE --queue-num $(($QNUM+1)) --queue-bypass|NFQUEUE --queue-num $(($QNUM+2)) --queue-bypass|NFQUEUE --queue-num $(($QNUM+3)) --queue-bypass" | \ + sed -re 's/^-A POSTROUTING (.*) -j NFQUEUE.*$/\1/' -e "s/-m mark ! --mark $DESYNC_MARK\/$DESYNC_MARK//" } reverse_nfqws_rule() { @@ -392,8 +442,7 @@ zapret_apply_firewall() { local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - local f4 f6 - local qn + local f4 f6 qn qns qn6 qns6 # always create ipsets. ip_exclude ipset is required create_ipset no-update @@ -411,30 +460,45 @@ zapret_apply_firewall() ;; nfqws) + # quite complex but we need to minimize nfqws processes to save RAM if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then echo both http and https are disabled. not applying redirection. else - if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then + get_nfqws_qnums qn qns qn6 qns6 + if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ $qn = $qns ]; then filter_apply_port_target f4 f4="$f4 $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM + filter_apply_ipset_target4 f4 + fw_nfqws_post4 "$f4 $desync" $qn else if [ "$MODE_HTTP" = "1" ]; then f4="--dport 80" [ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM + filter_apply_ipset_target4 f4 + fw_nfqws_post4 "$f4 $desync" $qn fi if [ "$MODE_HTTPS" = "1" ]; then f4="--dport 443 $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - qn=$QNUM - [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || qn=$(($QNUM+1)) - fw_nfqws_post "$f4 $desync" "$f6 $desync" $qn + filter_apply_ipset_target4 f4 + fw_nfqws_post4 "$f4 $desync" $qns + fi + fi + if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ $qn6 = $qns6 ]; then + filter_apply_port_target f6 + f6="$f6 $first_packet_only" + filter_apply_ipset_target6 f6 + fw_nfqws_post6 "$f6 $desync" $qn6 + else + if [ "$MODE_HTTP" = "1" ]; then + f6="--dport 80" + [ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only" + filter_apply_ipset_target6 f6 + fw_nfqws_post6 "$f6 $desync" $qn6 + fi + if [ "$MODE_HTTPS" = "1" ]; then + f6="--dport 443 $first_packet_only" + filter_apply_ipset_target6 f6 + fw_nfqws_post6 "$f6 $desync" $qns6 fi fi fi diff --git a/init.d/openwrt/zapret b/init.d/openwrt/zapret index fd685c8..ffda5b1 100755 --- a/init.d/openwrt/zapret +++ b/init.d/openwrt/zapret @@ -105,7 +105,7 @@ tpws_apply_socks_binds() start_service() { - local opt + local opt qn qns qn6 qns6 case "${MODE}" in tpws) @@ -119,17 +119,35 @@ start_service() { run_tpws_socks 1 "$opt" ;; nfqws) - opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTP" - filter_apply_hostlist_target opt - run_daemon 1 "$NFQWS" "$opt" - [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || { - opt="--qnum=$(($QNUM+1)) $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS" + # quite complex but we need to minimize nfqws processes to save RAM + get_nfqws_qnums qn qns qn6 qns6 + [ "$DISABLE_IPV4" = "1" ] || { + opt="--qnum=$qn $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTP" filter_apply_hostlist_target opt - run_daemon 2 "$NFQWS" "$opt" + run_daemon 1 "$NFQWS" "$opt" + [ "$qns" = "$qn" ] || { + opt="--qnum=$qns $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS" + filter_apply_hostlist_target opt + run_daemon 2 "$NFQWS" "$opt" + } + } + [ "$DISABLE_IPV6" = "1" ] || { + [ "$qn6" = "$qn" ] || [ "$qn6" = "$qns" ] || { + opt="--qnum=$qn6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTP6" + filter_apply_hostlist_target opt + run_daemon 3 "$NFQWS" "$opt" + } + [ "$qns6" = "$qn" ] || [ "$qns6" = "$qns" ] || [ "$qns6" = "$qn6" ] || { + opt="--qnum=$qns6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS6" + filter_apply_hostlist_target opt + run_daemon 4 "$NFQWS" "$opt" + } } ;; custom) existf zapret_custom_daemons && zapret_custom_daemons $1 ;; esac + + return 0 } diff --git a/init.d/sysv/functions b/init.d/sysv/functions index e00cb92..a848499 100644 --- a/init.d/sysv/functions +++ b/init.d/sysv/functions @@ -81,6 +81,8 @@ IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh" NFQWS_OPT_BASE="$USEROPT --dpi-desync-fwmark=$DESYNC_MARK" NFQWS_OPT_DESYNC_HTTP="${NFQWS_OPT_DESYNC_HTTP:-$NFQWS_OPT_DESYNC}" NFQWS_OPT_DESYNC_HTTPS="${NFQWS_OPT_DESYNC_HTTPS:-$NFQWS_OPT_DESYNC}" +NFQWS_OPT_DESYNC_HTTP6="${NFQWS_OPT_DESYNC_HTTP6:-$NFQWS_OPT_DESYNC_HTTP}" +NFQWS_OPT_DESYNC_HTTPS6="${NFQWS_OPT_DESYNC_HTTPS6:-$NFQWS_OPT_DESYNC_HTTPS}" [ -n "$TPPORT" ] || TPPORT=988 [ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws" @@ -520,20 +522,70 @@ filter_apply_port_target() fi eval $1="\"\$$1 $f\"" } + +filter_apply_ipset_target4() +{ + # $1 - var name of ipv4 iptables filter + if [ "$MODE_FILTER" = "ipset" ]; then + eval $1="\"\$$1 -m set --match-set zapret dst\"" + fi +} +filter_apply_ipset_target6() +{ + # $1 - var name of ipv4 iptables filter + if [ "$MODE_FILTER" = "ipset" ]; then + eval $1="\"\$$1 -m set --match-set zapret6 dst\"" + fi +} filter_apply_ipset_target() { # $1 - var name of ipv4 iptables filter # $2 - var name of ipv6 iptables filter - if [ "$MODE_FILTER" = "ipset" ]; then - eval $1="\"\$$1 -m set --match-set zapret dst\"" - eval $2="\"\$$2 -m set --match-set zapret6 dst\"" - fi + filter_apply_ipset_target4 $1 + filter_apply_ipset_target6 $2 } filter_apply_hostlist_target() { # $1 - var name of tpws or nfqws params [ "$MODE_FILTER" = "hostlist" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\"" } + +get_nfqws_qnums() +{ + # $1 - var name for ipv4 http + # $2 - var name for ipv4 https + # $3 - var name for ipv6 http + # $4 - var name for ipv6 https + local _qn=x _qns=x _qn6=x _qns6=x + + [ "$DISABLE_IPV4" = "1" ] || { + _qn=$QNUM + _qns=$_qn + [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || _qns=$(($QNUM+1)) + } + [ "$DISABLE_IPV6" = "1" ] || { + _qn6=$(($QNUM+2)) + _qns6=$(($QNUM+3)) + [ "$DISABLE_IPV4" = "1" ] || { + if [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then + _qn6=$_qn; + elif [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then + _qn6=$_qns; + fi + if [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then + _qns6=$_qn; + elif [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then + _qns6=$_qns; + fi + } + [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP6" ] && _qns6=$_qn6; + } + eval $1=$_qn + eval $2=$_qns + eval $3=$_qn6 + eval $4=$_qns6 +} + tpws_apply_socks_binds() { local o @@ -563,8 +615,7 @@ zapret_do_firewall() local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" - local f4 f6 - local qn + local f4 f6 qn qns qn6 qns6 # always create ipsets. ip_exclude ipset is required [ "$1" != "1" ] || create_ipset no-update @@ -585,27 +636,41 @@ zapret_do_firewall() if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then echo both http and https are disabled. not applying redirection. else - if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then + get_nfqws_qnums qn qns qn6 qns6 + if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ $qn = $qns ]; then filter_apply_port_target f4 f4="$f4 $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM + filter_apply_ipset_target4 f4 + fw_nfqws_post4 $1 "$f4 $desync" $qn else if [ "$MODE_HTTP" = "1" ]; then f4="--dport 80" [ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM + filter_apply_ipset_target4 f4 + fw_nfqws_post4 $1 "$f4 $desync" $qn fi if [ "$MODE_HTTPS" = "1" ]; then f4="--dport 443 $first_packet_only" - f6=$f4 - filter_apply_ipset_target f4 f6 - qn=$QNUM - [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || qn=$(($QNUM+1)) - fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $qn + filter_apply_ipset_target4 f4 + fw_nfqws_post4 $1 "$f4 $desync" $qns + fi + fi + if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ $qn6 = $qns6 ]; then + filter_apply_port_target f6 + f6="$f6 $first_packet_only" + filter_apply_ipset_target6 f6 + fw_nfqws_post6 $1 "$f6 $desync" $qn6 + else + if [ "$MODE_HTTP" = "1" ]; then + f6="--dport 80" + [ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only" + filter_apply_ipset_target6 f6 + fw_nfqws_post6 $1 "$f6 $desync" $qn6 + fi + if [ "$MODE_HTTPS" = "1" ]; then + f6="--dport 443 $first_packet_only" + filter_apply_ipset_target6 f6 + fw_nfqws_post6 $1 "$f6 $desync" $qns6 fi fi fi @@ -631,7 +696,7 @@ zapret_do_daemons() { # $1 - 1 - run, 0 - stop - local opt + local opt qn qns qn6 qns6 case "${MODE}" in tpws) @@ -645,13 +710,28 @@ zapret_do_daemons() do_tpws_socks $1 1 "$opt" ;; nfqws) - opt="--qnum=$QNUM $NFQWS_OPT_DESYNC_HTTP" - filter_apply_hostlist_target opt - do_nfqws $1 1 "$opt" - [ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || { - opt="--qnum=$(($QNUM+1)) $NFQWS_OPT_DESYNC_HTTPS" + get_nfqws_qnums qn qns qn6 qns6 + [ "$DISABLE_IPV4" = "1" ] || { + opt="--qnum=$qn $NFQWS_OPT_DESYNC_HTTP" filter_apply_hostlist_target opt - do_nfqws $1 2 "$opt" + do_nfqws $1 1 "$opt" + [ "$qns" = "$qn" ] || { + opt="--qnum=$qns $NFQWS_OPT_DESYNC_HTTPS" + filter_apply_hostlist_target opt + do_nfqws $1 2 "$opt" + } + } + [ "$DISABLE_IPV6" = "1" ] || { + [ "$qn6" = "$qn" ] || [ "$qn6" = "$qns" ] || { + opt="--qnum=$qn6 $NFQWS_OPT_DESYNC_HTTP6" + filter_apply_hostlist_target opt + do_nfqws $1 3 "$opt" + } + [ "$qns6" = "$qn" ] || [ "$qns6" = "$qns" ] || [ "$qns6" = "$qn6" ] || { + opt="--qnum=$qns6 $NFQWS_OPT_DESYNC_HTTPS6" + filter_apply_hostlist_target opt + do_nfqws $1 4 "$opt" + } } ;; custom) diff --git a/install_easy.sh b/install_easy.sh index f3f7af8..0ba092f 100755 --- a/install_easy.sh +++ b/install_easy.sh @@ -382,7 +382,7 @@ select_mode_mode() vars="TPWS_OPT" ;; nfqws) - vars="NFQWS_OPT_DESYNC NFQWS_OPT_DESYNC_HTTP NFQWS_OPT_DESYNC_HTTPS" + vars="NFQWS_OPT_DESYNC NFQWS_OPT_DESYNC_HTTP NFQWS_OPT_DESYNC_HTTPS NFQWS_OPT_DESYNC_HTTP6 NFQWS_OPT_DESYNC_HTTPS6" ;; esac [ -n "$vars" ] && {