blockcheck: optimize fw scheme, enable udp ipfrag tests

This commit is contained in:
bol-van 2024-03-15 14:49:59 +03:00
parent b05a18a53c
commit 1030588943

View File

@ -143,6 +143,10 @@ IPT_DEL()
{ {
$IPTABLES -C "$@" >/dev/null 2>/dev/null && $IPTABLES -D "$@" $IPTABLES -C "$@" >/dev/null 2>/dev/null && $IPTABLES -D "$@"
} }
IPT_ADD_DEL()
{
on_off_function IPT IPT_DEL "$@"
}
IPFW_ADD() IPFW_ADD()
{ {
ipfw -qf add $IPFW_RULE_NUM "$@" ipfw -qf add $IPFW_RULE_NUM "$@"
@ -199,7 +203,6 @@ check_system()
Linux) Linux)
PKTWS="$NFQWS" PKTWS="$NFQWS"
PKTWSD=nfqws PKTWSD=nfqws
LO_IFACE=lo
linux_fwtype linux_fwtype
[ "$FWTYPE" = iptables -o "$FWTYPE" = nftables ] || { [ "$FWTYPE" = iptables -o "$FWTYPE" = nftables ] || {
echo firewall type $FWTYPE not supported in $UNAME echo firewall type $FWTYPE not supported in $UNAME
@ -210,20 +213,17 @@ check_system()
PKTWS="$DVTWS" PKTWS="$DVTWS"
PKTWSD=dvtws PKTWSD=dvtws
FWTYPE=ipfw FWTYPE=ipfw
LO_IFACE=lo0
[ -f /etc/platform ] && read SUBSYS </etc/platform [ -f /etc/platform ] && read SUBSYS </etc/platform
;; ;;
OpenBSD) OpenBSD)
PKTWS="$DVTWS" PKTWS="$DVTWS"
PKTWSD=dvtws PKTWSD=dvtws
FWTYPE=opf FWTYPE=opf
LO_IFACE=lo0
;; ;;
Darwin) Darwin)
PKTWS="$DVTWS" PKTWS="$DVTWS"
PKTWSD=dvtws PKTWSD=dvtws
FWTYPE=mpf FWTYPE=mpf
LO_IFACE=lo0
;; ;;
*) *)
echo $UNAME not supported echo $UNAME not supported
@ -497,130 +497,128 @@ curl_test_http3()
curl_with_dig $1 $2 -ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME --http3-only $CURL_OPT "https://$2" -o /dev/null 2>&1 curl_with_dig $1 $2 -ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME --http3-only $CURL_OPT "https://$2" -o /dev/null 2>&1
} }
pktws_ipt_prepare_tcp() ipt_scheme()
{ {
# $1 - port # $1 - 1 - add , 0 - del
case "$FWTYPE" in # $2 - tcp/udp
iptables) # $3 - port
IPT_ADD_DEL $1 OUTPUT -t mangle -p $2 --dport $3 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
# to avoid possible INVALID state drop # to avoid possible INVALID state drop
IPT INPUT -p tcp --sport $1 ! --syn -j ACCEPT [ "$2" = tcp ] && IPT_ADD_DEL $1 INPUT -p $2 --sport $3 ! --syn -j ACCEPT
IPT OUTPUT -p tcp --dport $1 -m conntrack --ctstate INVALID -j ACCEPT # for strategies with incoming packets involved (autottl)
IPT_ADD_DEL $1 OUTPUT -p $2 --dport $3 -m conntrack --ctstate INVALID -j ACCEPT
if [ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ]; then if [ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ]; then
# the only way to reliable disable ipv6 defrag. works only in 4.16+ kernels # the only way to reliable disable ipv6 defrag. works only in 4.16+ kernels
IPT OUTPUT -t raw -p tcp -m frag -j CT --notrack IPT_ADD_DEL $1 OUTPUT -t raw -p $2 -m frag -j CT --notrack
elif [ "$IPV" = 4 ]; then elif [ "$IPV" = 4 ]; then
# enable fragments # enable fragments
IPT OUTPUT -f -j ACCEPT IPT_ADD_DEL $1 OUTPUT -f -j ACCEPT
fi fi
IPT OUTPUT -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
IPT INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD) # enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
# raw table may not be present # raw table may not be present
IPT OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack IPT_ADD_DEL $1 OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack
;; }
nftables) nft_scheme()
{
# $1 - tcp/udp
# $2 - port
nft add table inet $NFT_TABLE nft add table inet $NFT_TABLE
# prenat
# [ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ] && {
# nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }"
# nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} exthdr frag exists notrack"
# }
# nft "add chain inet $NFT_TABLE premangle { type filter hook output priority -152; }"
# nft "add rule inet $NFT_TABLE premangle meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM"
# postnat. this is good because we need only output traffic
nft "add chain inet $NFT_TABLE postnat { type filter hook output priority 102; }" nft "add chain inet $NFT_TABLE postnat { type filter hook output priority 102; }"
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM" nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK != $DESYNC_MARK queue num $QNUM"
# for strategies with incoming packets involved (autottl) # for strategies with incoming packets involved (autottl)
nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }" nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }"
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 ct original packets 1 queue num $QNUM"
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD) # enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }" nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }"
nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} mark and $DESYNC_MARK !=0 notrack" nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} mark and $DESYNC_MARK !=0 notrack"
}
pktws_ipt_prepare()
{
# $1 - tcp/udp
# $2 - port
case "$FWTYPE" in
iptables)
ipt_scheme 1 $1 $2
;;
nftables)
nft_scheme $1 $2
;; ;;
ipfw) ipfw)
# disable PF to avoid interferences # disable PF to avoid interferences
pf_is_avail && pfctl -qd pf_is_avail && pfctl -qd
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to any $2 proto ip${IPV} out not diverted not sockarg
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from me to any $1 proto ip${IPV} out not diverted not sockarg
# for autottl mode
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from any $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg
;; ;;
opf) opf)
opf_prepare_dvtws tcp $1 opf_prepare_dvtws $1 $2
;;
esac
}
pktws_ipt_unprepare()
{
# $1 - tcp/udp
# $2 - port
case "$FWTYPE" in
iptables)
ipt_scheme 0 $1 $2
;;
nftables)
nft delete table inet $NFT_TABLE 2>/dev/null
;;
ipfw)
IPFW_DEL
pf_is_avail && pf_restore
;;
opf)
pf_restore
;;
esac
}
pktws_ipt_prepare_tcp()
{
# $1 - port
pktws_ipt_prepare tcp $1
case "$FWTYPE" in
iptables)
# for autottl
IPT INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
;;
nftables)
# for autottl
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 ct original packets 1 queue num $QNUM"
;;
ipfw)
# for autottl mode
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from any $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg
;; ;;
esac esac
} }
pktws_ipt_unprepare_tcp() pktws_ipt_unprepare_tcp()
{ {
# $1 - port # $1 - port
pktws_ipt_unprepare tcp $1
case "$FWTYPE" in case "$FWTYPE" in
iptables) iptables)
IPT_DEL OUTPUT -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
IPT_DEL INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM IPT_DEL INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
IPT_DEL INPUT -p tcp --sport $1 ! --syn -j ACCEPT
IPT_DEL OUTPUT -p tcp --dport $1 -m conntrack --ctstate INVALID -j ACCEPT
if [ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ]; then
IPT_DEL OUTPUT -t raw -p tcp -m frag -j CT --notrack
elif [ "$IPV" = 4 ]; then
IPT_DEL OUTPUT -f -j ACCEPT
fi
# raw table may not be present
IPT_DEL OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack
;;
nftables)
nft delete table inet $NFT_TABLE 2>/dev/null
;;
ipfw)
IPFW_DEL
pf_is_avail && pf_restore
;;
opf)
pf_restore
;; ;;
esac esac
} }
pktws_ipt_prepare_udp() pktws_ipt_prepare_udp()
{ {
# $1 - port # $1 - port
case "$FWTYPE" in
iptables)
IPT OUTPUT -t mangle -p udp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
;;
nftables)
nft add table inet $NFT_TABLE
nft "add chain inet $NFT_TABLE premangle { type filter hook output priority -152; }"
nft "add rule inet $NFT_TABLE premangle meta nfproto ipv${IPV} udp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM"
;;
ipfw)
# disable PF to avoid interferences
pf_is_avail && pfctl -qd
IPFW_ADD divert $IPFW_DIVERT_PORT udp from me to any $1 proto ip${IPV} out not diverted not sockarg pktws_ipt_prepare udp $1
;;
opf)
opf_prepare_dvtws udp $1
;;
esac
} }
pktws_ipt_unprepare_udp() pktws_ipt_unprepare_udp()
{ {
# $1 - port # $1 - port
case "$FWTYPE" in
iptables) pktws_ipt_unprepare udp $1
IPT_DEL OUTPUT -t mangle -p udp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
;;
nftables)
nft delete table inet $NFT_TABLE 2>/dev/null
;;
ipfw)
IPFW_DEL
pf_is_avail && pf_restore
;;
opf)
pf_restore
;;
esac
} }
pktws_start() pktws_start()
@ -885,10 +883,20 @@ pktws_check_domain_http3_bypass()
[ "$IPV" = 6 ] && { [ "$IPV" = 6 ] && {
f="hopbyhop destopt" f="hopbyhop destopt"
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1"
for desync in $f; do for desync in $f; do
pktws_curl_test_update $1 $2 --dpi-desync=$desync pktws_curl_test_update $1 $2 --dpi-desync=$desync
done done
} }
[ "$IPV" = 4 -o -n "$IP6_DEFRAG_DISABLE" ] && {
for frag in 8 16 24 32 40 64; do
tests="ipfrag2"
[ "$IPV" = 6 ] && tests="$tests hopbyhop,ipfrag2 destopt,ipfrag2"
for desync in $tests; do
pktws_curl_test_update $1 $2 --dpi-desync=$desync --dpi-desync-ipfrag-pos-udp=$frag
done
done
}
report_strategy $1 $2 $PKTWSD report_strategy $1 $2 $PKTWSD
} }