blockcheck: nftables support

This commit is contained in:
bol-van 2022-02-10 22:30:50 +03:00
parent 2bdbb4584d
commit 75a81afa39

View File

@ -23,6 +23,8 @@ ZAPRET_BASE="$EXEDIR"
HDRTEMP=/tmp/zapret-hdr.txt HDRTEMP=/tmp/zapret-hdr.txt
ECHON="echo -n" ECHON="echo -n"
NFT_TABLE=blockcheck
[ -n "$DNSCHECK_DNS" ] || DNSCHECK_DNS="8.8.8.8 1.1.1.1 77.88.8.1" [ -n "$DNSCHECK_DNS" ] || DNSCHECK_DNS="8.8.8.8 1.1.1.1 77.88.8.1"
[ -n "$DNSCHECK_DOM" ] || DNSCHECK_DOM="pornhub.com putinhuylo.com rutracker.org nnmclub.to startmail.com" [ -n "$DNSCHECK_DOM" ] || DNSCHECK_DOM="pornhub.com putinhuylo.com rutracker.org nnmclub.to startmail.com"
DNSCHECK_DIG1=/tmp/dig1.txt DNSCHECK_DIG1=/tmp/dig1.txt
@ -139,6 +141,17 @@ ipt_has_nfq()
done done
return 0 return 0
} }
nft_has_nfq()
{
local res=1
nft delete table ${NFT_TABLE}_test 2>/dev/null
nft add table ${NFT_TABLE}_test 2>/dev/null && {
nft add chain ${NFT_TABLE}_test test
nft add rule ${NFT_TABLE}_test test queue num $QNUM bypass 2>/dev/null && res=0
nft delete table ${NFT_TABLE}_test
}
return $res
}
check_system() check_system()
{ {
@ -146,6 +159,7 @@ check_system()
UNAME=$(uname) UNAME=$(uname)
SUBSYS= SUBSYS=
FWTYPE=
case "$UNAME" in case "$UNAME" in
Linux) Linux)
@ -154,17 +168,38 @@ check_system()
local INIT=$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1) local INIT=$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)
[ -L "$INIT" ] && INIT=$(readlink "$INIT") [ -L "$INIT" ] && INIT=$(readlink "$INIT")
INIT=$(basename "$INIT") INIT=$(basename "$INIT")
[ -f "/etc/openwrt_release" ] && exists opkg && exists uci && [ "$INIT" = "procd" ] && SUBSYS=openwrt if [ -f "/etc/openwrt_release" ] && exists opkg && exists uci && [ "$INIT" = "procd" ] ; then
SUBSYS=openwrt
# new openwrt version abandon iptables and use nftables instead
# no iptables/ip6tables/ipt-kmods are installed by default
# fw4 firewall is used, fw3 is symbolic link to fw4
# no more firewall includes
# make sure nft was not just installed by user but all the system is based on fw4
if [ -x /sbin/fw4 ] && exists nft; then
FWTYPE=nftables
else
FWTYPE=iptables
fi
else
# generic linux
if exists nft; then
FWTYPE=nftables
else
FWTYPE=iptables
fi
fi
;; ;;
FreeBSD) FreeBSD)
PKTWS="$DVTWS" PKTWS="$DVTWS"
PKTWSD=dvtws PKTWSD=dvtws
FWTYPE=ipfw
;; ;;
*) *)
echo $UNAME not supported echo $UNAME not supported
exitp 5 exitp 5
esac esac
echo $UNAME${SUBSYS:+/$SUBSYS} detected echo $UNAME${SUBSYS:+/$SUBSYS} detected
echo firewall type is $FWTYPE
} }
freebsd_module_loaded() freebsd_module_loaded()
@ -194,12 +229,23 @@ check_prerequisites()
local prog progs='curl' local prog progs='curl'
case "$UNAME" in case "$UNAME" in
Linux) Linux)
progs="$progs iptables ip6tables" case "$FWTYPE" in
ipt_has_nfq || { iptables)
echo NFQUEUE iptables or ip6tables target is missing. pls install modules. progs="$progs iptables ip6tables"
[ "$SUBSYS" = openwrt ] && echo 'OpenWRT : opkg update ; opkg install iptables-mod-nfqueue' ipt_has_nfq || {
exitp 6 echo NFQUEUE iptables or ip6tables target is missing. pls install modules.
} [ "$SUBSYS" = openwrt ] && echo 'OpenWRT : opkg update ; opkg install iptables-mod-nfqueue'
exitp 6
}
;;
nftables)
nft_has_nfq || {
echo nftables queue support is not available. pls install modules.
[ "$SUBSYS" = openwrt ] && echo 'OpenWRT : opkg update ; opkg install kmod-nft-queue'
exitp 6
}
;;
esac
;; ;;
FreeBSD) FreeBSD)
progs="$progs ipfw" progs="$progs ipfw"
@ -340,8 +386,8 @@ curl_test_https_tls13()
pktws_ipt_prepare() pktws_ipt_prepare()
{ {
# $1 - port # $1 - port
case "$UNAME" in case "$FWTYPE" in
Linux) iptables)
# to avoid possible INVALID state drop # to avoid possible INVALID state drop
IPT INPUT -p tcp --sport $1 ! --syn -j ACCEPT IPT INPUT -p tcp --sport $1 ! --syn -j ACCEPT
IPT OUTPUT -p tcp --dport $1 -m conntrack --ctstate INVALID -j ACCEPT IPT OUTPUT -p tcp --dport $1 -m conntrack --ctstate INVALID -j ACCEPT
@ -352,19 +398,27 @@ pktws_ipt_prepare()
# enable fragments # enable fragments
IPT OUTPUT -f -j ACCEPT IPT OUTPUT -f -j ACCEPT
fi fi
IPT POSTROUTING -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM IPT POSTROUTING -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
;; ;;
FreeBSD) nftables)
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from me to any 80,443 proto ip${IPV} out not diverted not sockarg nft add table inet $NFT_TABLE
[ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ] && {
nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -401; }"
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 -151; }"
nft "add rule inet $NFT_TABLE premangle meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM bypass"
;;
ipfw)
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from me to any $1 proto ip${IPV} out not diverted not sockarg
;; ;;
esac esac
} }
pktws_ipt_unprepare() pktws_ipt_unprepare()
{ {
# $1 - port # $1 - port
case "$UNAME" in case "$FWTYPE" in
Linux) iptables)
IPT_DEL POSTROUTING -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM IPT_DEL POSTROUTING -t mangle -p tcp --dport $1 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
IPT_DEL INPUT -p tcp --sport $1 ! --syn -j ACCEPT IPT_DEL INPUT -p tcp --sport $1 ! --syn -j ACCEPT
@ -375,7 +429,10 @@ pktws_ipt_unprepare()
IPT_DEL OUTPUT -f -j ACCEPT IPT_DEL OUTPUT -f -j ACCEPT
fi fi
;; ;;
FreeBSD) nftables)
nft delete table inet $NFT_TABLE 2>/dev/null
;;
ipfw)
IPFW_DEL IPFW_DEL
;; ;;
esac esac
@ -383,23 +440,32 @@ pktws_ipt_unprepare()
tpws_ipt_prepare() tpws_ipt_prepare()
{ {
# $1 - port # $1 - port
case "$UNAME" in case "$FWTYPE" in
Linux) iptables)
IPT OUTPUT -t nat -p tcp --dport $1 -m owner ! --uid-owner $TPWS_UID -j DNAT --to $LOCALHOST_IPT:$TPPORT IPT OUTPUT -t nat -p tcp --dport $1 -m owner ! --uid-owner $TPWS_UID -j DNAT --to $LOCALHOST_IPT:$TPPORT
;; ;;
FreeBSD) nftables)
IPFW_ADD fwd $LOCALHOST,$TPPORT tcp from me to any 80,443 proto ip${IPV} not uid $TPWS_UID nft add table inet $NFT_TABLE
# -101 = pre dstnat
nft "add chain inet $NFT_TABLE output { type nat hook output priority -101; }"
nft "add rule inet $NFT_TABLE output tcp dport $1 skuid != $TPWS_UID dnat ip${IPVV} to $LOCALHOST_IPT:$TPPORT"
;;
ipfw)
IPFW_ADD fwd $LOCALHOST,$TPPORT tcp from me to any $1 proto ip${IPV} not uid $TPWS_UID
;; ;;
esac esac
} }
tpws_ipt_unprepare() tpws_ipt_unprepare()
{ {
# $1 - port # $1 - port
case "$UNAME" in case "$FWTYPE" in
Linux) iptables)
IPT_DEL OUTPUT -t nat -p tcp --dport $1 -m owner ! --uid-owner $TPWS_UID -j DNAT --to $LOCALHOST_IPT:$TPPORT IPT_DEL OUTPUT -t nat -p tcp --dport $1 -m owner ! --uid-owner $TPWS_UID -j DNAT --to $LOCALHOST_IPT:$TPPORT
;; ;;
FreeBSD) nftables)
nft delete table inet $NFT_TABLE 2>/dev/null
;;
ipfw)
IPFW_DEL IPFW_DEL
;; ;;
esac esac
@ -710,14 +776,16 @@ check_domain_https_tls13()
configure_ip_version() configure_ip_version()
{ {
if [ "$IPV" = 6 ]; then if [ "$IPV" = 6 ]; then
IPTABLES=ip6tables
LOCALHOST=::1 LOCALHOST=::1
LOCALHOST_IPT=[::1] LOCALHOST_IPT=[${LOCALHOST}]
IPVV=6
else else
IPTABLES=iptables IPTABLES=iptables
LOCALHOST=127.0.0.1 LOCALHOST=127.0.0.1
LOCALHOST_IPT=127.0.0.1 LOCALHOST_IPT=$LOCALHOST
IPVV=
fi fi
IPTABLES=ip${IPVV}tables
} }
configure_curl_opt() configure_curl_opt()
{ {
@ -731,40 +799,49 @@ configure_curl_opt()
curl_supports_tls13 && TLS13=1 curl_supports_tls13 && TLS13=1
} }
linux_ipv6_defrag_can_be_disabled()
{
local V1=$(sed -nre 's/^Linux version ([0-9]+)\.[0-9]+.*$/\1/p' /proc/version)
local V2=$(sed -nre 's/^Linux version [0-9]+\.([0-9]+).*$/\1/p' /proc/version)
[ -n "$V1" -a -n "$V2" ] && [ "$V1" -gt 4 -o "$V1" = 4 -a "$V2" -ge 16 ]
}
configure_defrag() configure_defrag()
{ {
case "$UNAME" in IP6_DEFRAG_DISABLE=
Linux)
IP6_DEFRAG_DISABLE= [ "$IPVS" = 4 ] && return
[ "$IPVS" = 6 -o "$IPVS" = "4 6" ] && {
local V1=$(sed -nre 's/^Linux version ([0-9]+)\.[0-9]+.*$/\1/p' /proc/version) [ "$UNAME" = "Linux" ] && {
local V2=$(sed -nre 's/^Linux version [0-9]+\.([0-9]+).*$/\1/p' /proc/version) linux_ipv6_defrag_can_be_disabled || {
if [ "$V1" -gt 4 -o "$V1" = 4 -a "$V2" -ge 16 ]; then echo "WARNING ! ipv6 defrag can only be effectively disabled in linux kernel 4.16+"
if ipt6_has_raw ; then echo "WARNING ! ipv6 ipfrag tests are disabled"
if ipt6_has_frag; then echo
IP6_DEFRAG_DISABLE=1 return
else }
echo "WARNING ! ip6tables does not have '-m frag' module, ipv6 ipfrag tests are disabled" }
echo
fi case "$FWTYPE" in
else iptables)
echo "WARNING ! ip6tables raw table is not available, ipv6 ipfrag tests are disabled" if ipt6_has_raw ; then
echo if ipt6_has_frag; then
fi IP6_DEFRAG_DISABLE=1
else else
echo "WARNING ! ipv6 defrag can only be effectively disabled in linux kernel 4.16+" echo "WARNING ! ip6tables does not have '-m frag' module, ipv6 ipfrag tests are disabled"
echo "WARNING ! ipv6 ipfrag tests are disabled"
echo echo
fi fi
[ -n "$IP6_DEFRAG_DISABLE" ] && { else
local ipexe="$(readlink -f $(whichq ip6tables))" echo "WARNING ! ip6tables raw table is not available, ipv6 ipfrag tests are disabled"
if [ "${ipexe#*nft}" != "$ipexe" ]; then echo
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6tables-nft is used. current ip6tables point to : $ipexe" fi
else [ -n "$IP6_DEFRAG_DISABLE" ] && {
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6table_raw kernel module is not loaded with parameter : raw_before_defrag=1" local ipexe="$(readlink -f $(whichq ip6tables))"
fi if [ "${ipexe#*nft}" != "$ipexe" ]; then
echo echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6tables-nft is used. current ip6tables point to : $ipexe"
} else
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6table_raw kernel module is not loaded with parameter : raw_before_defrag=1"
fi
echo
} }
;; ;;
*) *)