From 3ca682e25a624a3eb2cf38964086aaa660a0b29e Mon Sep 17 00:00:00 2001 From: bol-van Date: Sun, 4 May 2025 18:15:33 +0300 Subject: [PATCH] drop time exceeded icmp for nfqws-related connections --- blockcheck.sh | 16 +++++++++++++++- common/ipt.sh | 21 +++++++++++++++++++++ common/nft.sh | 28 +++++++++++++++++++++++----- docs/changes.txt | 3 +++ docs/iptables.txt | 1 - docs/nftables.txt | 1 - 6 files changed, 62 insertions(+), 8 deletions(-) diff --git a/blockcheck.sh b/blockcheck.sh index dd831589..ed6a452c 100755 --- a/blockcheck.sh +++ b/blockcheck.sh @@ -735,6 +735,11 @@ ipt_aux_scheme() # to avoid possible INVALID state drop [ "$2" = tcp ] && IPT_ADD_DEL $1 INPUT -p $2 --sport $3 ! --syn -j ACCEPT + + local icmp_filter="-p icmp -m icmp --icmp-type" + [ "$IPV" = 6 ] && icmp_filter="-p icmpv6 -m icmp6 --icmpv6-type" + IPT_ADD_DEL $1 INPUT $icmp_filter time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP + # 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 @@ -766,6 +771,7 @@ ipt_scheme() $IPTABLES -t mangle -A blockcheck_output -p $1 ! --dport $2 -j RETURN for ip in $3; do + $IPTABLES -t mangle -A blockcheck_output -d $ip -j CONNMARK --or-mark $DESYNC_MARK $IPTABLES -t mangle -A blockcheck_output -d $ip -j NFQUEUE --queue-num $QNUM done @@ -783,12 +789,20 @@ nft_scheme() nft add table inet $NFT_TABLE nft "add chain inet $NFT_TABLE postnat { type filter hook output priority 102; }" - nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK != $DESYNC_MARK ip${ipver} daddr {$iplist} queue num $QNUM" + nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK == 0 ip${ipver} daddr {$iplist} ct mark set ct mark or $DESYNC_MARK queue num $QNUM" # for strategies with incoming packets involved (autottl) nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }" # 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 rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} mark and $DESYNC_MARK !=0 notrack" + [ "$IPV" = 4 ] && { + nft "add rule inet $NFT_TABLE prenat icmp type time-exceeded ct mark and $DESYNC_MARK != 0 drop" + nft "add rule inet $NFT_TABLE prenat icmp type time-exceeded ct state invalid drop" + } + [ "$IPV" = 6 ] && { + nft "add rule inet $NFT_TABLE prenat icmpv6 type time-exceeded ct mark and $DESYNC_MARK != 0 drop" + nft "add rule inet $NFT_TABLE prenat icmpv6 type time-exceeded ct state invalid drop" + } } pktws_ipt_prepare() diff --git a/common/ipt.sh b/common/ipt.sh index f170ef6b..5e6184bc 100644 --- a/common/ipt.sh +++ b/common/ipt.sh @@ -391,6 +391,27 @@ zapret_do_firewall_rules_ipt() zapret_do_firewall_standard_rules_ipt $1 custom_runner zapret_custom_firewall $1 + zapret_do_icmp_filter $1 +} + +zapret_do_icmp_filter() +{ + # $1 - 1 - add, 0 - del + + local FW_EXTRA_PRE= FW_EXTRA_POST= + + [ "$FILTER_TTL_EXPIRED_ICMP" = 1 ] && { + [ "$DISABLE_IPV4" = 1 ] || { + ipt_add_del $1 POSTROUTING -t mangle -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CONNMARK --or-mark $DESYNC_MARK + ipt_add_del $1 INPUT -p icmp -m icmp --icmp-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP + ipt_add_del $1 FORWARD -p icmp -m icmp --icmp-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP + } + [ "$DISABLE_IPV6" = 1 ] || { + ipt6_add_del $1 POSTROUTING -t mangle -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CONNMARK --or-mark $DESYNC_MARK + ipt6_add_del $1 INPUT -p icmpv6 -m icmp6 --icmpv6-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP + ipt6_add_del $1 FORWARD -p icmpv6 -m icmp6 --icmpv6-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP + } + } } zapret_do_firewall_ipt() diff --git a/common/nft.sh b/common/nft.sh index fab4da36..d5b6c9bc 100644 --- a/common/nft.sh +++ b/common/nft.sh @@ -106,7 +106,7 @@ cat << EOF | nft -f - flush chain inet $ZAPRET_NFT_TABLE predefrag_nfqws add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 jump predefrag_nfqws comment "nfqws generated : avoid drop by INVALID conntrack state" add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws mark and $DESYNC_MARK_POSTNAT !=0 notrack comment "postnat traffic" - add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws ip frag-off != 0 notrack comment "ipfrag" + add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws ip frag-off & 0x1fff != 0 notrack comment "ipfrag" add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws exthdr frag exists notrack comment "ipfrag" add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws tcp flags ! syn,rst,ack notrack comment "datanoack" add set inet $ZAPRET_NFT_TABLE lanif { type ifname; } @@ -119,6 +119,20 @@ EOF nft_flush_chain predefrag_nfqws nft_add_rule predefrag_nfqws notrack comment \"do not track nfqws generated packets to avoid nat tampering and defragmentation\" } + [ "$FILTER_TTL_EXPIRED_ICMP" = 1 ] && { + if is_postnat; then + # can be caused by untracked nfqws-generated packets + nft_add_rule prerouting icmp type time-exceeded ct state invalid drop + else + nft_add_rule postrouting_hook mark and $DESYNC_MARK != 0 ct mark set ct mark or $DESYNC_MARK comment \"nfqws related : prevent ttl expired socket errors\" + fi + [ "$DISABLE_IPV4" = "1" ] || { + nft_add_rule prerouting icmp type time-exceeded ct mark and $DESYNC_MARK != 0 drop comment \"nfqws related : prevent ttl expired socket errors\" + } + [ "$DISABLE_IPV6" = "1" ] || { + nft_add_rule prerouting icmpv6 type time-exceeded ct mark and $DESYNC_MARK != 0 drop comment \"nfqws related : prevent ttl expired socket errors\" + } + } } nft_del_chains() { @@ -456,7 +470,7 @@ _nft_fw_nfqws_post4() nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4 rule="${3:+oifname @wanif }$filter ip daddr != @nozapret" is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT" - nft_insert_rule $chain $rule $setmark $FW_EXTRA_POST queue num $port bypass + nft_insert_rule $chain $rule $setmark $CONNMARKER $FW_EXTRA_POST queue num $port bypass nft_add_nfqws_flow_exempt_rule "$rule" } } @@ -471,7 +485,7 @@ _nft_fw_nfqws_post6() nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6 rule="${3:+oifname @wanif6 }$filter ip6 daddr != @nozapret6" is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT" - nft_insert_rule $chain $rule $setmark $FW_EXTRA_POST queue num $port bypass + nft_insert_rule $chain $rule $setmark $CONNMARKER $FW_EXTRA_POST queue num $port bypass nft_add_nfqws_flow_exempt_rule "$rule" } } @@ -495,7 +509,7 @@ _nft_fw_nfqws_pre4() local filter="$1" port="$2" rule nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4 rule="${3:+iifname @wanif }$filter ip saddr != @nozapret" - nft_insert_rule $(get_prechain) $rule $FW_EXTRA_POST queue num $port bypass + nft_insert_rule $(get_prechain) $rule $CONNMARKER $FW_EXTRA_POST queue num $port bypass } } _nft_fw_nfqws_pre6() @@ -508,7 +522,7 @@ _nft_fw_nfqws_pre6() local filter="$1" port="$2" rule nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6 rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6" - nft_insert_rule $(get_prechain) $rule $FW_EXTRA_POST queue num $port bypass + nft_insert_rule $(get_prechain) $rule $CONNMARKER $FW_EXTRA_POST queue num $port bypass } } nft_fw_nfqws_pre() @@ -686,3 +700,7 @@ zapret_do_firewall_nft() return 0 } + +# ctmark is not available in POSTNAT mode +CONNMARKER= +[ "$FILTER_TTL_EXPIRED_ICMP" = 1 ] && is_postnat && CONNMARKER="ct mark set ct mark or $DESYNC_MARK" diff --git a/docs/changes.txt b/docs/changes.txt index 2de6d31c..b56d77a6 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -489,4 +489,7 @@ nfqws: --dpi-desync-fake-tls=! means default tls fake nfqws: --dup* nfqws: --orig* nfqws: ipcache of hop count and host names +tpws: ipcache of host names +nfqws,tpws: set 1024 repeat limit to fakes and dups init.d: remove --ipset parameter prohibition +init.d, blockcheck: drop time exceeded icmp for nfqws-related connections diff --git a/docs/iptables.txt b/docs/iptables.txt index 397554a3..742f926c 100644 --- a/docs/iptables.txt +++ b/docs/iptables.txt @@ -13,7 +13,6 @@ iptables -t mangle -I POSTROUTING -p udp --dport 443 -m mark ! --mark 0x40000000 sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 iptables -t mangle -I POSTROUTING -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:12 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I PREROUTING -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:3 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass -iptables -t mangle -I PREROUTING -p udp -m multiport --sports 443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:1 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass For TPROXY : diff --git a/docs/nftables.txt b/docs/nftables.txt index 243f8701..43f21504 100644 --- a/docs/nftables.txt +++ b/docs/nftables.txt @@ -26,7 +26,6 @@ nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct orig sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 nft add chain inet ztest pre "{type filter hook prerouting priority filter;}" nft add rule inet ztest pre tcp sport "{80,443}" ct reply packets 1-3 queue num 200 bypass -nft add rule inet ztest pre udp sport 443 ct reply packets 1 queue num 200 bypass show rules : nft list table inet ztest