TSPU QUIC block bypass custom script

This commit is contained in:
bol-van 2022-05-29 23:07:59 +03:00
parent 01ec94806d
commit ef669a15a5
5 changed files with 156 additions and 12 deletions

View File

@ -129,7 +129,7 @@ _fw_tpws4()
# $3 - tpws port
# $4 - lan interface names space separated
# $5 - wan interface names space separated
[ "$DISABLE_IPV4" = "1" ] || {
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
local i rule
[ "$1" = 1 ] && prepare_tpws_fw4
@ -159,7 +159,7 @@ _fw_tpws6()
# $4 - lan interface names space separated
# $5 - wan interface names space separated
[ "$DISABLE_IPV6" = "1" ] || {
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
local i rule DNAT6
ipt_print_op $1 "$2" "tpws (port $3)" 6
@ -197,7 +197,7 @@ _fw_nfqws_post4()
# $2 - iptable filter for ipv4
# $3 - queue number
# $4 - wan interface names space separated
[ "$DISABLE_IPV4" = "1" ] || {
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
local i
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)"
@ -218,7 +218,7 @@ _fw_nfqws_post6()
# $2 - iptable filter for ipv6
# $3 - queue number
# $4 - wan interface names space separated
[ "$DISABLE_IPV6" = "1" ] || {
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
local i
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" 6

View File

@ -83,16 +83,20 @@ cat << EOF | nft -f -
add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr $TPWS_LOCALHOST4 return comment "route_localnet allow access to tpws"
add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr 127.0.0.0/8 drop comment "route_localnet remote access protection"
add rule inet $ZAPRET_NFT_TABLE input iif != lo jump localnet_protect
add chain inet $ZAPRET_NFT_TABLE postrouting { type filter hook postrouting priority 101; }
add chain inet $ZAPRET_NFT_TABLE postrouting { type filter hook postrouting priority 99; }
flush chain inet $ZAPRET_NFT_TABLE postrouting
add chain inet $ZAPRET_NFT_TABLE predefrag { type filter hook output priority -401; }
flush chain inet $ZAPRET_NFT_TABLE predefrag
add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 notrack comment "do not track nfqws generated packets to avoid nat tampering and defragmentation"
add set inet $ZAPRET_NFT_TABLE lanif { type ifname; }
add set inet $ZAPRET_NFT_TABLE wanif { type ifname; }
add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; }
add map inet $ZAPRET_NFT_TABLE link_local { type ifname : ipv6_addr; }
EOF
# unfortunately this approach breaks udp desync of the connection initiating packet (new, first one)
# however without notrack ipfrag will not work
# postrouting priority : 99 - before srcnat, 101 - after srcnat
# add chain inet $ZAPRET_NFT_TABLE predefrag { type filter hook output priority -401; }
# flush chain inet $ZAPRET_NFT_TABLE predefrag
# add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 notrack comment "do not track nfqws generated packets to avoid nat tampering and defragmentation"
}
nft_del_chains()
{
@ -206,6 +210,14 @@ nft_add_nfqws_flow_exempt_rule()
# do not need this because of oifname @wanif/@wanif6 filter in forward chain
#nft_add_rule flow_offload $(nft_reverse_nfqws_rule $1) return comment \"reverse flow offloading exemption\"
}
nft_add_flow_offload_exemption()
{
# "$1" - rule for ipv4
# "$2" - rule for ipv6
# "$3" - comment
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || nft_add_rule flow_offload oifname @wanif $1 ip daddr != @nozapret return comment \"$3\"
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || nft_add_rule flow_offload oifname @wanif6 $2 ip6 daddr != @nozapret6 return comment \"$3\"
}
nft_hw_offload_supported()
{
@ -351,7 +363,7 @@ _nft_fw_tpws4()
# $2 - tpws port
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV4" = "1" ] || {
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
local filter="$1" port="$2"
nft_print_op "$filter" "tpws (port $2)" 4
nft_add_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif }$filter ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$port
@ -366,7 +378,7 @@ _nft_fw_tpws6()
# $3 - lan interface names space separated
# $4 - not-empty if wan interface filtering required
[ "$DISABLE_IPV6" = "1" ] || {
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" DNAT6 i
nft_print_op "$filter" "tpws (port $port)" 6
nft_add_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6 }$filter ip6 daddr != @nozapret6 dnat ip6 to [::1]:$port
@ -396,7 +408,7 @@ _nft_fw_nfqws_post4()
# $2 - queue number
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV4" = "1" ] || {
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" rule
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4
rule="${3:+oifname @wanif }$filter ip daddr != @nozapret"
@ -410,7 +422,7 @@ _nft_fw_nfqws_post6()
# $2 - queue number
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV6" = "1" ] || {
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" rule
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6"

Binary file not shown.

View File

@ -0,0 +1,66 @@
# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering
# and also sends special fake on outgoing packets with short header and udp.length>=600
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
# need to add to config : NFQWS_OPT_DESYNC_QUIC_SHORT_HEADER="--dpi-desync=fake --dpi-desync-any-protocol --dpi-desync-fake-unknown-udp=/opt/zapret/files/fake/quic_short_header.bin --dpi-desync-cutoff=n2"
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
# this hack is for russian TSPU QUIC blocking
# without additional short header fake connections randomly hang
QNUM2=$(($QNUM+10))
QNUM3=$(($QNUM+11))
zapret_custom_daemons()
{
# stop logic is managed by procd
local MODE_OVERRIDE=nfqws
local opt
start_daemons_procd
opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
run_daemon 100 $NFQWS "$opt"
opt="--qnum=$QNUM3 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC_SHORT_HEADER"
run_daemon 101 $NFQWS "$opt"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=nfqws
local f
local first_packets_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:3"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
local udplen="-m length --length 600:1500"
local short_header4="-m u32 --u32 0>>22&0x3C@8>>24&0xC0=0x40"
zapret_do_firewall_rules_ipt $1
f="-p udp --dport 443"
fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2
# this for ipv4 only. do not have access to ipv6 enabled TSPU to test
fw_nfqws_post $1 "$f $desync $udplen $short_header4" "" $QNUM3
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=nfqws
local f
local first_packets_only="ct original packets 1-3"
local desync="mark and $DESYNC_MARK == 0"
local udplen="udp length 600-1500"
local short_header4="@th,64,2 1"
zapret_apply_firewall_rules_nft
f="udp dport 443"
nft_fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2
# this for ipv4 only. do not have access to ipv6 enabled TSPU to test
nft_fw_nfqws_post $1 "$f $desync $udplen $short_header4" "" $QNUM3
# add flow offload exemption for the whole stream because we dont know when short_header rule triggers
nft_add_flow_offload_exemption "$f" "" "QUIC exemption for complex TSPU hack"
}

View File

@ -0,0 +1,66 @@
# this custom script in addition to MODE=nfqws runs desync to all QUIC initial packets, without ipset/hostlist filtering
# and also sends special fake on outgoing packets with short header and udp.length>=600
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
# need to add to config : NFQWS_OPT_DESYNC_QUIC_SHORT_HEADER="--dpi-desync=fake --dpi-desync-any-protocol --dpi-desync-fake-unknown-udp=/opt/zapret/files/fake/quic_short_header.bin --dpi-desync-cutoff=n2"
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
# this hack is for russian TSPU QUIC blocking
# without additional short header fake connections randomly hang
QNUM2=$(($QNUM+10))
QNUM3=$(($QNUM+11))
zapret_custom_daemons()
{
# stop logic is managed by procd
local MODE_OVERRIDE=nfqws
local opt
zapret_do_daemons $1
opt="--qnum=$QNUM2 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
do_nfqws $1 100 "$opt"
opt="--qnum=$QNUM3 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC_SHORT_HEADER"
do_nfqws $1 101 "$opt"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=nfqws
local f
local first_packets_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:3"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
local udplen="-m length --length 600:1500"
local short_header4="-m u32 --u32 0>>22&0x3C@8>>24&0xC0=0x40"
zapret_do_firewall_rules_ipt $1
f="-p udp --dport 443"
fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2
# this for ipv4 only. do not have access to ipv6 enabled TSPU to test
fw_nfqws_post $1 "$f $desync $udplen $short_header4" "" $QNUM3
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=nfqws
local f
local first_packets_only="ct original packets 1-3"
local desync="mark and $DESYNC_MARK == 0"
local udplen="udp length 600-1500"
local short_header4="@th,64,2 1"
zapret_apply_firewall_rules_nft
f="udp dport 443"
nft_fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM2
# this for ipv4 only. do not have access to ipv6 enabled TSPU to test
nft_fw_nfqws_post $1 "$f $desync $udplen $short_header4" "" $QNUM3
# add flow offload exemption for the whole stream because we dont know when short_header rule triggers
nft_add_flow_offload_exemption "$f" "" "QUIC exemption for complex TSPU hack"
}