mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
autohostlist mode
This commit is contained in:
@@ -89,6 +89,14 @@ filter_apply_ipset_target()
|
||||
filter_apply_ipset_target6 $2
|
||||
}
|
||||
|
||||
reverse_nfqws_rule_stream()
|
||||
{
|
||||
sed -e 's/-o /-i /g' -e 's/--dport /--sport /g' -e 's/--dports /--sports /g' -e 's/ dst$/ src/' -e 's/ dst / src /g' -e 's/--connbytes-dir=original/--connbytes-dir=reply/g' -e "s/-m mark ! --mark $DESYNC_MARK\/$DESYNC_MARK//g"
|
||||
}
|
||||
reverse_nfqws_rule()
|
||||
{
|
||||
echo "$@" | reverse_nfqws_rule_stream
|
||||
}
|
||||
|
||||
prepare_tpws_fw4()
|
||||
{
|
||||
@@ -250,14 +258,81 @@ fw_nfqws_post()
|
||||
fw_nfqws_post6 $1 "$3" $4
|
||||
}
|
||||
|
||||
_fw_nfqws_pre4()
|
||||
{
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv4
|
||||
# $3 - queue number
|
||||
# $4 - wan interface names space separated
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
|
||||
local i
|
||||
|
||||
ipt_print_op $1 "$2" "nfqws input+forward (qnum $3)"
|
||||
|
||||
rule="$2 $IPSET_EXCLUDE src -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
if [ -n "$4" ] ; then
|
||||
for i in $4; do
|
||||
# iptables PREROUTING chain is before NAT. not possible to have DNATed ip's there
|
||||
ipt_add_del $1 INPUT -t mangle -i $i $rule
|
||||
ipt_add_del $1 FORWARD -t mangle -i $i $rule
|
||||
done
|
||||
else
|
||||
ipt_add_del $1 INPUT -t mangle $rule
|
||||
ipt_add_del $1 FORWARD -t mangle $rule
|
||||
fi
|
||||
}
|
||||
}
|
||||
_fw_nfqws_pre6()
|
||||
{
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv6
|
||||
# $3 - queue number
|
||||
# $4 - wan interface names space separated
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
|
||||
local i
|
||||
|
||||
ipt_print_op $1 "$2" "nfqws input+forward (qnum $3)" 6
|
||||
|
||||
rule="$2 $IPSET_EXCLUDE6 src -j NFQUEUE --queue-num $3 --queue-bypass"
|
||||
if [ -n "$4" ] ; then
|
||||
for i in $4; do
|
||||
# iptables PREROUTING chain is before NAT. not possible to have DNATed ip's there
|
||||
ipt6_add_del $1 INPUT -t mangle -i $i $rule
|
||||
ipt6_add_del $1 FORWARD -t mangle -i $i $rule
|
||||
done
|
||||
else
|
||||
ipt6_add_del $1 INPUT -t mangle $rule
|
||||
ipt6_add_del $1 FORWARD -t mangle $rule
|
||||
fi
|
||||
}
|
||||
}
|
||||
fw_nfqws_pre()
|
||||
{
|
||||
# $1 - 1 - add, 0 - del
|
||||
# $2 - iptable filter for ipv4
|
||||
# $3 - iptable filter for ipv6
|
||||
# $4 - queue number
|
||||
fw_nfqws_pre4 $1 "$2" $4
|
||||
fw_nfqws_pre6 $1 "$3" $4
|
||||
}
|
||||
|
||||
|
||||
zapret_do_firewall_rules_ipt()
|
||||
{
|
||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||
|
||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4"
|
||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:"
|
||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||
local f4 f6 qn qns qn6 qns6
|
||||
local n f4 f6 ff qn qns qn6 qns6
|
||||
|
||||
# autohostlist mode requires incoming traffic sample
|
||||
# always use conntrack packet limiter or nfqws will deal with gigabytes
|
||||
if [ "$MODE_FILTER" = "autohostlist" ]; then
|
||||
n=$((4+${AUTOHOSTLIST_RETRANS_THRESHOLD:-3}))
|
||||
else
|
||||
n=4
|
||||
fi
|
||||
first_packet_only="${first_packet_only}$n"
|
||||
|
||||
case "$mode" in
|
||||
tpws)
|
||||
@@ -279,17 +354,23 @@ zapret_do_firewall_rules_ipt()
|
||||
f4="$f4 $first_packet_only"
|
||||
filter_apply_ipset_target4 f4
|
||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre4 $1 "$(reverse_nfqws_rule $f4)" $qn
|
||||
else
|
||||
if [ -n "$qn" ]; then
|
||||
f4="-p tcp --dport 80"
|
||||
ff="$f4"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
||||
ff="$ff $first_packet_only"
|
||||
filter_apply_ipset_target4 f4
|
||||
filter_apply_ipset_target4 ff
|
||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre4 $1 "$(reverse_nfqws_rule $ff)" $qn
|
||||
fi
|
||||
if [ -n "$qns" ]; then
|
||||
f4="-p tcp --dport 443 $first_packet_only"
|
||||
filter_apply_ipset_target4 f4
|
||||
fw_nfqws_post4 $1 "$f4 $desync" $qns
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre4 $1 "$(reverse_nfqws_rule $f4)" $qns
|
||||
fi
|
||||
fi
|
||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||
@@ -297,17 +378,23 @@ zapret_do_firewall_rules_ipt()
|
||||
f6="$f6 $first_packet_only"
|
||||
filter_apply_ipset_target6 f6
|
||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre6 $1 "$(reverse_nfqws_rule $f6)" $qn
|
||||
else
|
||||
if [ -n "$qn6" ]; then
|
||||
f6="-p tcp --dport 80"
|
||||
ff="$f6"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
||||
ff="$ff $first_packet_only"
|
||||
filter_apply_ipset_target6 f6
|
||||
filter_apply_ipset_target6 ff
|
||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre6 $1 "$(reverse_nfqws_rule $ff)" $qn6
|
||||
fi
|
||||
if [ -n "$qns6" ]; then
|
||||
f6="-p tcp --dport 443 $first_packet_only"
|
||||
filter_apply_ipset_target6 f6
|
||||
fw_nfqws_post6 $1 "$f6 $desync" $qns6
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && fw_nfqws_pre6 $1 "$(reverse_nfqws_rule $f6)" $qns6
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@@ -1,3 +1,7 @@
|
||||
set_conntrack_liberal_mode()
|
||||
{
|
||||
[ -n "$SKIP_CONNTRACK_LIBERAL_MODE" ] || sysctl -w net.netfilter.nf_conntrack_tcp_be_liberal=$1
|
||||
}
|
||||
zapret_do_firewall()
|
||||
{
|
||||
linux_fwtype
|
||||
@@ -14,6 +18,13 @@ zapret_do_firewall()
|
||||
;;
|
||||
esac
|
||||
|
||||
# russian DPI sends RST,ACK with wrong ACK.
|
||||
# this is sometimes treated by conntrack as invalid and connbytes fw rules do not pass RST packet to nfqws.
|
||||
# swith on liberal mode on zapret firewall start and switch off on zapret firewall stop
|
||||
# this is only required for processing incoming bad RSTs. incoming rules are only applied in autohostlist mode
|
||||
# calling this after firewall because conntrack module can be not loaded before applying conntrack firewall rules
|
||||
[ "$MODE_FILTER" = "autohostlist" -a "$MODE" != tpws-socks ] && set_conntrack_liberal_mode $1
|
||||
|
||||
[ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK
|
||||
[ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK
|
||||
|
||||
|
@@ -13,13 +13,15 @@ find_hostlists()
|
||||
HOSTLIST_EXCLUDE="$HOSTLIST_BASE/zapret-hosts-user-exclude.txt.gz"
|
||||
[ -f "$HOSTLIST_EXCLUDE" ] || HOSTLIST_EXCLUDE="$HOSTLIST_BASE/zapret-hosts-user-exclude.txt"
|
||||
[ -f "$HOSTLIST_EXCLUDE" ] || HOSTLIST_EXCLUDE=
|
||||
|
||||
HOSTLIST_AUTO="$HOSTLIST_BASE/zapret-hosts-auto.txt"
|
||||
}
|
||||
|
||||
filter_apply_hostlist_target()
|
||||
{
|
||||
# $1 - var name of tpws or nfqws params
|
||||
|
||||
[ "$MODE_FILTER" = "hostlist" ] || return
|
||||
[ "$MODE_FILTER" = "hostlist" -o "$MODE_FILTER" = "autohostlist" ] || return
|
||||
|
||||
local HOSTLIST_BASE HOSTLIST HOSTLIST_USER HOSTLIST_EXCLUDE
|
||||
|
||||
@@ -28,4 +30,11 @@ filter_apply_hostlist_target()
|
||||
[ -n "$HOSTLIST" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
|
||||
[ -n "$HOSTLIST_USER" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST_USER\""
|
||||
[ -n "$HOSTLIST_EXCLUDE" ] && eval $1="\"\$$1 --hostlist-exclude=$HOSTLIST_EXCLUDE\""
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && {
|
||||
local parm1="${AUTOHOSTLIST_FAIL_THRESHOLD:+--hostlist-auto-fail-threshold=$AUTOHOSTLIST_FAIL_THRESHOLD}"
|
||||
local parm2="${AUTOHOSTLIST_FAIL_TIME:+--hostlist-auto-fail-time=$AUTOHOSTLIST_FAIL_TIME}"
|
||||
local parm3
|
||||
[ "$MODE" = "tpws" -o "$MODE" = "tpws-socks" ] || parm3="${AUTOHOSTLIST_RETRANS_THRESHOLD:+--hostlist-auto-retrans-threshold=$AUTOHOSTLIST_RETRANS_THRESHOLD}"
|
||||
eval $1="\"\$$1 --hostlist-auto=$HOSTLIST_AUTO $parm1 $parm2 $parm3\""
|
||||
}
|
||||
}
|
||||
|
@@ -63,10 +63,8 @@ nft_del_all_chains_from_table()
|
||||
|
||||
nft_create_chains()
|
||||
{
|
||||
# NOTE : postrouting hook has priority 101 to hook packets already processed by nat
|
||||
# NOTE : this is the only way to implement ipfrag for forwarded packets if nat is present
|
||||
# NOTE : to avoid retracking and sport changing use notrack for nfqws generated packets
|
||||
# NOTE : this also prevents defragmentation of ipv6 fragmented frames in kernels 4.16+
|
||||
# NOTE : postrouting hook has priority 99 to hook packets with original source but NATed destination
|
||||
# NOTE : prerouting hook has priority -99 for the same reason
|
||||
cat << EOF | nft -f -
|
||||
add chain inet $ZAPRET_NFT_TABLE dnat_output { type nat hook output priority -101; }
|
||||
flush chain inet $ZAPRET_NFT_TABLE dnat_output
|
||||
@@ -84,6 +82,7 @@ cat << EOF | nft -f -
|
||||
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 99; }
|
||||
add chain inet $ZAPRET_NFT_TABLE prerouting { type filter hook prerouting priority -99; }
|
||||
flush chain inet $ZAPRET_NFT_TABLE postrouting
|
||||
add set inet $ZAPRET_NFT_TABLE lanif { type ifname; }
|
||||
add set inet $ZAPRET_NFT_TABLE wanif { type ifname; }
|
||||
@@ -109,6 +108,7 @@ cat << EOF | nft -f - 2>/dev/null
|
||||
delete chain inet $ZAPRET_NFT_TABLE forward
|
||||
delete chain inet $ZAPRET_NFT_TABLE input
|
||||
delete chain inet $ZAPRET_NFT_TABLE postrouting
|
||||
delete chain inet $ZAPRET_NFT_TABLE prerouting
|
||||
delete chain inet $ZAPRET_NFT_TABLE flow_offload
|
||||
delete chain inet $ZAPRET_NFT_TABLE localnet_protect
|
||||
EOF
|
||||
@@ -202,7 +202,7 @@ nft_reverse_nfqws_rule()
|
||||
}
|
||||
nft_clean_nfqws_rule()
|
||||
{
|
||||
echo "$@" | sed -e "s/mark and $DESYNC_MARK == 0//g"
|
||||
echo "$@" | sed -e "s/mark and $DESYNC_MARK == 0//g" -e "s/oifname @wanif6//g" -e "s/oifname @wanif//g"
|
||||
}
|
||||
nft_add_nfqws_flow_exempt_rule()
|
||||
{
|
||||
@@ -464,6 +464,64 @@ nft_fw_nfqws_post()
|
||||
nft_fw_nfqws_post6 "$2" $3
|
||||
}
|
||||
|
||||
_nft_fw_nfqws_pre4()
|
||||
{
|
||||
# $1 - filter ipv4
|
||||
# $2 - queue number
|
||||
# $3 - not-empty if wan interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule
|
||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
|
||||
rule="${3:+iifname @wanif }$filter ip saddr != @nozapret"
|
||||
nft_add_rule prerouting $rule queue num $port bypass
|
||||
}
|
||||
}
|
||||
_nft_fw_nfqws_pre6()
|
||||
{
|
||||
# $1 - filter ipv6
|
||||
# $2 - queue number
|
||||
# $3 - not-empty if wan interface filtering required
|
||||
|
||||
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
|
||||
local filter="$1" port="$2" rule
|
||||
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
|
||||
rule="${3:+iifname @wanif6 }$filter ip6 saddr != @nozapret6"
|
||||
nft_add_rule prerouting $rule queue num $port bypass
|
||||
}
|
||||
}
|
||||
nft_fw_nfqws_pre()
|
||||
{
|
||||
# $1 - filter ipv4
|
||||
# $2 - filter ipv6
|
||||
# $3 - queue number
|
||||
|
||||
nft_fw_nfqws_pre4 "$1" $3
|
||||
nft_fw_nfqws_pre6 "$2" $3
|
||||
}
|
||||
|
||||
nft_fw_nfqws_both4()
|
||||
{
|
||||
# $1 - filter ipv4
|
||||
# $2 - queue number
|
||||
nft_fw_nfqws_post4 "$@"
|
||||
nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $1)" $2
|
||||
}
|
||||
nft_fw_nfqws_both6()
|
||||
{
|
||||
# $1 - filter ipv6
|
||||
# $2 - queue number
|
||||
nft_fw_nfqws_post6 "$@"
|
||||
nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $1)" $2
|
||||
}
|
||||
nft_fw_nfqws_both()
|
||||
{
|
||||
# $1 - filter ipv4
|
||||
# $2 - filter ipv6
|
||||
# $3 - queue number
|
||||
nft_fw_nfqws_both4 "$1" "$3"
|
||||
nft_fw_nfqws_both6 "$2" "$3"
|
||||
}
|
||||
|
||||
zapret_reload_ifsets()
|
||||
{
|
||||
@@ -485,9 +543,18 @@ zapret_apply_firewall_rules_nft()
|
||||
{
|
||||
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||
|
||||
local first_packet_only="ct original packets 1-4"
|
||||
local first_packet_only
|
||||
local desync="mark and $DESYNC_MARK == 0"
|
||||
local f4 f6 qn qns qn6 qns6
|
||||
local f4 f6 ff qn qns qn6 qns6
|
||||
|
||||
# autohostlist mode requires incoming traffic sample
|
||||
# always use conntrack packet limiter or nfqws will deal with gigabytes
|
||||
if [ "$MODE_FILTER" = "autohostlist" ]; then
|
||||
first_packet_only=$((4+${AUTOHOSTLIST_RETRANS_THRESHOLD:-3}))
|
||||
else
|
||||
first_packet_only=4
|
||||
fi
|
||||
first_packet_only="ct original packets 1-$first_packet_only"
|
||||
|
||||
case "$mode" in
|
||||
tpws)
|
||||
@@ -508,17 +575,23 @@ zapret_apply_firewall_rules_nft()
|
||||
f4="$f4 $first_packet_only"
|
||||
nft_filter_apply_ipset_target4 f4
|
||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $f4)" $qn
|
||||
else
|
||||
if [ -n "$qn" ]; then
|
||||
f4="tcp dport 80"
|
||||
ff="$f4"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
||||
ff="$ff $first_packet_only"
|
||||
nft_filter_apply_ipset_target4 f4
|
||||
nft_filter_apply_ipset_target4 ff
|
||||
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $ff)" $qn
|
||||
fi
|
||||
if [ -n "$qns" ]; then
|
||||
f4="tcp dport 443 $first_packet_only"
|
||||
nft_filter_apply_ipset_target4 f4
|
||||
nft_fw_nfqws_post4 "$f4 $desync" $qns
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $f4)" $qns
|
||||
fi
|
||||
fi
|
||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||
@@ -526,17 +599,23 @@ zapret_apply_firewall_rules_nft()
|
||||
f6="$f6 $first_packet_only"
|
||||
nft_filter_apply_ipset_target6 f6
|
||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $f6)" $qn
|
||||
else
|
||||
if [ -n "$qn6" ]; then
|
||||
f6="tcp dport 80"
|
||||
ff="$f6"
|
||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
||||
ff="$ff $first_packet_only"
|
||||
nft_filter_apply_ipset_target6 f6
|
||||
nft_filter_apply_ipset_target6 ff
|
||||
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $ff)" $qn6
|
||||
fi
|
||||
if [ -n "$qns6" ]; then
|
||||
f6="tcp dport 443 $first_packet_only"
|
||||
nft_filter_apply_ipset_target6 f6
|
||||
nft_fw_nfqws_post6 "$f6 $desync" $qns6
|
||||
[ "$MODE_FILTER" = "autohostlist" ] && nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $f6)" $qns6
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@@ -1,3 +1,12 @@
|
||||
apply_unspecified_desync_modes()
|
||||
{
|
||||
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}"
|
||||
NFQWS_OPT_DESYNC_QUIC6="${NFQWS_OPT_DESYNC_QUIC6:-$NFQWS_OPT_DESYNC_QUIC}"
|
||||
}
|
||||
|
||||
get_nfqws_qnums()
|
||||
{
|
||||
# $1 - var name for ipv4 http
|
||||
|
Reference in New Issue
Block a user