mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 20:20:53 +03:00
nftables support
This commit is contained in:
parent
b7aa3a878c
commit
95667733a6
101
blockcheck.sh
101
blockcheck.sh
@ -4,6 +4,12 @@ EXEDIR="$(dirname "$0")"
|
|||||||
EXEDIR="$(cd "$EXEDIR"; pwd)"
|
EXEDIR="$(cd "$EXEDIR"; pwd)"
|
||||||
ZAPRET_BASE="$EXEDIR"
|
ZAPRET_BASE="$EXEDIR"
|
||||||
|
|
||||||
|
[ -f "$ZAPRET_BASE/config" ] && . "$ZAPRET_BASE/config"
|
||||||
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
. "$ZAPRET_BASE/common/dialog.sh"
|
||||||
|
. "$ZAPRET_BASE/common/elevate.sh"
|
||||||
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
|
|
||||||
[ -n "$QNUM" ] || QNUM=59780
|
[ -n "$QNUM" ] || QNUM=59780
|
||||||
[ -n "$TPPORT" ] || TPPORT=993
|
[ -n "$TPPORT" ] || TPPORT=993
|
||||||
[ -n "$TPWS_UID" ] || TPWS_UID=1
|
[ -n "$TPWS_UID" ] || TPWS_UID=1
|
||||||
@ -32,14 +38,6 @@ DNSCHECK_DIG2=/tmp/dig2.txt
|
|||||||
DNSCHECK_DIGS=/tmp/digs.txt
|
DNSCHECK_DIGS=/tmp/digs.txt
|
||||||
|
|
||||||
|
|
||||||
exists()
|
|
||||||
{
|
|
||||||
which $1 >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
whichq()
|
|
||||||
{
|
|
||||||
which $1 2>/dev/null
|
|
||||||
}
|
|
||||||
killwait()
|
killwait()
|
||||||
{
|
{
|
||||||
# $1 - signal (-9, -2, ...)
|
# $1 - signal (-9, -2, ...)
|
||||||
@ -59,53 +57,6 @@ exitp()
|
|||||||
exit $1
|
exit $1
|
||||||
}
|
}
|
||||||
|
|
||||||
read_yes_no()
|
|
||||||
{
|
|
||||||
# $1 - default (Y/N)
|
|
||||||
local A
|
|
||||||
read A
|
|
||||||
[ -z "$A" ] || ([ "$A" != "Y" ] && [ "$A" != "y" ] && [ "$A" != "N" ] && [ "$A" != "n" ]) && A=$1
|
|
||||||
[ "$A" = "Y" ] || [ "$A" = "y" ] || [ "$A" = "1" ]
|
|
||||||
}
|
|
||||||
ask_yes_no()
|
|
||||||
{
|
|
||||||
# $1 - default (Y/N or 0/1)
|
|
||||||
# $2 - text
|
|
||||||
local DEFAULT=$1
|
|
||||||
[ "$1" = "1" ] && DEFAULT=Y
|
|
||||||
[ "$1" = "0" ] && DEFAULT=N
|
|
||||||
[ -z "$DEFAULT" ] && DEFAULT=N
|
|
||||||
$ECHON "$2 (default : $DEFAULT) (Y/N) ? "
|
|
||||||
read_yes_no $DEFAULT
|
|
||||||
}
|
|
||||||
ask_yes_no_var()
|
|
||||||
{
|
|
||||||
# $1 - variable name for answer : 0/1
|
|
||||||
# $2 - text
|
|
||||||
local DEFAULT
|
|
||||||
eval DEFAULT="\$$1"
|
|
||||||
if ask_yes_no "$DEFAULT" "$2"; then
|
|
||||||
eval $1=1
|
|
||||||
else
|
|
||||||
eval $1=0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
require_root()
|
|
||||||
{
|
|
||||||
local exe
|
|
||||||
echo \* checking privileges
|
|
||||||
[ $(id -u) -ne "0" ] && {
|
|
||||||
echo root is required
|
|
||||||
exe="$EXEDIR/$(basename "$0")"
|
|
||||||
exists sudo && exec sudo "$exe"
|
|
||||||
exists su && exec su root -c "$exe"
|
|
||||||
echo su or sudo not found
|
|
||||||
exitp 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IPT()
|
IPT()
|
||||||
{
|
{
|
||||||
$IPTABLES -C "$@" >/dev/null 2>/dev/null || $IPTABLES -I "$@"
|
$IPTABLES -C "$@" >/dev/null 2>/dev/null || $IPTABLES -I "$@"
|
||||||
@ -165,29 +116,11 @@ check_system()
|
|||||||
Linux)
|
Linux)
|
||||||
PKTWS="$NFQWS"
|
PKTWS="$NFQWS"
|
||||||
PKTWSD=nfqws
|
PKTWSD=nfqws
|
||||||
local INIT=$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)
|
linux_fwtype
|
||||||
[ -L "$INIT" ] && INIT=$(readlink "$INIT")
|
[ "$FWTYPE" = iptables -o "$FWTYPE" = nftables ] || {
|
||||||
INIT=$(basename "$INIT")
|
echo firewall type $FWTYPE not supported in $UNAME
|
||||||
if [ -f "/etc/openwrt_release" ] && exists opkg && exists uci && [ "$INIT" = "procd" ] ; then
|
exitp 5
|
||||||
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 && [ "$FWTYPE" != "iptables" ] ; then
|
|
||||||
FWTYPE=nftables
|
|
||||||
else
|
|
||||||
FWTYPE=iptables
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# generic linux
|
|
||||||
if exists nft && [ "$FWTYPE" != "iptables" ]; then
|
|
||||||
FWTYPE=nftables
|
|
||||||
else
|
|
||||||
FWTYPE=iptables
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
PKTWS="$DVTWS"
|
PKTWS="$DVTWS"
|
||||||
@ -403,10 +336,10 @@ pktws_ipt_prepare()
|
|||||||
nftables)
|
nftables)
|
||||||
nft add table inet $NFT_TABLE
|
nft add table inet $NFT_TABLE
|
||||||
[ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ] && {
|
[ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ] && {
|
||||||
nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -401; }"
|
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 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 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 bypass"
|
nft "add rule inet $NFT_TABLE premangle meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM bypass"
|
||||||
;;
|
;;
|
||||||
ipfw)
|
ipfw)
|
||||||
@ -447,7 +380,7 @@ tpws_ipt_prepare()
|
|||||||
nftables)
|
nftables)
|
||||||
nft add table inet $NFT_TABLE
|
nft add table inet $NFT_TABLE
|
||||||
# -101 = pre dstnat
|
# -101 = pre dstnat
|
||||||
nft "add chain inet $NFT_TABLE output { type nat hook output priority -101; }"
|
nft "add chain inet $NFT_TABLE output { type nat hook output priority -102; }"
|
||||||
nft "add rule inet $NFT_TABLE output tcp dport $1 skuid != $TPWS_UID dnat ip${IPVV} to $LOCALHOST_IPT:$TPPORT"
|
nft "add rule inet $NFT_TABLE output tcp dport $1 skuid != $TPWS_UID dnat ip${IPVV} to $LOCALHOST_IPT:$TPPORT"
|
||||||
;;
|
;;
|
||||||
ipfw)
|
ipfw)
|
||||||
@ -801,9 +734,7 @@ configure_curl_opt()
|
|||||||
|
|
||||||
linux_ipv6_defrag_can_be_disabled()
|
linux_ipv6_defrag_can_be_disabled()
|
||||||
{
|
{
|
||||||
local V1=$(sed -nre 's/^Linux version ([0-9]+)\.[0-9]+.*$/\1/p' /proc/version)
|
linux_min_version 4 16
|
||||||
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()
|
||||||
@ -836,7 +767,7 @@ configure_defrag()
|
|||||||
fi
|
fi
|
||||||
[ -n "$IP6_DEFRAG_DISABLE" ] && {
|
[ -n "$IP6_DEFRAG_DISABLE" ] && {
|
||||||
local ipexe="$(readlink -f $(whichq ip6tables))"
|
local ipexe="$(readlink -f $(whichq ip6tables))"
|
||||||
if [ "${ipexe#*nft}" != "$ipexe" ]; then
|
if contains "$ipexe" nft; then
|
||||||
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6tables-nft is used. current ip6tables point to : $ipexe"
|
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6tables-nft is used. current ip6tables point to : $ipexe"
|
||||||
else
|
else
|
||||||
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6table_raw kernel module is not loaded with parameter : raw_before_defrag=1"
|
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6table_raw kernel module is not loaded with parameter : raw_before_defrag=1"
|
||||||
|
135
common/base.sh
Normal file
135
common/base.sh
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
exists()
|
||||||
|
{
|
||||||
|
which "$1" >/dev/null 2>/dev/null
|
||||||
|
}
|
||||||
|
existf()
|
||||||
|
{
|
||||||
|
type "$1" >/dev/null 2>/dev/null
|
||||||
|
}
|
||||||
|
whichq()
|
||||||
|
{
|
||||||
|
which $1 2>/dev/null
|
||||||
|
}
|
||||||
|
exist_all()
|
||||||
|
{
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
exists "$1" || return 1
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
on_off_function()
|
||||||
|
{
|
||||||
|
# $1 : function name on
|
||||||
|
# $2 : function name off
|
||||||
|
# $3 : 0 - off, 1 - on
|
||||||
|
local F="$1"
|
||||||
|
[ "$3" = "1" ] || F="$2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
"$F" "$@"
|
||||||
|
}
|
||||||
|
contains()
|
||||||
|
{
|
||||||
|
# check if substring $2 contains in $1
|
||||||
|
[ "${1#*$2}" != "$1" ]
|
||||||
|
}
|
||||||
|
find_str_in_list()
|
||||||
|
{
|
||||||
|
[ -n "$1" ] && {
|
||||||
|
for v in $2; do
|
||||||
|
[ "$v" = "$1" ] && return 0
|
||||||
|
done
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
end_with_newline()
|
||||||
|
{
|
||||||
|
local c=$(tail -c 1)
|
||||||
|
[ "$c" = "" ]
|
||||||
|
}
|
||||||
|
make_separator_list()
|
||||||
|
{
|
||||||
|
# $1 - var name to receive result
|
||||||
|
# $2 - separator
|
||||||
|
# $3,$4,... - elements
|
||||||
|
local var="$1" sep="$2" i
|
||||||
|
|
||||||
|
shift; shift
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
if [ -n "$i" ] ; then
|
||||||
|
i=$i$sep$1
|
||||||
|
else
|
||||||
|
i=$1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
eval $var=$i
|
||||||
|
}
|
||||||
|
make_comma_list()
|
||||||
|
{
|
||||||
|
# $1 - var name to receive result
|
||||||
|
# $2,$3,... - elements
|
||||||
|
local var="$1"
|
||||||
|
shift
|
||||||
|
make_separator_list $var , "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_linked_to_busybox()
|
||||||
|
{
|
||||||
|
local IFS F P
|
||||||
|
|
||||||
|
IFS=:
|
||||||
|
for path in $PATH; do
|
||||||
|
F=$path/$1
|
||||||
|
P="$(readlink $F)"
|
||||||
|
if [ -z "$P" ] && [ -x $F ] && [ ! -L $F ]; then return 1; fi
|
||||||
|
[ "${P%busybox*}" != "$P" ] && return
|
||||||
|
done
|
||||||
|
}
|
||||||
|
get_dir_inode()
|
||||||
|
{
|
||||||
|
local dir="$1"
|
||||||
|
[ -L "$dir" ] && dir=$(readlink "$dir")
|
||||||
|
ls -id "$dir" | awk '{print $1}'
|
||||||
|
}
|
||||||
|
|
||||||
|
linux_min_version()
|
||||||
|
{
|
||||||
|
# $1 - major ver
|
||||||
|
# $2 - minor ver
|
||||||
|
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 "$1" -o "$V1" -eq "$1" -a "$V2" -ge "$2" ]
|
||||||
|
}
|
||||||
|
linux_get_subsys()
|
||||||
|
{
|
||||||
|
local INIT=$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)
|
||||||
|
|
||||||
|
[ -L "$INIT" ] && INIT=$(readlink "$INIT")
|
||||||
|
INIT=$(basename "$INIT")
|
||||||
|
if [ -f "/etc/openwrt_release" ] && [ "$INIT" = "procd" ] ; then
|
||||||
|
SUBSYS=openwrt
|
||||||
|
else
|
||||||
|
# generic linux
|
||||||
|
SUBSYS=
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
openwrt_fw3()
|
||||||
|
{
|
||||||
|
[ ! -x /sbin/fw4 -a -x /sbin/fw3 ]
|
||||||
|
}
|
||||||
|
openwrt_fw4()
|
||||||
|
{
|
||||||
|
[ -x /sbin/fw4 ]
|
||||||
|
}
|
||||||
|
openwrt_fw3_integration()
|
||||||
|
{
|
||||||
|
[ "$FWTYPE" = iptables ] && openwrt_fw3
|
||||||
|
}
|
||||||
|
|
||||||
|
create_dev_stdin()
|
||||||
|
{
|
||||||
|
[ -e /dev/stdin ] || ln -s /proc/self/fd/0 /dev/stdin
|
||||||
|
}
|
58
common/dialog.sh
Normal file
58
common/dialog.sh
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
read_yes_no()
|
||||||
|
{
|
||||||
|
# $1 - default (Y/N)
|
||||||
|
local A
|
||||||
|
read A
|
||||||
|
[ -z "$A" ] || ([ "$A" != "Y" ] && [ "$A" != "y" ] && [ "$A" != "N" ] && [ "$A" != "n" ]) && A=$1
|
||||||
|
[ "$A" = "Y" ] || [ "$A" = "y" ] || [ "$A" = "1" ]
|
||||||
|
}
|
||||||
|
ask_yes_no()
|
||||||
|
{
|
||||||
|
# $1 - default (Y/N or 0/1)
|
||||||
|
# $2 - text
|
||||||
|
local DEFAULT=$1
|
||||||
|
[ "$1" = "1" ] && DEFAULT=Y
|
||||||
|
[ "$1" = "0" ] && DEFAULT=N
|
||||||
|
[ -z "$DEFAULT" ] && DEFAULT=N
|
||||||
|
printf "$2 (default : $DEFAULT) (Y/N) ? "
|
||||||
|
read_yes_no $DEFAULT
|
||||||
|
}
|
||||||
|
ask_yes_no_var()
|
||||||
|
{
|
||||||
|
# $1 - variable name for answer : 0/1
|
||||||
|
# $2 - text
|
||||||
|
local DEFAULT
|
||||||
|
eval DEFAULT="\$$1"
|
||||||
|
if ask_yes_no "$DEFAULT" "$2"; then
|
||||||
|
eval $1=1
|
||||||
|
else
|
||||||
|
eval $1=0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
ask_list()
|
||||||
|
{
|
||||||
|
# $1 - mode var
|
||||||
|
# $2 - space separated value list
|
||||||
|
# $3 - (optional) default value
|
||||||
|
local M_DEFAULT
|
||||||
|
eval M_DEFAULT="\$$1"
|
||||||
|
local M_ALL=$M_DEFAULT
|
||||||
|
local M=""
|
||||||
|
local m
|
||||||
|
|
||||||
|
[ -n "$3" ] && { find_str_in_list "$M_DEFAULT" "$2" || M_DEFAULT="$3" ;}
|
||||||
|
|
||||||
|
n=1
|
||||||
|
for m in $2; do
|
||||||
|
echo $n : $m
|
||||||
|
n=$(($n+1))
|
||||||
|
done
|
||||||
|
printf "your choice (default : $M_DEFAULT) : "
|
||||||
|
read m
|
||||||
|
[ -n "$m" ] && M=$(echo $2 | cut -d ' ' -f$m 2>/dev/null)
|
||||||
|
[ -z "$M" ] && M="$M_DEFAULT"
|
||||||
|
echo selected : $M
|
||||||
|
eval $1="\"$M\""
|
||||||
|
|
||||||
|
[ "$M" != "$M_OLD" ]
|
||||||
|
}
|
13
common/elevate.sh
Normal file
13
common/elevate.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
require_root()
|
||||||
|
{
|
||||||
|
local exe
|
||||||
|
echo \* checking privileges
|
||||||
|
[ $(id -u) -ne "0" ] && {
|
||||||
|
echo root is required
|
||||||
|
exe="$EXEDIR/$(basename "$0")"
|
||||||
|
exists sudo && exec sudo "$exe"
|
||||||
|
exists su && exec su root -c "$exe"
|
||||||
|
echo su or sudo not found
|
||||||
|
exitp 2
|
||||||
|
}
|
||||||
|
}
|
64
common/fwtype.sh
Normal file
64
common/fwtype.sh
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
linux_ipt_avail()
|
||||||
|
{
|
||||||
|
exists iptables && exists ip6tables
|
||||||
|
}
|
||||||
|
linux_maybe_iptables_fwtype()
|
||||||
|
{
|
||||||
|
linux_ipt_avail && FWTYPE=iptables
|
||||||
|
}
|
||||||
|
linux_nft_avail()
|
||||||
|
{
|
||||||
|
exists nft
|
||||||
|
}
|
||||||
|
linux_fwtype()
|
||||||
|
{
|
||||||
|
[ -n "$FWTYPE" ] && return
|
||||||
|
|
||||||
|
FWTYPE=unsupported
|
||||||
|
|
||||||
|
linux_get_subsys
|
||||||
|
if [ "$SUBSYS" = openwrt ] ; then
|
||||||
|
# linux kernel is new enough if fw4 is there
|
||||||
|
if [ -x /sbin/fw4 ] && linux_nft_avail ; then
|
||||||
|
FWTYPE=nftables
|
||||||
|
else
|
||||||
|
linux_maybe_iptables_fwtype
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
SUBSYS=
|
||||||
|
# generic linux
|
||||||
|
# flowtable is implemented since kernel 4.16
|
||||||
|
if linux_nft_avail && linux_min_version 4 16; then
|
||||||
|
FWTYPE=nftables
|
||||||
|
else
|
||||||
|
linux_maybe_iptables_fwtype
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
export FWTYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
get_fwtype()
|
||||||
|
{
|
||||||
|
[ -n "$FWTYPE" ] && return
|
||||||
|
|
||||||
|
local UNAME="$(uname)"
|
||||||
|
|
||||||
|
case "$UNAME" in
|
||||||
|
Linux)
|
||||||
|
linux_fwtype
|
||||||
|
;;
|
||||||
|
FreeBSD)
|
||||||
|
if exists ipfw ; then
|
||||||
|
FWTYPE=ipfw
|
||||||
|
else
|
||||||
|
FWTYPE=unsupported
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
FWTYPE=unsupported
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
export FWTYPE
|
||||||
|
}
|
462
common/installer.sh
Normal file
462
common/installer.sh
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
GET_LIST_PREFIX=/ipset/get_
|
||||||
|
|
||||||
|
SYSTEMD_DIR=/lib/systemd
|
||||||
|
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
|
||||||
|
[ -d "$SYSTEMD_DIR" ] && SYSTEMD_SYSTEM_DIR="$SYSTEMD_DIR/system"
|
||||||
|
|
||||||
|
INIT_SCRIPT=/etc/init.d/zapret
|
||||||
|
|
||||||
|
|
||||||
|
exitp()
|
||||||
|
{
|
||||||
|
echo
|
||||||
|
echo press enter to continue
|
||||||
|
read A
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_var_checked()
|
||||||
|
{
|
||||||
|
# $1 - file name
|
||||||
|
# $2 - var name
|
||||||
|
local sed="sed -nre s/^[[:space:]]*$2=[\\\"|\']?([^\\\"|\']*)[\\\"|\']?/\1/p"
|
||||||
|
local v="$($sed <"$1" | tail -n 1)"
|
||||||
|
eval $2=\"$v\"
|
||||||
|
}
|
||||||
|
parse_vars_checked()
|
||||||
|
{
|
||||||
|
# $1 - file name
|
||||||
|
# $2,$3,... - var names
|
||||||
|
local f="$1"
|
||||||
|
shift
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
parse_var_checked "$f" $1
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
edit_file()
|
||||||
|
{
|
||||||
|
# $1 - file name
|
||||||
|
local ed="$EDITOR"
|
||||||
|
[ -n "$ed" ] || {
|
||||||
|
for e in mcedit nano vi; do
|
||||||
|
exists "$e" && {
|
||||||
|
ed="$e"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
[ -n "$ed" ] && "$ed" "$1"
|
||||||
|
}
|
||||||
|
edit_vars()
|
||||||
|
{
|
||||||
|
# $1,$2,... - var names
|
||||||
|
local n=1 var v tmp="/tmp/zvars"
|
||||||
|
rm -f "$tmp"
|
||||||
|
while [ 1=1 ]; do
|
||||||
|
eval var="\$$n"
|
||||||
|
[ -n "$var" ] || break
|
||||||
|
eval v="\$$var"
|
||||||
|
echo $var=\"$v\" >>"$tmp"
|
||||||
|
n=$(($n+1))
|
||||||
|
done
|
||||||
|
edit_file "$tmp" && parse_vars_checked "$tmp" "$@"
|
||||||
|
rm -f "$tmp"
|
||||||
|
}
|
||||||
|
|
||||||
|
openrc_test()
|
||||||
|
{
|
||||||
|
exists rc-update || return 1
|
||||||
|
# some systems do not usse openrc-init but launch openrc from inittab
|
||||||
|
[ "$INIT" = "openrc-init" ] || grep -qE "sysinit.*openrc" /etc/inittab 2>/dev/null
|
||||||
|
}
|
||||||
|
check_system()
|
||||||
|
{
|
||||||
|
echo \* checking system
|
||||||
|
|
||||||
|
SYSTEM=""
|
||||||
|
SYSTEMCTL=$(whichq systemctl)
|
||||||
|
|
||||||
|
get_fwtype
|
||||||
|
OPENWRT_FW3=
|
||||||
|
|
||||||
|
local info
|
||||||
|
local UNAME=$(uname)
|
||||||
|
if [ "$UNAME" = "Linux" ]; then
|
||||||
|
# do not use 'exe' because it requires root
|
||||||
|
local INIT=$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)
|
||||||
|
[ -L "$INIT" ] && INIT=$(readlink "$INIT")
|
||||||
|
INIT=$(basename "$INIT")
|
||||||
|
# some distros include systemctl without systemd
|
||||||
|
if [ -d "$SYSTEMD_DIR" ] && [ -x "$SYSTEMCTL" ] && [ "$INIT" = "systemd" ]; then
|
||||||
|
SYSTEM=systemd
|
||||||
|
elif [ -f "/etc/openwrt_release" ] && exists opkg && exists uci && [ "$INIT" = "procd" ] ; then
|
||||||
|
{
|
||||||
|
SYSTEM=openwrt
|
||||||
|
if openwrt_fw3 ; then
|
||||||
|
OPENWRT_FW3=1
|
||||||
|
info="openwrt firewall uses fw3"
|
||||||
|
if is_ipt_flow_offload_avail; then
|
||||||
|
info="$info. hardware flow offloading requires iptables."
|
||||||
|
else
|
||||||
|
info="$info. flow offloading unavailable."
|
||||||
|
fi
|
||||||
|
elif openwrt_fw4; then
|
||||||
|
info="openwrt firewall uses fw4. flow offloading requires nftables."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
elif openrc_test; then
|
||||||
|
SYSTEM=openrc
|
||||||
|
else
|
||||||
|
echo system is not either systemd, openrc or openwrt based
|
||||||
|
echo easy installer can set up config settings but can\'t configure auto start
|
||||||
|
echo you have to do it manually. check readme.txt for manual setup info.
|
||||||
|
if ask_yes_no N "do you want to continue"; then
|
||||||
|
SYSTEM=linux
|
||||||
|
else
|
||||||
|
exitp 5
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
elif [ "$UNAME" = "Darwin" ]; then
|
||||||
|
SYSTEM=macos
|
||||||
|
else
|
||||||
|
echo easy installer only supports Linux and MacOS. check readme.txt for supported systems and manual setup info.
|
||||||
|
exitp 5
|
||||||
|
fi
|
||||||
|
echo system is based on $SYSTEM
|
||||||
|
[ -n "$info" ] && echo $info
|
||||||
|
}
|
||||||
|
|
||||||
|
get_free_space_mb()
|
||||||
|
{
|
||||||
|
df -m $PWD | awk '/[0-9]%/{print $(NF-2)}'
|
||||||
|
}
|
||||||
|
get_ram_kb()
|
||||||
|
{
|
||||||
|
grep MemTotal /proc/meminfo | awk '{print $2}'
|
||||||
|
}
|
||||||
|
get_ram_mb()
|
||||||
|
{
|
||||||
|
local R=$(get_ram_kb)
|
||||||
|
echo $(($R/1024))
|
||||||
|
}
|
||||||
|
|
||||||
|
crontab_del()
|
||||||
|
{
|
||||||
|
exists crontab || return
|
||||||
|
|
||||||
|
echo \* removing crontab entry
|
||||||
|
|
||||||
|
CRONTMP=/tmp/cron.tmp
|
||||||
|
crontab -l >$CRONTMP 2>/dev/null
|
||||||
|
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
||||||
|
echo removing following entries from crontab :
|
||||||
|
grep "$GET_LIST_PREFIX" $CRONTMP
|
||||||
|
grep -v "$GET_LIST_PREFIX" $CRONTMP >$CRONTMP.2
|
||||||
|
crontab $CRONTMP.2
|
||||||
|
rm -f $CRONTMP.2
|
||||||
|
fi
|
||||||
|
rm -f $CRONTMP
|
||||||
|
}
|
||||||
|
crontab_del_quiet()
|
||||||
|
{
|
||||||
|
exists crontab || return
|
||||||
|
|
||||||
|
CRONTMP=/tmp/cron.tmp
|
||||||
|
crontab -l >$CRONTMP 2>/dev/null
|
||||||
|
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
||||||
|
grep -v "$GET_LIST_PREFIX" $CRONTMP >$CRONTMP.2
|
||||||
|
crontab $CRONTMP.2
|
||||||
|
rm -f $CRONTMP.2
|
||||||
|
fi
|
||||||
|
rm -f $CRONTMP
|
||||||
|
}
|
||||||
|
crontab_add()
|
||||||
|
{
|
||||||
|
# $1 - hour min
|
||||||
|
# $2 - hour max
|
||||||
|
[ -x "$GET_LIST" ] && {
|
||||||
|
echo \* adding crontab entry
|
||||||
|
|
||||||
|
if exists crontab; then
|
||||||
|
CRONTMP=/tmp/cron.tmp
|
||||||
|
crontab -l >$CRONTMP 2>/dev/null
|
||||||
|
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
||||||
|
echo some entries already exist in crontab. check if this is corrent :
|
||||||
|
grep "$GET_LIST_PREFIX" $CRONTMP
|
||||||
|
else
|
||||||
|
end_with_newline <"$CRONTMP" || echo >>"$CRONTMP"
|
||||||
|
echo "$(random 0 59) $(random $1 $2) */2 * * $GET_LIST" >>$CRONTMP
|
||||||
|
crontab $CRONTMP
|
||||||
|
fi
|
||||||
|
rm -f $CRONTMP
|
||||||
|
else
|
||||||
|
echo '!!! CRON IS ABSENT !!! LISTS AUTO UPDATE WILL NOT WORK !!!'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cron_ensure_running()
|
||||||
|
{
|
||||||
|
# if no crontabs present in /etc/cron openwrt init script does not launch crond. this is default
|
||||||
|
[ "$SYSTEM" = "openwrt" ] && {
|
||||||
|
/etc/init.d/cron enable
|
||||||
|
/etc/init.d/cron start
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
service_start_systemd()
|
||||||
|
{
|
||||||
|
echo \* starting zapret service
|
||||||
|
|
||||||
|
"$SYSTEMCTL" start zapret || {
|
||||||
|
echo could not start zapret service
|
||||||
|
exitp 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service_stop_systemd()
|
||||||
|
{
|
||||||
|
echo \* stopping zapret service
|
||||||
|
|
||||||
|
"$SYSTEMCTL" daemon-reload
|
||||||
|
"$SYSTEMCTL" disable zapret
|
||||||
|
"$SYSTEMCTL" stop zapret
|
||||||
|
}
|
||||||
|
service_remove_systemd()
|
||||||
|
{
|
||||||
|
echo \* removing zapret service
|
||||||
|
|
||||||
|
rm -f "$SYSTEMD_SYSTEM_DIR/zapret.service"
|
||||||
|
"$SYSTEMCTL" daemon-reload
|
||||||
|
}
|
||||||
|
timer_remove_systemd()
|
||||||
|
{
|
||||||
|
echo \* removing zapret-list-update timer
|
||||||
|
|
||||||
|
"$SYSTEMCTL" daemon-reload
|
||||||
|
"$SYSTEMCTL" disable zapret-list-update.timer
|
||||||
|
"$SYSTEMCTL" stop zapret-list-update.timer
|
||||||
|
rm -f "$SYSTEMD_SYSTEM_DIR/zapret-list-update.service" "$SYSTEMD_SYSTEM_DIR/zapret-list-update.timer"
|
||||||
|
"$SYSTEMCTL" daemon-reload
|
||||||
|
}
|
||||||
|
|
||||||
|
install_sysv_init()
|
||||||
|
{
|
||||||
|
# $1 - "0"=disable
|
||||||
|
echo \* installing init script
|
||||||
|
|
||||||
|
[ -x "$INIT_SCRIPT" ] && {
|
||||||
|
"$INIT_SCRIPT" stop
|
||||||
|
"$INIT_SCRIPT" disable
|
||||||
|
}
|
||||||
|
ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
|
||||||
|
[ "$1" != "0" ] && "$INIT_SCRIPT" enable
|
||||||
|
}
|
||||||
|
install_openrc_init()
|
||||||
|
{
|
||||||
|
# $1 - "0"=disable
|
||||||
|
echo \* installing init script
|
||||||
|
|
||||||
|
[ -x "$INIT_SCRIPT" ] && {
|
||||||
|
"$INIT_SCRIPT" stop
|
||||||
|
rc-update del zapret
|
||||||
|
}
|
||||||
|
ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
|
||||||
|
[ "$1" != "0" ] && rc-update add zapret
|
||||||
|
}
|
||||||
|
service_remove_openrc()
|
||||||
|
{
|
||||||
|
echo \* removing zapret service
|
||||||
|
|
||||||
|
[ -x "$INIT_SCRIPT" ] && {
|
||||||
|
rc-update del zapret
|
||||||
|
"$INIT_SCRIPT" stop
|
||||||
|
}
|
||||||
|
rm -f "$INIT_SCRIPT"
|
||||||
|
}
|
||||||
|
service_start_sysv()
|
||||||
|
{
|
||||||
|
[ -x "$INIT_SCRIPT" ] && {
|
||||||
|
echo \* starting zapret service
|
||||||
|
"$INIT_SCRIPT" start || {
|
||||||
|
echo could not start zapret service
|
||||||
|
exitp 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service_stop_sysv()
|
||||||
|
{
|
||||||
|
[ -x "$INIT_SCRIPT" ] && {
|
||||||
|
echo \* stopping zapret service
|
||||||
|
"$INIT_SCRIPT" stop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
service_remove_sysv()
|
||||||
|
{
|
||||||
|
echo \* removing zapret service
|
||||||
|
|
||||||
|
[ -x "$INIT_SCRIPT" ] && {
|
||||||
|
"$INIT_SCRIPT" disable
|
||||||
|
"$INIT_SCRIPT" stop
|
||||||
|
}
|
||||||
|
rm -f "$INIT_SCRIPT"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_kmod()
|
||||||
|
{
|
||||||
|
[ -f "/lib/modules/$(uname -r)/$1.ko" ]
|
||||||
|
}
|
||||||
|
check_package_exists_openwrt()
|
||||||
|
{
|
||||||
|
[ -n "$(opkg list $1)" ]
|
||||||
|
}
|
||||||
|
check_package_openwrt()
|
||||||
|
{
|
||||||
|
[ -n "$(opkg list-installed $1)" ] && return 0
|
||||||
|
local what=$(opkg whatprovides $1 | tail -n +2 | head -n 1)
|
||||||
|
[ -n "$what" ] || return 1
|
||||||
|
[ -n "$(opkg list-installed $what)" ]
|
||||||
|
}
|
||||||
|
check_packages_openwrt()
|
||||||
|
{
|
||||||
|
for pkg in $@; do
|
||||||
|
check_package_openwrt $pkg || return
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
install_openwrt_iface_hook()
|
||||||
|
{
|
||||||
|
echo \* installing ifup hook
|
||||||
|
|
||||||
|
ln -fs "$OPENWRT_IFACE_HOOK" /etc/hotplug.d/iface
|
||||||
|
}
|
||||||
|
remove_openwrt_iface_hook()
|
||||||
|
{
|
||||||
|
echo \* removing ifup hook
|
||||||
|
|
||||||
|
rm -f /etc/hotplug.d/iface/??-zapret
|
||||||
|
}
|
||||||
|
openwrt_fw_section_find()
|
||||||
|
{
|
||||||
|
# $1 - fw include postfix
|
||||||
|
# echoes section number
|
||||||
|
|
||||||
|
i=0
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
path=$(uci -q get firewall.@include[$i].path)
|
||||||
|
[ -n "$path" ] || break
|
||||||
|
[ "$path" = "$OPENWRT_FW_INCLUDE$1" ] && {
|
||||||
|
echo $i
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
i=$(($i+1))
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
openwrt_fw_section_del()
|
||||||
|
{
|
||||||
|
# $1 - fw include postfix
|
||||||
|
|
||||||
|
local id=$(openwrt_fw_section_find $1)
|
||||||
|
[ -n "$id" ] && {
|
||||||
|
uci delete firewall.@include[$id] && uci commit firewall
|
||||||
|
rm -f "$OPENWRT_FW_INCLUDE$1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
openwrt_fw_section_add()
|
||||||
|
{
|
||||||
|
openwrt_fw_section_find ||
|
||||||
|
{
|
||||||
|
uci add firewall include >/dev/null || return
|
||||||
|
echo -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
openwrt_fw_section_configure()
|
||||||
|
{
|
||||||
|
local id=$(openwrt_fw_section_add $1)
|
||||||
|
[ -z "$id" ] ||
|
||||||
|
! uci set firewall.@include[$id].path="$OPENWRT_FW_INCLUDE" ||
|
||||||
|
! uci set firewall.@include[$id].reload="1" ||
|
||||||
|
! uci commit firewall &&
|
||||||
|
{
|
||||||
|
echo could not add firewall include
|
||||||
|
exitp 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
install_openwrt_firewall()
|
||||||
|
{
|
||||||
|
echo \* installing firewall script $1
|
||||||
|
|
||||||
|
[ -n "MODE" ] || {
|
||||||
|
echo should specify MODE in $ZAPRET_CONFIG
|
||||||
|
exitp 7
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "linking : $FW_SCRIPT_SRC => $OPENWRT_FW_INCLUDE"
|
||||||
|
ln -fs "$FW_SCRIPT_SRC" "$OPENWRT_FW_INCLUDE"
|
||||||
|
|
||||||
|
openwrt_fw_section_configure $1
|
||||||
|
}
|
||||||
|
restart_openwrt_firewall()
|
||||||
|
{
|
||||||
|
echo \* restarting firewall
|
||||||
|
|
||||||
|
fw3 -q restart || {
|
||||||
|
echo could not restart firewall
|
||||||
|
exitp 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove_openwrt_firewall()
|
||||||
|
{
|
||||||
|
echo \* removing firewall script
|
||||||
|
|
||||||
|
openwrt_fw_section_del
|
||||||
|
# from old zapret versions. now we use single include
|
||||||
|
openwrt_fw_section_del 6
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_ipset()
|
||||||
|
{
|
||||||
|
echo "* clearing ipset(s)"
|
||||||
|
|
||||||
|
# free some RAM
|
||||||
|
"$IPSET_DIR/create_ipset.sh" clear
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
service_install_macos()
|
||||||
|
{
|
||||||
|
echo \* installing zapret service
|
||||||
|
|
||||||
|
ln -fs "$ZAPRET_BASE/init.d/macos/zapret.plist" /Library/LaunchDaemons
|
||||||
|
}
|
||||||
|
service_start_macos()
|
||||||
|
{
|
||||||
|
echo \* starting zapret service
|
||||||
|
|
||||||
|
"$INIT_SCRIPT_SRC" start
|
||||||
|
}
|
||||||
|
service_stop_macos()
|
||||||
|
{
|
||||||
|
echo \* stopping zapret service
|
||||||
|
|
||||||
|
"$INIT_SCRIPT_SRC" stop
|
||||||
|
}
|
||||||
|
service_remove_macos()
|
||||||
|
{
|
||||||
|
echo \* removing zapret service
|
||||||
|
|
||||||
|
rm -f /Library/LaunchDaemons/zapret.plist
|
||||||
|
zapret_stop_daemons
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_macos_firewall()
|
||||||
|
{
|
||||||
|
echo \* removing zapret PF hooks
|
||||||
|
|
||||||
|
pf_anchors_clear
|
||||||
|
pf_anchors_del
|
||||||
|
pf_anchor_root_del
|
||||||
|
pf_anchor_root_reload
|
||||||
|
}
|
172
common/ipt.sh
Normal file
172
common/ipt.sh
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
ipt()
|
||||||
|
{
|
||||||
|
iptables -C "$@" >/dev/null 2>/dev/null || iptables -I "$@"
|
||||||
|
}
|
||||||
|
ipta()
|
||||||
|
{
|
||||||
|
iptables -C "$@" >/dev/null 2>/dev/null || iptables -A "$@"
|
||||||
|
}
|
||||||
|
ipt_del()
|
||||||
|
{
|
||||||
|
iptables -C "$@" >/dev/null 2>/dev/null && iptables -D "$@"
|
||||||
|
}
|
||||||
|
ipt_add_del()
|
||||||
|
{
|
||||||
|
on_off_function ipt ipt_del "$@"
|
||||||
|
}
|
||||||
|
ipta_add_del()
|
||||||
|
{
|
||||||
|
on_off_function ipta ipt_del "$@"
|
||||||
|
}
|
||||||
|
ipt6()
|
||||||
|
{
|
||||||
|
ip6tables -C "$@" >/dev/null 2>/dev/null || ip6tables -I "$@"
|
||||||
|
}
|
||||||
|
ipt6a()
|
||||||
|
{
|
||||||
|
ip6tables -C "$@" >/dev/null 2>/dev/null || ip6tables -A "$@"
|
||||||
|
}
|
||||||
|
ipt6_del()
|
||||||
|
{
|
||||||
|
ip6tables -C "$@" >/dev/null 2>/dev/null && ip6tables -D "$@"
|
||||||
|
}
|
||||||
|
ipt6_add_del()
|
||||||
|
{
|
||||||
|
on_off_function ipt6 ipt6_del "$@"
|
||||||
|
}
|
||||||
|
ipt6a_add_del()
|
||||||
|
{
|
||||||
|
on_off_function ipt6 ipt6a_del "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_ipt_flow_offload_avail()
|
||||||
|
{
|
||||||
|
# $1 = '' for ipv4, '6' for ipv6
|
||||||
|
grep -q FLOWOFFLOAD 2>/dev/null /proc/net/ip$1_tables_targets
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_apply_port_target()
|
||||||
|
{
|
||||||
|
# $1 - var name of iptables filter
|
||||||
|
local f
|
||||||
|
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
||||||
|
f="-m multiport --dports 80,443"
|
||||||
|
elif [ "$MODE_HTTPS" = "1" ]; then
|
||||||
|
f="--dport 443"
|
||||||
|
elif [ "$MODE_HTTP" = "1" ]; then
|
||||||
|
f="--dport 80"
|
||||||
|
else
|
||||||
|
echo WARNING !!! HTTP and HTTPS are both disabled
|
||||||
|
fi
|
||||||
|
eval $1="\"\$$1 $f\""
|
||||||
|
}
|
||||||
|
filter_apply_ipset_target4()
|
||||||
|
{
|
||||||
|
# $1 - var name of ipv4 iptables filter
|
||||||
|
if [ "$MODE_FILTER" = "ipset" ]; then
|
||||||
|
eval $1="\"\$$1 -m set --match-set zapret dst\""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
filter_apply_ipset_target6()
|
||||||
|
{
|
||||||
|
# $1 - var name of ipv6 iptables filter
|
||||||
|
if [ "$MODE_FILTER" = "ipset" ]; then
|
||||||
|
eval $1="\"\$$1 -m set --match-set zapret6 dst\""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
filter_apply_ipset_target()
|
||||||
|
{
|
||||||
|
# $1 - var name of ipv4 iptables filter
|
||||||
|
# $2 - var name of ipv6 iptables filter
|
||||||
|
filter_apply_ipset_target4 $1
|
||||||
|
filter_apply_ipset_target6 $2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
zapret_do_firewall_ipt()
|
||||||
|
{
|
||||||
|
# $1 - 1 - add, 0 - del
|
||||||
|
|
||||||
|
if [ "$1" = 1 ]; then
|
||||||
|
echo Applying iptables
|
||||||
|
else
|
||||||
|
echo Clearing iptables
|
||||||
|
fi
|
||||||
|
|
||||||
|
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||||
|
|
||||||
|
[ "$mode" = "tpws-socks" ] && return 0
|
||||||
|
|
||||||
|
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4"
|
||||||
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
|
local f4 f6 qn qns qn6 qns6
|
||||||
|
|
||||||
|
# always create ipsets. ip_exclude ipset is required
|
||||||
|
[ "$1" = 1 ] && create_ipset no-update
|
||||||
|
|
||||||
|
case "$mode" in
|
||||||
|
tpws)
|
||||||
|
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
|
||||||
|
echo both http and https are disabled. not applying redirection.
|
||||||
|
else
|
||||||
|
filter_apply_port_target f4
|
||||||
|
f6=$f4
|
||||||
|
filter_apply_ipset_target f4 f6
|
||||||
|
fw_tpws $1 "$f4" "$f6" $TPPORT
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
nfqws)
|
||||||
|
# quite complex but we need to minimize nfqws processes to save RAM
|
||||||
|
get_nfqws_qnums qn qns qn6 qns6
|
||||||
|
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
||||||
|
filter_apply_port_target f4
|
||||||
|
f4="$f4 $first_packet_only"
|
||||||
|
filter_apply_ipset_target4 f4
|
||||||
|
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||||
|
else
|
||||||
|
if [ -n "$qn" ]; then
|
||||||
|
f4="--dport 80"
|
||||||
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
||||||
|
filter_apply_ipset_target4 f4
|
||||||
|
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
||||||
|
fi
|
||||||
|
if [ -n "$qns" ]; then
|
||||||
|
f4="--dport 443 $first_packet_only"
|
||||||
|
filter_apply_ipset_target4 f4
|
||||||
|
fw_nfqws_post4 $1 "$f4 $desync" $qns
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||||
|
filter_apply_port_target f6
|
||||||
|
f6="$f6 $first_packet_only"
|
||||||
|
filter_apply_ipset_target6 f6
|
||||||
|
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||||
|
else
|
||||||
|
if [ -n "$qn6" ]; then
|
||||||
|
f6="--dport 80"
|
||||||
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
||||||
|
filter_apply_ipset_target6 f6
|
||||||
|
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
||||||
|
fi
|
||||||
|
if [ -n "$qns6" ]; then
|
||||||
|
f6="--dport 443 $first_packet_only"
|
||||||
|
filter_apply_ipset_target6 f6
|
||||||
|
fw_nfqws_post6 $1 "$f6 $desync" $qns6
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
custom)
|
||||||
|
existf zapret_custom_firewall && zapret_custom_firewall $1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$1" = 1 ] ; then
|
||||||
|
existf flow_offloading_exempt && flow_offloading_exempt
|
||||||
|
else
|
||||||
|
existf flow_offloading_unexempt && flow_offloading_unexempt
|
||||||
|
unprepare_tpws_fw
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
23
common/linux_fw.sh
Normal file
23
common/linux_fw.sh
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
zapret_do_firewall()
|
||||||
|
{
|
||||||
|
linux_fwtype
|
||||||
|
|
||||||
|
case "$FWTYPE" in
|
||||||
|
iptables)
|
||||||
|
zapret_do_firewall_ipt "$@"
|
||||||
|
;;
|
||||||
|
nftables)
|
||||||
|
zapret_do_firewall_nft "$@"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
zapret_apply_firewall()
|
||||||
|
{
|
||||||
|
zapret_do_firewall 1 "$@"
|
||||||
|
}
|
||||||
|
zapret_unapply_firewall()
|
||||||
|
{
|
||||||
|
zapret_do_firewall 0 "$@"
|
||||||
|
}
|
51
common/linux_iphelper.sh
Normal file
51
common/linux_iphelper.sh
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# there's no route_localnet for ipv6
|
||||||
|
# the best we can is to route to link local of the incoming interface
|
||||||
|
# OUTPUT - can DNAT to ::1
|
||||||
|
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
|
||||||
|
# not a good idea to expose tpws to the world (bind to ::)
|
||||||
|
|
||||||
|
|
||||||
|
get_ipv6_linklocal()
|
||||||
|
{
|
||||||
|
# $1 - interface name. if empty - any interface
|
||||||
|
if exists ip ; then
|
||||||
|
local dev
|
||||||
|
[ -n "$1" ] && dev="dev $1"
|
||||||
|
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope link.*$/\1/;t;d' | head -n 1
|
||||||
|
else
|
||||||
|
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Link.*$/\1/;t;d' | head -n 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
get_ipv6_global()
|
||||||
|
{
|
||||||
|
# $1 - interface name. if empty - any interface
|
||||||
|
if exists ip ; then
|
||||||
|
local dev
|
||||||
|
[ -n "$1" ] && dev="dev $1"
|
||||||
|
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1
|
||||||
|
else
|
||||||
|
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Global.*$/\1/;t;d' | head -n 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
iface_is_up()
|
||||||
|
{
|
||||||
|
# $1 - interface name
|
||||||
|
[ -f /sys/class/net/$1/operstate ] || return
|
||||||
|
local state
|
||||||
|
read state </sys/class/net/$1/operstate
|
||||||
|
[ "$state" != "down" ]
|
||||||
|
}
|
||||||
|
wait_ifup()
|
||||||
|
{
|
||||||
|
# $1 - interface name
|
||||||
|
local ct=0
|
||||||
|
while
|
||||||
|
iface_is_up $1 && return
|
||||||
|
[ "$ct" -ge "$IFUP_WAIT_SEC" ] && break
|
||||||
|
echo waiting for ifup of $1 for another $(($IFUP_WAIT_SEC - $ct)) seconds ...
|
||||||
|
ct=$(($ct+1))
|
||||||
|
sleep 1
|
||||||
|
do :; done
|
||||||
|
false
|
||||||
|
}
|
348
common/nft.sh
Normal file
348
common/nft.sh
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
[ -n "$ZAPRET_NFT_TABLE" ] || ZAPRET_NFT_TABLE=zapret
|
||||||
|
|
||||||
|
# required for : nft -f -
|
||||||
|
create_dev_stdin
|
||||||
|
|
||||||
|
nft_create_table()
|
||||||
|
{
|
||||||
|
nft add table inet $ZAPRET_NFT_TABLE
|
||||||
|
}
|
||||||
|
nft_del_table()
|
||||||
|
{
|
||||||
|
nft delete table inet $ZAPRET_NFT_TABLE 2>/dev/null
|
||||||
|
}
|
||||||
|
nft_list_table()
|
||||||
|
{
|
||||||
|
nft -t list table inet $ZAPRET_NFT_TABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_create_set()
|
||||||
|
{
|
||||||
|
# $1 - set name
|
||||||
|
# $2 - params
|
||||||
|
nft create set inet $ZAPRET_NFT_TABLE $1 "{ $2 }" 2>/dev/null
|
||||||
|
}
|
||||||
|
nft_del_set()
|
||||||
|
{
|
||||||
|
# $1 - set name
|
||||||
|
nft delete set inet $ZAPRET_NFT_TABLE $1
|
||||||
|
}
|
||||||
|
nft_flush_set()
|
||||||
|
{
|
||||||
|
# $1 - set name
|
||||||
|
nft flush set inet $ZAPRET_NFT_TABLE $1
|
||||||
|
}
|
||||||
|
nft_set_exists()
|
||||||
|
{
|
||||||
|
# $1 - set name
|
||||||
|
nft -t list set inet $ZAPRET_NFT_TABLE $1 2>/dev/null >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_del_all_chains_from_table()
|
||||||
|
{
|
||||||
|
# $1 - table_name with or without family
|
||||||
|
|
||||||
|
# delete all chains with possible references to each other
|
||||||
|
# cannot just delete all in the list because of references
|
||||||
|
# avoid infinite loops
|
||||||
|
local chains deleted=1 error=1
|
||||||
|
while [ -n "$deleted" -a -n "$error" ]; do
|
||||||
|
chains=$(nft -t list table $1 2>/dev/null | sed -nre "s/^[ ]*chain ([^ ]+) \{/\1/p" | xargs)
|
||||||
|
[ -n "$chains" ] || break
|
||||||
|
deleted=
|
||||||
|
error=
|
||||||
|
for chain in $chains; do
|
||||||
|
if nft delete chain $1 $chain 2>/dev/null; then
|
||||||
|
deleted=1
|
||||||
|
else
|
||||||
|
error=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_del_chains()
|
||||||
|
{
|
||||||
|
nft_del_all_chains_from_table "inet $ZAPRET_NFT_TABLE"
|
||||||
|
}
|
||||||
|
nft_create_chains()
|
||||||
|
{
|
||||||
|
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
|
||||||
|
add chain inet $ZAPRET_NFT_TABLE dnat_pre { type nat hook prerouting priority -101; }
|
||||||
|
flush chain inet $ZAPRET_NFT_TABLE dnat_pre
|
||||||
|
add chain inet $ZAPRET_NFT_TABLE forward { type filter hook forward priority -1; }
|
||||||
|
flush chain inet $ZAPRET_NFT_TABLE forward
|
||||||
|
add chain inet $ZAPRET_NFT_TABLE input { type filter hook input priority -1; }
|
||||||
|
flush chain inet $ZAPRET_NFT_TABLE input
|
||||||
|
add chain inet $ZAPRET_NFT_TABLE flow_offload
|
||||||
|
flush chain inet $ZAPRET_NFT_TABLE flow_offload
|
||||||
|
add chain inet $ZAPRET_NFT_TABLE localnet_protect
|
||||||
|
flush chain inet $ZAPRET_NFT_TABLE localnet_protect
|
||||||
|
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 iifname != lo jump localnet_protect
|
||||||
|
add chain inet $ZAPRET_NFT_TABLE postrouting { type filter hook postrouting priority -151; }
|
||||||
|
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; }
|
||||||
|
add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; }
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
nft_del_flowtable()
|
||||||
|
{
|
||||||
|
nft delete flowtable inet $ZAPRET_NFT_TABLE ft 2>/dev/null
|
||||||
|
}
|
||||||
|
nft_create_or_update_flowtable()
|
||||||
|
{
|
||||||
|
# $1 = flags ('offload' for hw offload)
|
||||||
|
# $2,$3,$4,... - interfaces
|
||||||
|
# can be called multiple times to add interfaces. interfaces can only be added , not removed
|
||||||
|
local flags=$1 devices
|
||||||
|
shift
|
||||||
|
make_comma_list devices "$@"
|
||||||
|
[ -n "$devices" ] && devices="devices={$devices};"
|
||||||
|
[ -n "$flags" ] && flags="flags $flags;"
|
||||||
|
nft add flowtable inet $ZAPRET_NFT_TABLE ft "{ hook ingress priority -1; $flags $devices }"
|
||||||
|
}
|
||||||
|
nft_flush_ifsets()
|
||||||
|
{
|
||||||
|
cat << EOF | nft -f - 2>/dev/null
|
||||||
|
flush set inet $ZAPRET_NFT_TABLE lanif
|
||||||
|
flush set inet $ZAPRET_NFT_TABLE wanif
|
||||||
|
flush set inet $ZAPRET_NFT_TABLE wanif6
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
nft_list_ifsets()
|
||||||
|
{
|
||||||
|
nft list set inet $ZAPRET_NFT_TABLE lanif
|
||||||
|
nft list set inet $ZAPRET_NFT_TABLE wanif
|
||||||
|
nft list set inet $ZAPRET_NFT_TABLE wanif6
|
||||||
|
nft list flowtable inet $ZAPRET_NFT_TABLE ft
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_create_firewall()
|
||||||
|
{
|
||||||
|
nft_create_table
|
||||||
|
nft_del_flowtable
|
||||||
|
nft_create_chains
|
||||||
|
}
|
||||||
|
nft_del_firewall()
|
||||||
|
{
|
||||||
|
nft_del_chains
|
||||||
|
nft_del_flowtable
|
||||||
|
nft_flush_ifsets
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_add_rule()
|
||||||
|
{
|
||||||
|
# $1 - chain
|
||||||
|
# $2,$3,... - rule(s)
|
||||||
|
local chain="$1"
|
||||||
|
shift
|
||||||
|
nft add rule inet $ZAPRET_NFT_TABLE $chain "$@"
|
||||||
|
}
|
||||||
|
nft_add_set_elements()
|
||||||
|
{
|
||||||
|
# $1 - set name
|
||||||
|
# $2,$3,... - element(s)
|
||||||
|
local set="$1" elements
|
||||||
|
shift
|
||||||
|
make_comma_list elements "$@"
|
||||||
|
[ -z "$elements" ] || nft add element inet $ZAPRET_NFT_TABLE $set "{ $elements }"
|
||||||
|
}
|
||||||
|
nft_reverse_nfqws_rule()
|
||||||
|
{
|
||||||
|
echo "$@" | sed -e 's/oifname /iifname /g' -e 's/dport /sport /g' -e 's/daddr /saddr /g' -e 's/ct original /ct reply /g' -e "s/mark and $DESYNC_MARK == 0//g"
|
||||||
|
}
|
||||||
|
nft_clean_nfqws_rule()
|
||||||
|
{
|
||||||
|
echo "$@" | sed -e "s/mark and $DESYNC_MARK == 0//g"
|
||||||
|
}
|
||||||
|
nft_add_nfqws_flow_exempt_rule()
|
||||||
|
{
|
||||||
|
# $1 - rule (must be all filters in one var)
|
||||||
|
nft_add_rule flow_offload $(nft_clean_nfqws_rule $1) return comment \"direct flow offloading exemption\"
|
||||||
|
nft_add_rule flow_offload $(nft_reverse_nfqws_rule $1) return comment \"reverse flow offloading exemption\"
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_hw_offload_supported()
|
||||||
|
{
|
||||||
|
# $1,$2,... - interface names
|
||||||
|
local devices res=1
|
||||||
|
make_comma_list devices "$@"
|
||||||
|
[ -n "$devices" ] && devices="devices={$devices};"
|
||||||
|
nft add table ${ZAPRET_NFT_TABLE}_test && nft add flowtable ${ZAPRET_NFT_TABLE}_test ft "{ flags offload; $devices }" 2>/dev/null && res=0
|
||||||
|
nft delete table ${ZAPRET_NFT_TABLE}_test 2>/dev/null
|
||||||
|
return $res
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_apply_flow_offloading()
|
||||||
|
{
|
||||||
|
# ft can be absent
|
||||||
|
nft_add_rule flow_offload meta l4proto "{ tcp, udp }" flow add @ft 2>/dev/null && nft_add_rule forward jump flow_offload
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
nft_filter_apply_port_target()
|
||||||
|
{
|
||||||
|
# $1 - var name of nftables filter
|
||||||
|
local f
|
||||||
|
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
||||||
|
f="tcp dport {80,443}"
|
||||||
|
elif [ "$MODE_HTTPS" = "1" ]; then
|
||||||
|
f="tcp dport 443"
|
||||||
|
elif [ "$MODE_HTTP" = "1" ]; then
|
||||||
|
f="tcp dport 80"
|
||||||
|
else
|
||||||
|
echo WARNING !!! HTTP and HTTPS are both disabled
|
||||||
|
fi
|
||||||
|
eval $1="\"\$$1 $f\""
|
||||||
|
}
|
||||||
|
nft_filter_apply_ipset_target4()
|
||||||
|
{
|
||||||
|
# $1 - var name of ipv4 nftables filter
|
||||||
|
if [ "$MODE_FILTER" = "ipset" ]; then
|
||||||
|
eval $1="\"\$$1 ip daddr @zapret\""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
nft_filter_apply_ipset_target6()
|
||||||
|
{
|
||||||
|
# $1 - var name of ipv6 nftables filter
|
||||||
|
if [ "$MODE_FILTER" = "ipset" ]; then
|
||||||
|
eval $1="\"\$$1 ip6 daddr @zapret6\""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
nft_filter_apply_ipset_target()
|
||||||
|
{
|
||||||
|
# $1 - var name of ipv4 nftables filter
|
||||||
|
# $2 - var name of ipv6 nftables filter
|
||||||
|
nft_filter_apply_ipset_target4 $1
|
||||||
|
nft_filter_apply_ipset_target6 $2
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_only()
|
||||||
|
{
|
||||||
|
linux_fwtype
|
||||||
|
|
||||||
|
case "$FWTYPE" in
|
||||||
|
nftables)
|
||||||
|
"$@"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_reload_ifsets()
|
||||||
|
{
|
||||||
|
nft_only nft_create_table ; nft_fill_ifsets
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
zapret_list_ifsets()
|
||||||
|
{
|
||||||
|
nft_only nft_list_ifsets
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
zapret_list_table()
|
||||||
|
{
|
||||||
|
nft_only nft_list_table
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_apply_firewall_nft()
|
||||||
|
{
|
||||||
|
echo Applying nftables
|
||||||
|
|
||||||
|
local mode="${MODE_OVERRIDE:-$MODE}"
|
||||||
|
|
||||||
|
[ "$mode" = "tpws-socks" ] && return 0
|
||||||
|
|
||||||
|
local first_packet_only="ct original packets 1-4"
|
||||||
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
local f4 f6 qn qns qn6 qns6
|
||||||
|
|
||||||
|
create_ipset no-update
|
||||||
|
nft_create_firewall
|
||||||
|
nft_fill_ifsets
|
||||||
|
|
||||||
|
case "$mode" in
|
||||||
|
tpws)
|
||||||
|
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
|
||||||
|
echo both http and https are disabled. not applying redirection.
|
||||||
|
else
|
||||||
|
nft_filter_apply_port_target f4
|
||||||
|
f6=$f4
|
||||||
|
nft_filter_apply_ipset_target f4 f6
|
||||||
|
nft_fw_tpws "$f4" "$f6" $TPPORT
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
nfqws)
|
||||||
|
# quite complex but we need to minimize nfqws processes to save RAM
|
||||||
|
get_nfqws_qnums qn qns qn6 qns6
|
||||||
|
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
||||||
|
nft_filter_apply_port_target f4
|
||||||
|
f4="$f4 $first_packet_only"
|
||||||
|
nft_filter_apply_ipset_target4 f4
|
||||||
|
nft_fw_nfqws_post4 "$f4 $desync" $qn
|
||||||
|
else
|
||||||
|
if [ -n "$qn" ]; then
|
||||||
|
f4="tcp dport 80"
|
||||||
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
||||||
|
nft_filter_apply_ipset_target4 f4
|
||||||
|
nft_fw_nfqws_post4 "$f4 $desync" $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
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
||||||
|
nft_filter_apply_port_target f6
|
||||||
|
f6="$f6 $first_packet_only"
|
||||||
|
nft_filter_apply_ipset_target6 f6
|
||||||
|
nft_fw_nfqws_post6 "$f6 $desync" $qn6
|
||||||
|
else
|
||||||
|
if [ -n "$qn6" ]; then
|
||||||
|
f6="tcp dport 80"
|
||||||
|
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
||||||
|
nft_filter_apply_ipset_target6 f6
|
||||||
|
nft_fw_nfqws_post6 "$f6 $desync" $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
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
custom)
|
||||||
|
existf zapret_custom_firewall_nft && zapret_custom_firewall_nft
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && nft_apply_flow_offloading
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
zapret_unapply_firewall_nft()
|
||||||
|
{
|
||||||
|
echo Clearing nftables
|
||||||
|
|
||||||
|
unprepare_route_localnet
|
||||||
|
nft_del_firewall
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
zapret_do_firewall_nft()
|
||||||
|
{
|
||||||
|
# $1 - 1 - add, 0 - del
|
||||||
|
|
||||||
|
if [ "$1" = 0 ] ; then
|
||||||
|
zapret_unapply_firewall_nft
|
||||||
|
else
|
||||||
|
zapret_apply_firewall_nft
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
262
common/pf.sh
Normal file
262
common/pf.sh
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
PF_MAIN="/etc/pf.conf"
|
||||||
|
PF_ANCHOR_DIR=/etc/pf.anchors
|
||||||
|
PF_ANCHOR_ZAPRET="$PF_ANCHOR_DIR/zapret"
|
||||||
|
PF_ANCHOR_ZAPRET_V4="$PF_ANCHOR_DIR/zapret-v4"
|
||||||
|
PF_ANCHOR_ZAPRET_V6="$PF_ANCHOR_DIR/zapret-v6"
|
||||||
|
|
||||||
|
pf_anchor_root_reload()
|
||||||
|
{
|
||||||
|
echo reloading PF root anchor
|
||||||
|
pfctl -qf "$PF_MAIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
pf_anchor_root()
|
||||||
|
{
|
||||||
|
local patch
|
||||||
|
[ -f "$PF_MAIN" ] && {
|
||||||
|
grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" || {
|
||||||
|
echo patching rdr-anchor in $PF_MAIN
|
||||||
|
patch=1
|
||||||
|
sed -i '' -e '/^rdr-anchor "com\.apple\/\*"$/i \
|
||||||
|
rdr-anchor "zapret"
|
||||||
|
' $PF_MAIN
|
||||||
|
}
|
||||||
|
grep -q '^anchor "zapret"$' "$PF_MAIN" || {
|
||||||
|
echo patching anchor in $PF_MAIN
|
||||||
|
patch=1
|
||||||
|
sed -i '' -e '/^anchor "com\.apple\/\*"$/i \
|
||||||
|
anchor "zapret"
|
||||||
|
' $PF_MAIN
|
||||||
|
}
|
||||||
|
grep -q "^set limit table-entries" "$PF_MAIN" || {
|
||||||
|
echo patching table-entries limit
|
||||||
|
patch=1
|
||||||
|
sed -i '' -e '/^scrub-anchor "com\.apple\/\*"$/i \
|
||||||
|
set limit table-entries 5000000
|
||||||
|
' $PF_MAIN
|
||||||
|
}
|
||||||
|
|
||||||
|
grep -q '^anchor "zapret"$' "$PF_MAIN" &&
|
||||||
|
grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" &&
|
||||||
|
grep -q '^set limit table-entries' "$PF_MAIN" && {
|
||||||
|
if [ -n "$patch" ]; then
|
||||||
|
echo successfully patched $PF_MAIN
|
||||||
|
pf_anchor_root_reload
|
||||||
|
else
|
||||||
|
echo successfully checked zapret anchors in $PF_MAIN
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo ----------------------------------
|
||||||
|
echo Automatic $PF_MAIN patching failed. You must apply root anchors manually in your PF config.
|
||||||
|
echo rdr-anchor \"zapret\"
|
||||||
|
echo anchor \"zapret\"
|
||||||
|
echo ----------------------------------
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
pf_anchor_root_del()
|
||||||
|
{
|
||||||
|
sed -i '' -e '/^anchor "zapret"$/d' -e '/^rdr-anchor "zapret"$/d' -e '/^set limit table-entries/d' "$PF_MAIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
pf_anchor_zapret()
|
||||||
|
{
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
if [ -f "$ZIPLIST_EXCLUDE" ]; then
|
||||||
|
echo "table <nozapret> persist file \"$ZIPLIST_EXCLUDE\""
|
||||||
|
else
|
||||||
|
echo "table <nozapret> persist"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
|
if [ -f "$ZIPLIST_EXCLUDE6" ]; then
|
||||||
|
echo "table <nozapret6> persist file \"$ZIPLIST_EXCLUDE6\""
|
||||||
|
else
|
||||||
|
echo "table <nozapret6> persist"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || echo "rdr-anchor \"/zapret-v4\" inet to !<nozapret>"
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || echo "rdr-anchor \"/zapret-v6\" inet6 to !<nozapret6>"
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || echo "anchor \"/zapret-v4\" inet to !<nozapret>"
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || echo "anchor \"/zapret-v6\" inet6 to !<nozapret6>"
|
||||||
|
}
|
||||||
|
pf_anchor_zapret_tables()
|
||||||
|
{
|
||||||
|
# $1 - variable to receive applied table names
|
||||||
|
# $2/$3 $4/$5 ... table_name/table_file
|
||||||
|
local tblv=$1
|
||||||
|
local _tbl
|
||||||
|
|
||||||
|
shift
|
||||||
|
[ "$MODE_FILTER" = "ipset" ] &&
|
||||||
|
{
|
||||||
|
while [ -n "$1" ] && [ -n "$2" ] ; do
|
||||||
|
[ -f "$2" ] && {
|
||||||
|
echo "table <$1> file \"$2\""
|
||||||
|
_tbl="$_tbl<$1> "
|
||||||
|
}
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
[ -n "$_tbl" ] || _tbl="any"
|
||||||
|
|
||||||
|
eval $tblv="\"\$_tbl\""
|
||||||
|
}
|
||||||
|
pf_anchor_port_target()
|
||||||
|
{
|
||||||
|
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
||||||
|
echo "{80,443}"
|
||||||
|
elif [ "$MODE_HTTPS" = "1" ]; then
|
||||||
|
echo "443"
|
||||||
|
elif [ "$MODE_HTTP" = "1" ]; then
|
||||||
|
echo "80"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
pf_anchor_zapret_v4_tpws()
|
||||||
|
{
|
||||||
|
# $1 - port
|
||||||
|
|
||||||
|
local rule port=$(pf_anchor_port_target)
|
||||||
|
for lan in $IFACE_LAN; do
|
||||||
|
for t in $tbl; do
|
||||||
|
echo "rdr on $lan inet proto tcp from any to $t port $port -> 127.0.0.1 port $1"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
echo "rdr on lo0 inet proto tcp from !127.0.0.0/8 to any port $port -> 127.0.0.1 port $1"
|
||||||
|
for t in $tbl; do
|
||||||
|
rule="route-to (lo0 127.0.0.1) inet proto tcp from !127.0.0.0/8 to $t port $port user { >root }"
|
||||||
|
if [ -n "$IFACE_WAN" ] ; then
|
||||||
|
for wan in $IFACE_WAN; do
|
||||||
|
echo "pass out on $wan $rule"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "pass out $rule"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
pf_anchor_zapret_v4()
|
||||||
|
{
|
||||||
|
local tbl port
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
case $MODE in
|
||||||
|
tpws)
|
||||||
|
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
||||||
|
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
||||||
|
pf_anchor_zapret_v4_tpws $TPPORT
|
||||||
|
;;
|
||||||
|
custom)
|
||||||
|
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
||||||
|
existf zapret_custom_firewall_v4 && zapret_custom_firewall_v4
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pf_anchor_zapret_v6_tpws()
|
||||||
|
{
|
||||||
|
# $1 - port
|
||||||
|
|
||||||
|
local LL_LAN rule port=$(pf_anchor_port_target)
|
||||||
|
# LAN link local is only for router
|
||||||
|
for lan in $IFACE_LAN; do
|
||||||
|
LL_LAN=$(get_ipv6_linklocal $lan)
|
||||||
|
[ -n "$LL_LAN" ] && {
|
||||||
|
for t in $tbl; do
|
||||||
|
echo "rdr on $lan inet6 proto tcp from any to $t port $port -> $LL_LAN port $1"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
done
|
||||||
|
echo "rdr on lo0 inet6 proto tcp from !::1 to any port $port -> fe80::1 port $1"
|
||||||
|
for t in $tbl; do
|
||||||
|
rule="route-to (lo0 fe80::1) inet6 proto tcp from !::1 to $t port $port user { >root }"
|
||||||
|
if [ -n "$IFACE_WAN" ] ; then
|
||||||
|
for wan in $IFACE_WAN; do
|
||||||
|
echo "pass out on $wan $rule"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "pass out $rule"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
pf_anchor_zapret_v6()
|
||||||
|
{
|
||||||
|
local tbl port
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
|
case $MODE in
|
||||||
|
tpws)
|
||||||
|
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
||||||
|
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
||||||
|
pf_anchor_zapret_v6_tpws $TPPORT
|
||||||
|
;;
|
||||||
|
custom)
|
||||||
|
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
||||||
|
existf zapret_custom_firewall_v6 && zapret_custom_firewall_v6
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pf_anchors_create()
|
||||||
|
{
|
||||||
|
wait_lan_ll
|
||||||
|
pf_anchor_zapret >"$PF_ANCHOR_ZAPRET"
|
||||||
|
pf_anchor_zapret_v4 >"$PF_ANCHOR_ZAPRET_V4"
|
||||||
|
pf_anchor_zapret_v6 >"$PF_ANCHOR_ZAPRET_V6"
|
||||||
|
}
|
||||||
|
pf_anchors_del()
|
||||||
|
{
|
||||||
|
rm -f "$PF_ANCHOR_ZAPRET" "$PF_ANCHOR_ZAPRET_V4" "$PF_ANCHOR_ZAPRET_V6"
|
||||||
|
}
|
||||||
|
pf_anchors_load()
|
||||||
|
{
|
||||||
|
echo loading zapret anchor from "$PF_ANCHOR_ZAPRET"
|
||||||
|
pfctl -qa zapret -f "$PF_ANCHOR_ZAPRET" || {
|
||||||
|
echo error loading zapret anchor
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if [ "$DISABLE_IPV4" = "1" ]; then
|
||||||
|
echo clearing zapret-v4 anchor
|
||||||
|
pfctl -qa zapret-v4 -F all 2>/dev/null
|
||||||
|
else
|
||||||
|
echo loading zapret-v4 anchor from "$PF_ANCHOR_ZAPRET_V4"
|
||||||
|
pfctl -qa zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4" || {
|
||||||
|
echo error loading zapret-v4 anchor
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
if [ "$DISABLE_IPV6" = "1" ]; then
|
||||||
|
echo clearing zapret-v6 anchor
|
||||||
|
pfctl -qa zapret-v6 -F all 2>/dev/null
|
||||||
|
else
|
||||||
|
echo loading zapret-v6 anchor from "$PF_ANCHOR_ZAPRET_V6"
|
||||||
|
pfctl -qa zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6" || {
|
||||||
|
echo error loading zapret-v6 anchor
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
echo successfully loaded PF anchors
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
pf_anchors_clear()
|
||||||
|
{
|
||||||
|
echo clearing zapret anchors
|
||||||
|
pfctl -qa zapret-v4 -F all 2>/dev/null
|
||||||
|
pfctl -qa zapret-v6 -F all 2>/dev/null
|
||||||
|
pfctl -qa zapret -F all 2>/dev/null
|
||||||
|
}
|
||||||
|
pf_enable()
|
||||||
|
{
|
||||||
|
echo enabling PF
|
||||||
|
pfctl -qe
|
||||||
|
}
|
||||||
|
pf_table_reload()
|
||||||
|
{
|
||||||
|
echo reloading zapret tables
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || pfctl -qTl -a zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4"
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || pfctl -qTl -a zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6"
|
||||||
|
pfctl -qTl -a zapret -f "$PF_ANCHOR_ZAPRET"
|
||||||
|
}
|
45
common/queue.sh
Normal file
45
common/queue.sh
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
get_nfqws_qnums()
|
||||||
|
{
|
||||||
|
# $1 - var name for ipv4 http
|
||||||
|
# $2 - var name for ipv4 https
|
||||||
|
# $3 - var name for ipv6 http
|
||||||
|
# $4 - var name for ipv6 https
|
||||||
|
local _qn _qns _qn6 _qns6
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
_qn=$QNUM
|
||||||
|
_qns=$_qn
|
||||||
|
[ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || _qns=$(($QNUM+1))
|
||||||
|
}
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
|
_qn6=$(($QNUM+2))
|
||||||
|
_qns6=$(($QNUM+3))
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
if [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then
|
||||||
|
_qn6=$_qn;
|
||||||
|
elif [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then
|
||||||
|
_qn6=$_qns;
|
||||||
|
fi
|
||||||
|
if [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then
|
||||||
|
_qns6=$_qn;
|
||||||
|
elif [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then
|
||||||
|
_qns6=$_qns;
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
[ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP6" ] && _qns6=$_qn6;
|
||||||
|
}
|
||||||
|
if [ "$MODE_HTTP" = 1 ]; then
|
||||||
|
eval $1=$_qn
|
||||||
|
eval $3=$_qn6
|
||||||
|
else
|
||||||
|
eval $1=
|
||||||
|
eval $3=
|
||||||
|
fi
|
||||||
|
if [ "$MODE_HTTPS" = 1 ]; then
|
||||||
|
eval $2=$_qns
|
||||||
|
eval $4=$_qns6
|
||||||
|
else
|
||||||
|
eval $2=
|
||||||
|
eval $4=
|
||||||
|
fi
|
||||||
|
}
|
12
config
12
config
@ -4,10 +4,15 @@
|
|||||||
# can help in case /tmp has not enough space
|
# can help in case /tmp has not enough space
|
||||||
#TMPDIR=/opt/zapret/tmp
|
#TMPDIR=/opt/zapret/tmp
|
||||||
|
|
||||||
|
# override firewall type : iptables,nftables,ipfw
|
||||||
|
#FWTYPE=iptables
|
||||||
|
|
||||||
# options for ipsets
|
# options for ipsets
|
||||||
|
# maximum number of elements in sets. also used for nft sets
|
||||||
|
SET_MAXELEM=262144
|
||||||
# too low hashsize can cause memory allocation errors on low RAM systems , even if RAM is enough
|
# too low hashsize can cause memory allocation errors on low RAM systems , even if RAM is enough
|
||||||
# too large hashsize will waste lots of RAM
|
# too large hashsize will waste lots of RAM
|
||||||
IPSET_OPT="hashsize 262144 maxelem 2097152"
|
IPSET_OPT="hashsize 262144 maxelem $SET_MAXELEM"
|
||||||
|
|
||||||
# options for ip2net. "-4" or "-6" auto added by ipset create script
|
# options for ip2net. "-4" or "-6" auto added by ipset create script
|
||||||
IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
|
IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
|
||||||
@ -65,9 +70,8 @@ FLOWOFFLOAD=donttouch
|
|||||||
#IFACE_LAN=eth0
|
#IFACE_LAN=eth0
|
||||||
#IFACE_WAN=eth1
|
#IFACE_WAN=eth1
|
||||||
|
|
||||||
# should init scripts apply firewall rules ?
|
# should start/stop command of init scripts apply firewall rules ?
|
||||||
# set to 0 if firewall control system is present
|
# not applicable to older openwrt with fw3 firewall
|
||||||
# openwrt uses fw3 firewall , init never touch fw
|
|
||||||
INIT_APPLY_FW=1
|
INIT_APPLY_FW=1
|
||||||
|
|
||||||
# do not work with ipv4
|
# do not work with ipv4
|
||||||
|
@ -218,3 +218,7 @@ nfqws: ipfrag
|
|||||||
v45
|
v45
|
||||||
|
|
||||||
nfqws: hop-by-hop ipv6 desync and fooling
|
nfqws: hop-by-hop ipv6 desync and fooling
|
||||||
|
|
||||||
|
v46
|
||||||
|
|
||||||
|
big startup script refactoring to support nftables and new openwrt snapshot builds with firewall4
|
||||||
|
92
docs/nftables_notes.txt
Normal file
92
docs/nftables_notes.txt
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
nftables - это технология, пришедшая на замену iptables.
|
||||||
|
В ней собрали все, что относилось к различным iptables. А их немало. iptables, ip6tables, ebtables, arptables, ipset.
|
||||||
|
Весь код из разрозненных, но похожих компонент, собрали в одно целое с единым синтаксисом.
|
||||||
|
Добавили различные конструкции языка, позволяющие писать правила более лаконично, не повторяя одни и те же команды с небольшими различиями.
|
||||||
|
На nftables можно сделать почти все, что можно было сделать на iptables. Есть то, что можно сделать на nftables, но нельзя на iptables.
|
||||||
|
Удобно, красиво.
|
||||||
|
|
||||||
|
К сожалению, не обошлось и без боли. 10 лет развития nftables казалось бы должны были вылизать все. Но не тут то было.
|
||||||
|
|
||||||
|
Главная боль N1. Очень серьезная, актуальная для openwrt, и решения не видно.
|
||||||
|
|
||||||
|
ipset-ы позволяли загонять пересекающиеся интервалы ip адресов или подсетей.
|
||||||
|
nftables sets это не позволяют. Любое пересечение вызывает ошибку.
|
||||||
|
Есть auto-merge, но это работает только в user mode в процессе nft, при условии, что весь блок адресов загоняется одной командой
|
||||||
|
и нет пересечений с уже имеющимся контентом в set.
|
||||||
|
Это не было бы критической проблемой, поскольку скрипты zapret и так загоняют ipset целиком.
|
||||||
|
Проблема в катастрофическом расходе памяти при операции загона больших интервальных листов, то есть с подсетями и диапазонами.
|
||||||
|
Чтобы загнать 100000 ipv4 записей, едва хватает 300 Mb памяти устройства.
|
||||||
|
При успехе операции в ядре список столько не занимает, но суть дела это не меняет.
|
||||||
|
Для традиционных linux систем это не проблема, но почти все роутеры загнутся.
|
||||||
|
Приемлемого решения не просматривается.
|
||||||
|
Сделать записи непересекающимися в листах - задача непростая. Потребуется переписать алгоритм auto-merge из nft,
|
||||||
|
но с пониженным расходом памяти.
|
||||||
|
Загонять записи по одному отдельными вызовами nft, игнорируя ошибки, займет вечность.
|
||||||
|
Загонять блоком отдельных команд, игнорируя ошибки, - nft такого не умеет. Похоже, при любой ошибке происходит откат всего скрипта.
|
||||||
|
К тому же при таком подходе будут неточности в итоговом результате.
|
||||||
|
Swap позволяет немного сгладить проблему, но лишь незначительно.
|
||||||
|
Скажем, если вдруг list загоняется без ошибок с 300 Mb памяти и с падением на 256 Mb, то swap спасает.
|
||||||
|
Если памяти становится 200 Mb, то swap уже не спасет. Все равно вызывается OOM killer, заодно убивая и другие процессы, кроме nft,
|
||||||
|
а это уже совсем плохо. Может быть убито что-то важное.
|
||||||
|
|
||||||
|
Боль N2, но не такая смертельная.
|
||||||
|
|
||||||
|
10 лет вылизывания кода, но при загоне больших листов в set-ы то и дело при вызовах nft list происходят seg faults.
|
||||||
|
Например, падать может nft -t list ruleset, но nft -t list table inet zapret может не падать.
|
||||||
|
Вроде это не влияет на функционал, но все равно создается неудобство.
|
||||||
|
|
||||||
|
Боль N3, не смертельная, но тоже не айс.
|
||||||
|
|
||||||
|
Какие-то нерациональные алгоритмы разбора таблиц в nft.
|
||||||
|
Например, есть 1 большой set на 100000 элементов и 1 маленький на 2 элемента.
|
||||||
|
Чтобы просто пролистать мелкий set или добавить туда еще что-то nft будет мусолить несколько секунд.
|
||||||
|
Что он делает за это время ? Тащит из ядра огромный блоб, в котором все в куче, и разбирает его, чтобы выделить искомую мелочь ?
|
||||||
|
В какой-то мере удается это сгладить, обьединяя несколько команд в единый скрипт.
|
||||||
|
|
||||||
|
|
||||||
|
Плюс N1, главный
|
||||||
|
|
||||||
|
iptables хороши, когда ими пользуется кто-то один. Иначе это проходной двор.
|
||||||
|
Когда есть система управления фаерволом, то приходится как-то к ней прикручиваться, чтобы не нарушить ее работу
|
||||||
|
и управлять правилами синхронно. Нужно уметь внести и удалить отдельные правила когда это нужно, не трогая все остальное.
|
||||||
|
Некоторые системы управления фаерволом вообще не предполагают, чтобы кто-то еще лез в iptables, и это очень сильно портит жизнь.
|
||||||
|
У iptables есть предопределенный набор хуков netfilter с фиксированным приоритетом.
|
||||||
|
В nftables хуков можно создать неограниченное количество с выбранным приоритетом, управляя ими независимо в отдельных таблицах.
|
||||||
|
Система управления фаерволом может работать в одной таблице (fw4 в случае openwrt) и не трогать все остальное.
|
||||||
|
zapret может работать в другой таблице и не трогать систему управления фаерволом. Они друг другу не мешают.
|
||||||
|
Это снимает множество боли.
|
||||||
|
|
||||||
|
Плюс N2
|
||||||
|
|
||||||
|
Возможность выбора приоритета хука позволяет легко решить проблему хаотической и принудительной дефрагментацией L3 ipv6,
|
||||||
|
без танцев с загрузкой модулей ядра со специальными параметрами или перекомпиляцией nftables-nft.
|
||||||
|
|
||||||
|
Плюс N3
|
||||||
|
|
||||||
|
Наличие множеств (anonymous/named sets) позволяет не писать кучу однообразных правил там, где в iptables их пришлось бы написать.
|
||||||
|
|
||||||
|
Плюс N4
|
||||||
|
|
||||||
|
Если у вас есть nftables, то там наверняка есть уже все или почти все.
|
||||||
|
Нет кучи разных модулей ядра и .so плагинов для iptables user-mode процесса.
|
||||||
|
Отдельные модули ядра есть, но их меньше, чем в iptables, и openwrt их делит на меньшее число пакетов, большинство из которых
|
||||||
|
и так ставятся по умолчанию. user-mode процесс nft и вовсе неделим. EXE-шник + lib.
|
||||||
|
|
||||||
|
Плюс N5
|
||||||
|
|
||||||
|
Пишут, что nftables работают быстрее.
|
||||||
|
|
||||||
|
|
||||||
|
Выводы
|
||||||
|
|
||||||
|
Честно говоря, лучше бы openwrt оставался на iptables.
|
||||||
|
Пусть они и старые, c недостатками, но как говорится ложка дегтя портит цистерну меда.
|
||||||
|
nftables - именно тот случай. Все хорошо, но все плохо из-за досадной особенности.
|
||||||
|
Без больших листов все почти прекрасно. Но большие ip листы убивают все. Не для домашних это роутеров.
|
||||||
|
А ipset-ы к nftables не прикрутить.
|
||||||
|
Делать нечего. Openwrt отошел от iptables. С этим придется как-то жить.
|
||||||
|
Поэтому пришлось сделать для openwrt поддержку и iptables, и nftables (только с версии openwrt 21.xx, в более старых будут проблемы).
|
||||||
|
iptables можно задействовать на любой openwrt версии.
|
||||||
|
Если используется fw3, применяется старый механизм интеграции в fw3.
|
||||||
|
Если он не используется, то правилами iptables управляем как в традиционных linux системах - то есть с возможностью
|
||||||
|
запуска и остановки, а скрипт запуска вносит в том числе и правила iptables.
|
@ -49,7 +49,7 @@ deal with its consequences.
|
|||||||
3. Modification of TCP connection at the packet level. Implemented through the NFQUEUE handler and raw sockets.
|
3. Modification of TCP connection at the packet level. Implemented through the NFQUEUE handler and raw sockets.
|
||||||
|
|
||||||
For options 2 and 3, tpws and nfqws programs are implemented, respectively.
|
For options 2 and 3, tpws and nfqws programs are implemented, respectively.
|
||||||
You need to run them with the necessary parameters and redirect certain traffic with iptables.
|
You need to run them with the necessary parameters and redirect certain traffic with iptables or nftables.
|
||||||
|
|
||||||
To redirect a TCP connection to a transparent proxy, the following commands are used:
|
To redirect a TCP connection to a transparent proxy, the following commands are used:
|
||||||
|
|
||||||
@ -110,6 +110,17 @@ In the PREROUTING DNAT chain, it is possible to any global address or to the lin
|
|||||||
the packet came from.
|
the packet came from.
|
||||||
NFQUEUE works without changes.
|
NFQUEUE works without changes.
|
||||||
|
|
||||||
|
|
||||||
|
## nftables
|
||||||
|
|
||||||
|
nftables are fine except one very big problem.
|
||||||
|
nft requires tons of RAM to load large nf sets (ip lists) with subnets/intervals. Most of the home routers can't afford that.
|
||||||
|
For example, even a 256 Mb system can't load a 100K ip list. nft process will OOM.
|
||||||
|
nf sets do not support overlapping intervals and that's why nft process applies very RAM consuming algorithm to merge intervals so they don't overlap.
|
||||||
|
There're equivalents to iptables for all other functions. Interface and protocol anonymous sets allow not to write multiple similar rules.
|
||||||
|
Flow offloading is built-in into new linux kernels and nft versions.
|
||||||
|
|
||||||
|
|
||||||
## When it will not work
|
## When it will not work
|
||||||
|
|
||||||
* If DNS server returns false responses. ISP can return false IP addresses or not return anything
|
* If DNS server returns false responses. ISP can return false IP addresses or not return anything
|
||||||
@ -564,6 +575,9 @@ if remote resolving causes trouble configure clients to use local name resolutio
|
|||||||
|
|
||||||
## Ways to get a list of blocked IP
|
## Ways to get a list of blocked IP
|
||||||
|
|
||||||
|
nftables can't work with ipsets. Native nf sets require lots of RAM to load large ip lists with subnets and intervals.
|
||||||
|
In case you're on a low RAM system and need large lists it may be required to fall back to iptables+ipset.
|
||||||
|
|
||||||
1. Enter the blocked domains to `ipset/zapret-hosts-user.txt` and run `ipset/get_user.sh`
|
1. Enter the blocked domains to `ipset/zapret-hosts-user.txt` and run `ipset/get_user.sh`
|
||||||
At the output, you get `ipset/zapret-ip-user.txt` with IP addresses.
|
At the output, you get `ipset/zapret-ip-user.txt` with IP addresses.
|
||||||
|
|
||||||
@ -643,6 +657,12 @@ When using large regulator lists estimate the amount of RAM on the router !
|
|||||||
The file `/opt/zapret/config` is used by various components of the system and contains basic settings.
|
The file `/opt/zapret/config` is used by various components of the system and contains basic settings.
|
||||||
It needs to be viewed and edited if necessary.
|
It needs to be viewed and edited if necessary.
|
||||||
|
|
||||||
|
Which firewall type use on linux systems : `nftables` or `iptables`.
|
||||||
|
On traditional systems `nftables` is selected by default if nft is installed.
|
||||||
|
On openwrt by default `nftables` is selected on `firewall4` based systems.
|
||||||
|
|
||||||
|
`FWTYPE=iptables`
|
||||||
|
|
||||||
Main mode :
|
Main mode :
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -739,8 +759,9 @@ temp directory. Used by ipset/*.sh scripts for large lists processing.
|
|||||||
/tmp by default. Can be reassigned if /tmp is tmpfs and RAM is low.
|
/tmp by default. Can be reassigned if /tmp is tmpfs and RAM is low.
|
||||||
TMPDIR=/opt/zapret/tmp
|
TMPDIR=/opt/zapret/tmp
|
||||||
|
|
||||||
ipset options :
|
ipset and nfset options :
|
||||||
|
|
||||||
|
`SET_MAXELEM=262144`
|
||||||
`IPSET_OPT="hashsize 262144 maxelem 2097152`
|
`IPSET_OPT="hashsize 262144 maxelem 2097152`
|
||||||
|
|
||||||
Kernel automatically increases hashsize if ipset is too large for the current hashsize.
|
Kernel automatically increases hashsize if ipset is too large for the current hashsize.
|
||||||
@ -770,6 +791,11 @@ In openwrt there's default network 'lan'. Only traffic coming from this network
|
|||||||
To override this behaviour set the following variable :
|
To override this behaviour set the following variable :
|
||||||
`OPENWRT_LAN="lan lan2 lan3"`
|
`OPENWRT_LAN="lan lan2 lan3"`
|
||||||
|
|
||||||
|
The `INIT_APPLY_FW=1` parameter enables the init script to independently apply iptables rules.
|
||||||
|
With other values or if the parameter is commented out, the rules will not be applied.
|
||||||
|
This is useful if you have a firewall management system, in the settings of which you should tie the rules.
|
||||||
|
Not applicable to `OpenWRT` if used with `firewall3+iptables`.
|
||||||
|
|
||||||
The following settings are not relevant for openwrt :
|
The following settings are not relevant for openwrt :
|
||||||
|
|
||||||
If your system works as a router, then you need to enter the names of the internal and external interfaces:
|
If your system works as a router, then you need to enter the names of the internal and external interfaces:
|
||||||
@ -781,10 +807,6 @@ IMPORTANT: configuring routing, masquerade, etc. not a zapret task.
|
|||||||
Only modes that intercept transit traffic are enabled.
|
Only modes that intercept transit traffic are enabled.
|
||||||
It's possible to specify multiple interfaces like this : `IFACE_LAN="eth0 eth1 eth2"`
|
It's possible to specify multiple interfaces like this : `IFACE_LAN="eth0 eth1 eth2"`
|
||||||
|
|
||||||
The `INIT_APPLY_FW=1` parameter enables the init script to independently apply iptables rules.
|
|
||||||
With other values or if the parameter is commented out, the rules will not be applied.
|
|
||||||
This is useful if you have a firewall management system, in the settings of which you should tie the rules.
|
|
||||||
|
|
||||||
|
|
||||||
## Screwing to the firewall control system or your launch system
|
## Screwing to the firewall control system or your launch system
|
||||||
|
|
||||||
@ -795,17 +817,41 @@ In this case, the rules for iptables should be screwed to your firewall separate
|
|||||||
The following calls allow you to apply or remove iptables rules separately:
|
The following calls allow you to apply or remove iptables rules separately:
|
||||||
|
|
||||||
```
|
```
|
||||||
/opt/zapret/init.d/sysv/zapret start-fw
|
/opt/zapret/init.d/sysv/zapret start_fw
|
||||||
/opt/zapret/init.d/sysv/zapret stop-fw
|
/opt/zapret/init.d/sysv/zapret stop_fw
|
||||||
|
/opt/zapret/init.d/sysv/zapret restart_fw
|
||||||
```
|
```
|
||||||
|
|
||||||
And you can start or stop the demons separately from the firewall:
|
And you can start or stop the demons separately from the firewall:
|
||||||
|
|
||||||
```
|
```
|
||||||
/opt/zapret/init.d/sysv/zapret start-daemons
|
/opt/zapret/init.d/sysv/zapret start_daemons
|
||||||
/opt/zapret/init.d/sysv/zapret stop-daemons
|
/opt/zapret/init.d/sysv/zapret stop_daemons
|
||||||
|
/opt/zapret/init.d/sysv/zapret restart_daemons
|
||||||
```
|
```
|
||||||
|
|
||||||
|
nftables nearly eliminate conflicts betweeen firewall control systems because they allow
|
||||||
|
separate tables and netfilter hooks. `zapret` nf table is used for zapret purposes.
|
||||||
|
If your system does not touch it everything will likely be OK.
|
||||||
|
|
||||||
|
Some additional nftables-only calls exist :
|
||||||
|
|
||||||
|
Lookup `lanif`, `wanif`, `wanif6` and `flow table` interface sets.
|
||||||
|
```
|
||||||
|
/opt/zapret/init.d/sysv/zapret list_ifsets
|
||||||
|
```
|
||||||
|
|
||||||
|
Renew `lanif`, `wanif`, `wanif6` and `flow table` interface sets.
|
||||||
|
Taken from `IFACE_LAN`, `IFACE_WAN` config variables on traditional Linux systems.
|
||||||
|
Autoselected on `OpenWRT`. `lanif` can be extended using `OPENWRT_LAN` config variable.
|
||||||
|
/opt/zapret/init.d/sysv/zapret reload_ifsets
|
||||||
|
|
||||||
|
Calls `nft -t list table inet zapret`.
|
||||||
|
```
|
||||||
|
/opt/zapret/init.d/sysv/zapret list_table
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Checking ISP
|
### Checking ISP
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
zapret v.45
|
zapret v.46
|
||||||
|
|
||||||
English
|
English
|
||||||
-------
|
-------
|
||||||
@ -63,7 +63,7 @@ For english version refer to docs/readme.eng.txt
|
|||||||
|
|
||||||
Для вариантов 2 и 3 реализованы программы tpws и nfqws соответственно.
|
Для вариантов 2 и 3 реализованы программы tpws и nfqws соответственно.
|
||||||
Чтобы они работали, необходимо их запустить с нужными параметрами и перенаправить на них определенный трафик
|
Чтобы они работали, необходимо их запустить с нужными параметрами и перенаправить на них определенный трафик
|
||||||
средствами iptables.
|
средствами iptables или nftables.
|
||||||
|
|
||||||
|
|
||||||
Для перенаправления tcp соединения на transparent proxy используются команды следующего вида :
|
Для перенаправления tcp соединения на transparent proxy используются команды следующего вида :
|
||||||
@ -149,6 +149,14 @@ DNAT на localhost (::1) возможен только в цепочке OUTPUT
|
|||||||
NFQUEUE работает без изменений.
|
NFQUEUE работает без изменений.
|
||||||
|
|
||||||
|
|
||||||
|
Особенности применения nftables
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Более подробно преимущества и недостатки nftables применительно к данной системе описаны в docs/nftables_notes.txt
|
||||||
|
Если коротко, то в nftables невозможно работать с большими ip листами на системах с малым количеством RAM.
|
||||||
|
Остальные рассматриваемые здесь функции могут быть перенесены на nftables.
|
||||||
|
|
||||||
|
|
||||||
Когда это работать не будет
|
Когда это работать не будет
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
@ -490,6 +498,9 @@ options ip6table_raw raw_before_defrag=1
|
|||||||
|
|
||||||
Это нужно сделать вручную, никакой автоматики в blockcheck.sh нет.
|
Это нужно сделать вручную, никакой автоматики в blockcheck.sh нет.
|
||||||
|
|
||||||
|
Либо можно раз и навсегда избавиться от этой проблемы, используя nftables. Там можно создать netfilter hook
|
||||||
|
с любым приоритетом. Используйте приоритет -401 и ниже.
|
||||||
|
|
||||||
tpws
|
tpws
|
||||||
-----
|
-----
|
||||||
|
|
||||||
@ -642,6 +653,10 @@ tpws полностью работает на асинхронных сокет
|
|||||||
Способы получения списка заблокированных IP
|
Способы получения списка заблокированных IP
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
|
!!! nftables не могут работать с ipset-ами. Собственный аналогичный механизм требует огромного количество RAM
|
||||||
|
!!! для загрузки больших листов. Например, для загона 100K записей в nfset не хватает даже 256 Mb.
|
||||||
|
!!! Если вам нужны большие листы на домашних роутерах, откатывайтесь на iptables+ipset.
|
||||||
|
|
||||||
1) Внесите заблокированные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
|
1) Внесите заблокированные домены в ipset/zapret-hosts-user.txt и запустите ipset/get_user.sh
|
||||||
На выходе получите ipset/zapret-ip-user.txt с IP адресами.
|
На выходе получите ipset/zapret-ip-user.txt с IP адресами.
|
||||||
|
|
||||||
@ -829,6 +844,11 @@ tpws и nfqws решают нужно ли применять дурение в
|
|||||||
Файл /opt/zapret/config используется различными компонентами системы и содержит основные настройки.
|
Файл /opt/zapret/config используется различными компонентами системы и содержит основные настройки.
|
||||||
Его нужно просмотреть и при необходимости отредактировать.
|
Его нужно просмотреть и при необходимости отредактировать.
|
||||||
|
|
||||||
|
На linux системах можно выбрать использовать iptables или nftables.
|
||||||
|
По умолчанию на традиционных linux выбирается nftables, если установлен nft.
|
||||||
|
На openwrt по умолчанию выбирается nftables на новых версиях с firewall4.
|
||||||
|
|
||||||
|
FWTYPE=iptables
|
||||||
|
|
||||||
Основной режим :
|
Основной режим :
|
||||||
tpws - tpws в режиме transparent
|
tpws - tpws в режиме transparent
|
||||||
@ -910,8 +930,11 @@ MDIG_THREADS=30
|
|||||||
указать место на флэшке или диске.
|
указать место на флэшке или диске.
|
||||||
TMPDIR=/opt/zapret/tmp
|
TMPDIR=/opt/zapret/tmp
|
||||||
|
|
||||||
Опции для создания ipset-ов
|
Опции для создания ipset-ов и nfset-ов
|
||||||
|
|
||||||
|
SET_MAXELEM=262144
|
||||||
IPSET_OPT="hashsize 262144 maxelem 2097152"
|
IPSET_OPT="hashsize 262144 maxelem 2097152"
|
||||||
|
|
||||||
ПРО РУГАНЬ в dmesg по поводу нехватки памяти.
|
ПРО РУГАНЬ в dmesg по поводу нехватки памяти.
|
||||||
Может так случиться, что памяти в системе достаточно, но при попытке заполнить огромный ipset
|
Может так случиться, что памяти в системе достаточно, но при попытке заполнить огромный ipset
|
||||||
ядро начинает громко ругаться, ipset заполняется не полностью.
|
ядро начинает громко ругаться, ipset заполняется не полностью.
|
||||||
@ -939,6 +962,11 @@ GZIP_LISTS=1
|
|||||||
Но возможно задать другие сети или список сетей :
|
Но возможно задать другие сети или список сетей :
|
||||||
OPENWRT_LAN="lan lan2 lan3"
|
OPENWRT_LAN="lan lan2 lan3"
|
||||||
|
|
||||||
|
Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.
|
||||||
|
При иных значениях или если параметр закомментирован, правила применены не будут.
|
||||||
|
Это полезно, если у вас есть система управления фаерволом, в настройки которой и следует прикрутить правила.
|
||||||
|
На openwrt неприменимо при использовании firewall3+iptables.
|
||||||
|
|
||||||
Следующие настройки не актуальны для openwrt :
|
Следующие настройки не актуальны для openwrt :
|
||||||
|
|
||||||
Если ваша система работает как роутер, то нужно вписать названия внутреннего и внешнего интерфейсов :
|
Если ваша система работает как роутер, то нужно вписать названия внутреннего и внешнего интерфейсов :
|
||||||
@ -948,10 +976,6 @@ IFACE_WAN=eth1
|
|||||||
Включаются только режимы, обеспечивающие перехват транзитного трафика.
|
Включаются только режимы, обеспечивающие перехват транзитного трафика.
|
||||||
Возможно определить несколько интерфейсов следующим образом : IFACE_LAN="eth0 eth1 eth2"
|
Возможно определить несколько интерфейсов следующим образом : IFACE_LAN="eth0 eth1 eth2"
|
||||||
|
|
||||||
Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.
|
|
||||||
При иных значениях или если параметр закомментирован, правила применены не будут.
|
|
||||||
Это полезно, если у вас есть система управления фаерволом, в настройки которой и следует прикрутить правила.
|
|
||||||
|
|
||||||
Прикручивание к системе управления фаерволом или своей системе запуска
|
Прикручивание к системе управления фаерволом или своей системе запуска
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
@ -961,13 +985,34 @@ IFACE_WAN=eth1
|
|||||||
|
|
||||||
Следующие вызовы позволяют применить или убрать правила iptables отдельно :
|
Следующие вызовы позволяют применить или убрать правила iptables отдельно :
|
||||||
|
|
||||||
/opt/zapret/init.d/sysv/zapret start-fw
|
/opt/zapret/init.d/sysv/zapret start_fw
|
||||||
/opt/zapret/init.d/sysv/zapret stop-fw
|
/opt/zapret/init.d/sysv/zapret stop_fw
|
||||||
|
/opt/zapret/init.d/sysv/zapret restart_fw
|
||||||
|
|
||||||
А так можно запустить или остановить демоны отдельно от фаервола :
|
А так можно запустить или остановить демоны отдельно от фаервола :
|
||||||
|
|
||||||
/opt/zapret/init.d/sysv/zapret start-daemons
|
/opt/zapret/init.d/sysv/zapret start_daemons
|
||||||
/opt/zapret/init.d/sysv/zapret stop-daemons
|
/opt/zapret/init.d/sysv/zapret stop_daemons
|
||||||
|
/opt/zapret/init.d/sysv/zapret restart_daemons
|
||||||
|
|
||||||
|
nftables сводят практически на нет конфликты между разными системами управления, поскольку позволяют
|
||||||
|
использовать независимые таблицы и хуки. Используется отдельная nf-таблица "zapret".
|
||||||
|
Если ваша система ее не будет трогать, скорее всего все будет нормально.
|
||||||
|
|
||||||
|
Для nftables предусмотрено несколько дополнительных вызовов :
|
||||||
|
|
||||||
|
Посмотреть set-ы интерфейсов, относящихся к lan, wan и wan6. По ним идет завертывание трафика.
|
||||||
|
А так же таблицу flow table с именами интерфейсов ingress hook.
|
||||||
|
/opt/zapret/init.d/sysv/zapret list_ifsets
|
||||||
|
|
||||||
|
Обновить set-ы интерфейсов, относящихся к lan, wan и wan6.
|
||||||
|
Для традиционных linux список интерфейсов берется из переменных конфига IFACE_LAN, IFACE_WAN.
|
||||||
|
Для openwrt определяется автоматически. Множество lanif может быть расширено параметром OPENWRT_LAN.
|
||||||
|
Все интерфейсы lan и wan так же добавляются в ingress hook от flow table.
|
||||||
|
/opt/zapret/init.d/sysv/zapret reload_ifsets
|
||||||
|
|
||||||
|
Просмотр таблицы без содержимого set-ов. Вызывает nft -t list table inet zapret
|
||||||
|
/opt/zapret/init.d/sysv/zapret list_table
|
||||||
|
|
||||||
Вариант custom
|
Вариант custom
|
||||||
--------------
|
--------------
|
||||||
@ -980,20 +1025,22 @@ custom код вынесен в отдельный shell include
|
|||||||
Нужно свой код вписать в функции :
|
Нужно свой код вписать в функции :
|
||||||
zapret_custom_daemons
|
zapret_custom_daemons
|
||||||
zapret_custom_firewall
|
zapret_custom_firewall
|
||||||
|
zapret_custom_firewall_nft
|
||||||
|
|
||||||
В файле custom пишите ваш код, пользуясь хелперами из "functions" или "zapret".
|
В файле custom пишите ваш код, пользуясь хелперами из "functions" или "zapret".
|
||||||
Смотрите как там сделано добавление iptables или запуск демонов.
|
Смотрите как там сделано добавление iptables или запуск демонов.
|
||||||
Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи
|
Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи
|
||||||
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
|
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
|
||||||
Хелперы это учитывают , вам нужно сосредоточиться лишь на фильтрах iptables и
|
Хелперы это учитывают , вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и
|
||||||
параметрах демонов.
|
параметрах демонов.
|
||||||
|
|
||||||
Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку.
|
Код для openwrt и sysv немного отличается. В sysv нужно обрабатывать и запуск, и остановку демонов.
|
||||||
Запуск это или остановка передается в параметре $1 (0 или 1).
|
Запуск это или остановка передается в параметре $1 (0 или 1).
|
||||||
В openwrt за остановку демонов отвечает procd, а firewall вычищается при "fw3 restart",
|
В openwrt за остановку отвечает procd.
|
||||||
потому нет необходимости реализовывать логику останова.
|
|
||||||
|
|
||||||
При апгрейде нужно сохранить лишь custom, другие файлы править не надо.
|
Для фаервола кастом пишется отдельно для iptables и nftables. Все очень похоже, но отличается
|
||||||
|
написание фильтров и названия процедур хелперов. Если вам не нужны iptables или nftables -
|
||||||
|
можете не писать соответствующую функцию.
|
||||||
|
|
||||||
Готовый custom скрипт custom-tpws4http-nfqws4https позволяет применить дурение
|
Готовый custom скрипт custom-tpws4http-nfqws4https позволяет применить дурение
|
||||||
tpws к http и nfqws к https. При этом поддерживаются установки из config.
|
tpws к http и nfqws к https. При этом поддерживаются установки из config.
|
||||||
@ -1011,6 +1058,8 @@ tpws к http и nfqws к https. При этом поддерживаются у
|
|||||||
apt-get update
|
apt-get update
|
||||||
apt-get install ipset curl dnsutils git
|
apt-get install ipset curl dnsutils git
|
||||||
|
|
||||||
|
Если хотите использовать nftables, то нужен пакет nftables, а ipset не обязателен.
|
||||||
|
|
||||||
Скопировать директорию zapret в /opt или скачать через git :
|
Скопировать директорию zapret в /opt или скачать через git :
|
||||||
cd /opt
|
cd /opt
|
||||||
git clone --depth 1 https://github.com/bol-van/zapret
|
git clone --depth 1 https://github.com/bol-van/zapret
|
||||||
@ -1124,7 +1173,7 @@ git и curl по умолчанию могут присутствовать, ips
|
|||||||
|
|
||||||
Подключить init скрипт :
|
Подключить init скрипт :
|
||||||
|
|
||||||
ln -fs /opt/zapret/init.d/sysv/zapret /etc/init.d
|
ln -fs /opt/zapret/init.d/openrc/zapret /etc/init.d
|
||||||
rc-update add zapret
|
rc-update add zapret
|
||||||
|
|
||||||
Запустить службу :
|
Запустить службу :
|
||||||
@ -1174,8 +1223,11 @@ install_easy.sh автоматизирует описанные выше руч
|
|||||||
Деинсталяция выполняется через uninstall_easy.sh
|
Деинсталяция выполняется через uninstall_easy.sh
|
||||||
|
|
||||||
|
|
||||||
Ручная установка на openwrt/LEDE
|
Ручная установка на openwrt/LEDE 15.xx-21.xx
|
||||||
--------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
|
!!! Данная инструкция написана для систем, основанных на iptables+firewall3
|
||||||
|
!!! В новых версиях openwrt переходит на nftables+firewall4, инструкция неприменима. Пользуйтесь install_easy.sh
|
||||||
|
|
||||||
Установить дополнительные пакеты :
|
Установить дополнительные пакеты :
|
||||||
opkg update
|
opkg update
|
||||||
@ -1283,10 +1335,10 @@ Cкрипт из /etc/hotplug.d/iface перезапустит демоны по
|
|||||||
|
|
||||||
Посмотреть через iptables -nL, ip6tables -nL или через luci вкладку "firewall" появились ли нужные правила.
|
Посмотреть через iptables -nL, ip6tables -nL или через luci вкладку "firewall" появились ли нужные правила.
|
||||||
|
|
||||||
ЭКОНОМИЯ МЕСТА : если его мало, то можно оставить в директории zapret лишь подкаталог ipset, файл config и init.d/openwrt.
|
ЭКОНОМИЯ МЕСТА : если его мало, то можно оставить в директории zapret лишь подкаталоги
|
||||||
|
ipset, common, файл config, init.d/openwrt.
|
||||||
Далее нужно создать подкаталоги с реально используемыми бинариками (ip2net, mdig, tpws, nfq)
|
Далее нужно создать подкаталоги с реально используемыми бинариками (ip2net, mdig, tpws, nfq)
|
||||||
и скопировать туда из binaries рабочие executables.
|
и скопировать туда из binaries рабочие executables.
|
||||||
Рекомендуется оставить ip2net и mdig. Из tpws и nfq оставить лишь тот, что был выбран в config.
|
|
||||||
|
|
||||||
ЕСЛИ ВСЕ ПЛОХО С МЕСТОМ : откажитесь от работы со списком РКН. используйте только get_user.sh
|
ЕСЛИ ВСЕ ПЛОХО С МЕСТОМ : откажитесь от работы со списком РКН. используйте только get_user.sh
|
||||||
|
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
|
# init script functions library for macos
|
||||||
|
|
||||||
[ -n "$ZAPRET_BASE" ] || ZAPRET_BASE=/opt/zapret
|
[ -n "$ZAPRET_BASE" ] || ZAPRET_BASE=/opt/zapret
|
||||||
|
. "$ZAPRET_BASE/config"
|
||||||
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
. "$ZAPRET_BASE/common/pf.sh"
|
||||||
|
|
||||||
IPSET_DIR=$ZAPRET_BASE/ipset
|
IPSET_DIR=$ZAPRET_BASE/ipset
|
||||||
. "$IPSET_DIR/def.sh"
|
. "$IPSET_DIR/def.sh"
|
||||||
@ -14,33 +19,9 @@ TPWS_WAIT="--bind-wait-ifup=30 --bind-wait-ip=30"
|
|||||||
TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30"
|
TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30"
|
||||||
[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
|
[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
|
||||||
|
|
||||||
PF_MAIN="/etc/pf.conf"
|
|
||||||
PF_ANCHOR_DIR=/etc/pf.anchors
|
|
||||||
PF_ANCHOR_ZAPRET="$PF_ANCHOR_DIR/zapret"
|
|
||||||
PF_ANCHOR_ZAPRET_V4="$PF_ANCHOR_DIR/zapret-v4"
|
|
||||||
PF_ANCHOR_ZAPRET_V6="$PF_ANCHOR_DIR/zapret-v6"
|
|
||||||
|
|
||||||
CUSTOM_SCRIPT="$ZAPRET_BASE/init.d/macos/custom"
|
CUSTOM_SCRIPT="$ZAPRET_BASE/init.d/macos/custom"
|
||||||
[ -f "$CUSTOM_SCRIPT" ] && . "$CUSTOM_SCRIPT"
|
[ -f "$CUSTOM_SCRIPT" ] && . "$CUSTOM_SCRIPT"
|
||||||
|
|
||||||
existf()
|
|
||||||
{
|
|
||||||
type "$1" >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
on_off_function()
|
|
||||||
{
|
|
||||||
# $1 : function name on
|
|
||||||
# $2 : function name off
|
|
||||||
# $3 : 0 - off, 1 - on
|
|
||||||
local F="$1"
|
|
||||||
[ "$3" = "1" ] || F="$2"
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
"$F" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
run_daemon()
|
run_daemon()
|
||||||
{
|
{
|
||||||
# $1 - daemon number : 1,2,3,...
|
# $1 - daemon number : 1,2,3,...
|
||||||
@ -134,263 +115,6 @@ get_ipv6_linklocal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pf_anchor_root_reload()
|
|
||||||
{
|
|
||||||
echo reloading PF root anchor
|
|
||||||
pfctl -qf "$PF_MAIN"
|
|
||||||
}
|
|
||||||
|
|
||||||
pf_anchor_root()
|
|
||||||
{
|
|
||||||
local patch
|
|
||||||
[ -f "$PF_MAIN" ] && {
|
|
||||||
grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" || {
|
|
||||||
echo patching rdr-anchor in $PF_MAIN
|
|
||||||
patch=1
|
|
||||||
sed -i '' -e '/^rdr-anchor "com\.apple\/\*"$/i \
|
|
||||||
rdr-anchor "zapret"
|
|
||||||
' $PF_MAIN
|
|
||||||
}
|
|
||||||
grep -q '^anchor "zapret"$' "$PF_MAIN" || {
|
|
||||||
echo patching anchor in $PF_MAIN
|
|
||||||
patch=1
|
|
||||||
sed -i '' -e '/^anchor "com\.apple\/\*"$/i \
|
|
||||||
anchor "zapret"
|
|
||||||
' $PF_MAIN
|
|
||||||
}
|
|
||||||
grep -q "^set limit table-entries" "$PF_MAIN" || {
|
|
||||||
echo patching table-entries limit
|
|
||||||
patch=1
|
|
||||||
sed -i '' -e '/^scrub-anchor "com\.apple\/\*"$/i \
|
|
||||||
set limit table-entries 5000000
|
|
||||||
' $PF_MAIN
|
|
||||||
}
|
|
||||||
|
|
||||||
grep -q '^anchor "zapret"$' "$PF_MAIN" &&
|
|
||||||
grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" &&
|
|
||||||
grep -q '^set limit table-entries' "$PF_MAIN" && {
|
|
||||||
if [ -n "$patch" ]; then
|
|
||||||
echo successfully patched $PF_MAIN
|
|
||||||
pf_anchor_root_reload
|
|
||||||
else
|
|
||||||
echo successfully checked zapret anchors in $PF_MAIN
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo ----------------------------------
|
|
||||||
echo Automatic $PF_MAIN patching failed. You must apply root anchors manually in your PF config.
|
|
||||||
echo rdr-anchor \"zapret\"
|
|
||||||
echo anchor \"zapret\"
|
|
||||||
echo ----------------------------------
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
pf_anchor_root_del()
|
|
||||||
{
|
|
||||||
sed -i '' -e '/^anchor "zapret"$/d' -e '/^rdr-anchor "zapret"$/d' -e '/^set limit table-entries/d' "$PF_MAIN"
|
|
||||||
}
|
|
||||||
|
|
||||||
pf_anchor_zapret()
|
|
||||||
{
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
|
||||||
if [ -f "$ZIPLIST_EXCLUDE" ]; then
|
|
||||||
echo "table <nozapret> persist file \"$ZIPLIST_EXCLUDE\""
|
|
||||||
else
|
|
||||||
echo "table <nozapret> persist"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
|
||||||
if [ -f "$ZIPLIST_EXCLUDE6" ]; then
|
|
||||||
echo "table <nozapret6> persist file \"$ZIPLIST_EXCLUDE6\""
|
|
||||||
else
|
|
||||||
echo "table <nozapret6> persist"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || echo "rdr-anchor \"/zapret-v4\" inet to !<nozapret>"
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || echo "rdr-anchor \"/zapret-v6\" inet6 to !<nozapret6>"
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || echo "anchor \"/zapret-v4\" inet to !<nozapret>"
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || echo "anchor \"/zapret-v6\" inet6 to !<nozapret6>"
|
|
||||||
}
|
|
||||||
pf_anchor_zapret_tables()
|
|
||||||
{
|
|
||||||
# $1 - variable to receive applied table names
|
|
||||||
# $2/$3 $4/$5 ... table_name/table_file
|
|
||||||
local tblv=$1
|
|
||||||
local _tbl
|
|
||||||
|
|
||||||
shift
|
|
||||||
[ "$MODE_FILTER" = "ipset" ] &&
|
|
||||||
{
|
|
||||||
while [ -n "$1" ] && [ -n "$2" ] ; do
|
|
||||||
[ -f "$2" ] && {
|
|
||||||
echo "table <$1> file \"$2\""
|
|
||||||
_tbl="$_tbl<$1> "
|
|
||||||
}
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
}
|
|
||||||
[ -n "$_tbl" ] || _tbl="any"
|
|
||||||
|
|
||||||
eval $tblv="\"\$_tbl\""
|
|
||||||
}
|
|
||||||
pf_anchor_port_target()
|
|
||||||
{
|
|
||||||
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
|
||||||
echo "{80,443}"
|
|
||||||
elif [ "$MODE_HTTPS" = "1" ]; then
|
|
||||||
echo "443"
|
|
||||||
elif [ "$MODE_HTTP" = "1" ]; then
|
|
||||||
echo "80"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
pf_anchor_zapret_v4_tpws()
|
|
||||||
{
|
|
||||||
# $1 - port
|
|
||||||
|
|
||||||
local rule port=$(pf_anchor_port_target)
|
|
||||||
for lan in $IFACE_LAN; do
|
|
||||||
for t in $tbl; do
|
|
||||||
echo "rdr on $lan inet proto tcp from any to $t port $port -> 127.0.0.1 port $1"
|
|
||||||
done
|
|
||||||
done
|
|
||||||
echo "rdr on lo0 inet proto tcp from !127.0.0.0/8 to any port $port -> 127.0.0.1 port $1"
|
|
||||||
for t in $tbl; do
|
|
||||||
rule="route-to (lo0 127.0.0.1) inet proto tcp from !127.0.0.0/8 to $t port $port user { >root }"
|
|
||||||
if [ -n "$IFACE_WAN" ] ; then
|
|
||||||
for wan in $IFACE_WAN; do
|
|
||||||
echo "pass out on $wan $rule"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "pass out $rule"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
pf_anchor_zapret_v4()
|
|
||||||
{
|
|
||||||
local tbl port
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
|
||||||
case $MODE in
|
|
||||||
tpws)
|
|
||||||
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
|
||||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
|
||||||
pf_anchor_zapret_v4_tpws $TPPORT
|
|
||||||
;;
|
|
||||||
custom)
|
|
||||||
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
|
|
||||||
existf zapret_custom_firewall_v4 && zapret_custom_firewall_v4
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pf_anchor_zapret_v6_tpws()
|
|
||||||
{
|
|
||||||
# $1 - port
|
|
||||||
|
|
||||||
local LL_LAN rule port=$(pf_anchor_port_target)
|
|
||||||
# LAN link local is only for router
|
|
||||||
for lan in $IFACE_LAN; do
|
|
||||||
LL_LAN=$(get_ipv6_linklocal $lan)
|
|
||||||
[ -n "$LL_LAN" ] && {
|
|
||||||
for t in $tbl; do
|
|
||||||
echo "rdr on $lan inet6 proto tcp from any to $t port $port -> $LL_LAN port $1"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
done
|
|
||||||
echo "rdr on lo0 inet6 proto tcp from !::1 to any port $port -> fe80::1 port $1"
|
|
||||||
for t in $tbl; do
|
|
||||||
rule="route-to (lo0 fe80::1) inet6 proto tcp from !::1 to $t port $port user { >root }"
|
|
||||||
if [ -n "$IFACE_WAN" ] ; then
|
|
||||||
for wan in $IFACE_WAN; do
|
|
||||||
echo "pass out on $wan $rule"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "pass out $rule"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
pf_anchor_zapret_v6()
|
|
||||||
{
|
|
||||||
local tbl port
|
|
||||||
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
|
||||||
case $MODE in
|
|
||||||
tpws)
|
|
||||||
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
|
|
||||||
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
|
||||||
pf_anchor_zapret_v6_tpws $TPPORT
|
|
||||||
;;
|
|
||||||
custom)
|
|
||||||
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
|
|
||||||
existf zapret_custom_firewall_v6 && zapret_custom_firewall_v6
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pf_anchors_create()
|
|
||||||
{
|
|
||||||
wait_lan_ll
|
|
||||||
pf_anchor_zapret >"$PF_ANCHOR_ZAPRET"
|
|
||||||
pf_anchor_zapret_v4 >"$PF_ANCHOR_ZAPRET_V4"
|
|
||||||
pf_anchor_zapret_v6 >"$PF_ANCHOR_ZAPRET_V6"
|
|
||||||
}
|
|
||||||
pf_anchors_del()
|
|
||||||
{
|
|
||||||
rm -f "$PF_ANCHOR_ZAPRET" "$PF_ANCHOR_ZAPRET_V4" "$PF_ANCHOR_ZAPRET_V6"
|
|
||||||
}
|
|
||||||
pf_anchors_load()
|
|
||||||
{
|
|
||||||
echo loading zapret anchor from "$PF_ANCHOR_ZAPRET"
|
|
||||||
pfctl -qa zapret -f "$PF_ANCHOR_ZAPRET" || {
|
|
||||||
echo error loading zapret anchor
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
if [ "$DISABLE_IPV4" = "1" ]; then
|
|
||||||
echo clearing zapret-v4 anchor
|
|
||||||
pfctl -qa zapret-v4 -F all 2>/dev/null
|
|
||||||
else
|
|
||||||
echo loading zapret-v4 anchor from "$PF_ANCHOR_ZAPRET_V4"
|
|
||||||
pfctl -qa zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4" || {
|
|
||||||
echo error loading zapret-v4 anchor
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
if [ "$DISABLE_IPV6" = "1" ]; then
|
|
||||||
echo clearing zapret-v6 anchor
|
|
||||||
pfctl -qa zapret-v6 -F all 2>/dev/null
|
|
||||||
else
|
|
||||||
echo loading zapret-v6 anchor from "$PF_ANCHOR_ZAPRET_V6"
|
|
||||||
pfctl -qa zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6" || {
|
|
||||||
echo error loading zapret-v6 anchor
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
echo successfully loaded PF anchors
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
pf_anchors_clear()
|
|
||||||
{
|
|
||||||
echo clearing zapret anchors
|
|
||||||
pfctl -qa zapret-v4 -F all 2>/dev/null
|
|
||||||
pfctl -qa zapret-v6 -F all 2>/dev/null
|
|
||||||
pfctl -qa zapret -F all 2>/dev/null
|
|
||||||
}
|
|
||||||
pf_enable()
|
|
||||||
{
|
|
||||||
echo enabling PF
|
|
||||||
pfctl -qe
|
|
||||||
}
|
|
||||||
pf_table_reload()
|
|
||||||
{
|
|
||||||
echo reloading zapret tables
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || pfctl -qTl -a zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4"
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || pfctl -qTl -a zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6"
|
|
||||||
pfctl -qTl -a zapret -f "$PF_ANCHOR_ZAPRET"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
zapret_do_firewall()
|
zapret_do_firewall()
|
||||||
{
|
{
|
||||||
# $1 - 1 - add, 0 - del
|
# $1 - 1 - add, 0 - del
|
||||||
|
@ -20,26 +20,26 @@ case "$1" in
|
|||||||
"$0" start
|
"$0" start
|
||||||
;;
|
;;
|
||||||
|
|
||||||
start-fw)
|
start-fw|start_fw)
|
||||||
zapret_apply_firewall
|
zapret_apply_firewall
|
||||||
;;
|
;;
|
||||||
stop-fw)
|
stop-fw|stop_fw)
|
||||||
zapret_unapply_firewall
|
zapret_unapply_firewall
|
||||||
;;
|
;;
|
||||||
restart-fw)
|
restart-fw|stop_fw)
|
||||||
zapret_restart_firewall
|
zapret_restart_firewall
|
||||||
;;
|
;;
|
||||||
reload-fw-tables)
|
reload-fw-tables|reload_fw_tables)
|
||||||
pf_table_reload
|
pf_table_reload
|
||||||
;;
|
;;
|
||||||
|
|
||||||
start-daemons)
|
start-daemons|start_daemons)
|
||||||
zapret_run_daemons
|
zapret_run_daemons
|
||||||
;;
|
;;
|
||||||
stop-daemons)
|
stop-daemons|stop_daemons)
|
||||||
zapret_stop_daemons
|
zapret_stop_daemons
|
||||||
;;
|
;;
|
||||||
restart-daemons)
|
restart-daemons|restart_daemons)
|
||||||
zapret_restart_daemons
|
zapret_restart_daemons
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
69
init.d/openrc/zapret
Normal file
69
init.d/openrc/zapret
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
# zapret openrc to sysv adapter
|
||||||
|
# on some systems (alpine) for unknown reason non-openrc-run scripts are not started from /etc/init.d
|
||||||
|
|
||||||
|
EXEDIR=$(dirname "$RC_SERVICE")
|
||||||
|
EXEDIR="$(cd "$EXEDIR"; pwd)"
|
||||||
|
ZAPRET_BASE="$EXEDIR/../.."
|
||||||
|
ZAPRET_INIT="$ZAPRET_BASE/init.d/sysv/zapret"
|
||||||
|
|
||||||
|
extra_commands="start_fw stop_fw restart_fw start_daemons stop_daemons restart_daemons reload_ifsets list_ifsets list_table"
|
||||||
|
description="extra commands :"
|
||||||
|
description_stop_fw="Stop zapret firewall"
|
||||||
|
description_start_fw="Start zapret firewall"
|
||||||
|
description_restart_fw="Restart zapret firewall"
|
||||||
|
description_reload_ifsets="Reload interface lists (nftables only)"
|
||||||
|
description_list_ifsets="Display interface lists (nftables only)"
|
||||||
|
description_list_table="Display zapret nftable (nftables only)"
|
||||||
|
description_stop_daemons="Stop zapret daemons only"
|
||||||
|
description_start_daemons="Start zapret daemons only"
|
||||||
|
description_restart_daemons="Restart zapret firewall only"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
rc-service -e networking && need networking
|
||||||
|
}
|
||||||
|
start()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" start
|
||||||
|
}
|
||||||
|
stop()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" stop
|
||||||
|
}
|
||||||
|
start_fw()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" start_fw
|
||||||
|
}
|
||||||
|
stop_fw()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" stop_fw
|
||||||
|
}
|
||||||
|
restart_fw()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" restart_fw
|
||||||
|
}
|
||||||
|
start_daemons()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" start_daemons
|
||||||
|
}
|
||||||
|
stop_daemons()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" stop_daemons
|
||||||
|
}
|
||||||
|
restart_daemons()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" restart_daemons
|
||||||
|
}
|
||||||
|
reload_ifsets()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" reload_ifsets
|
||||||
|
}
|
||||||
|
list_ifsets()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" list_ifsets
|
||||||
|
}
|
||||||
|
list_table()
|
||||||
|
{
|
||||||
|
"$ZAPRET_INIT" list_table
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
ZAPRET=/etc/init.d/zapret
|
ZAPRET=/etc/init.d/zapret
|
||||||
|
|
||||||
[ "$ACTION" = "ifup" ] && [ -x "$ZAPRET" ] && "$ZAPRET" enabled && {
|
[ -n "$INTERFACE" -a -n "$ACTION" -a -x "$ZAPRET" ] && "$ZAPRET" enabled && {
|
||||||
SCRIPT=$(readlink "$ZAPRET")
|
SCRIPT=$(readlink "$ZAPRET")
|
||||||
if [ -n "$SCRIPT" ]; then
|
if [ -n "$SCRIPT" ]; then
|
||||||
EXEDIR=$(dirname "$SCRIPT")
|
EXEDIR=$(dirname "$SCRIPT")
|
||||||
@ -11,11 +11,29 @@ ZAPRET=/etc/init.d/zapret
|
|||||||
ZAPRET_BASE=/opt/zapret
|
ZAPRET_BASE=/opt/zapret
|
||||||
fi
|
fi
|
||||||
. "$ZAPRET_BASE/config"
|
. "$ZAPRET_BASE/config"
|
||||||
[ -n "$OPENWRT_LAN" ] || OPENWRT_LAN=lan
|
[ "$ACTION" = "ifup" ] && {
|
||||||
for lan in $OPENWRT_LAN; do
|
[ -n "$OPENWRT_LAN" ] || OPENWRT_LAN=lan
|
||||||
[ "$INTERFACE" = "$lan" ] && {
|
for lan in $OPENWRT_LAN; do
|
||||||
"$ZAPRET" restart
|
[ "$INTERFACE" = "$lan" ] && {
|
||||||
break
|
logger -t zapret restarting daemons due to $ACTION of $INTERFACE
|
||||||
}
|
"$ZAPRET" restart_daemons
|
||||||
done
|
break
|
||||||
|
}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
|
linux_fwtype
|
||||||
|
case "$FWTYPE" in
|
||||||
|
nftables)
|
||||||
|
logger -t zapret reloading nftables ifsets due to $ACTION of $INTERFACE
|
||||||
|
"$ZAPRET" reload_ifsets
|
||||||
|
;;
|
||||||
|
iptables)
|
||||||
|
openwrt_fw3 || {
|
||||||
|
logger -t zapret reloading iptables due to $ACTION of $INTERFACE
|
||||||
|
"$ZAPRET" restart_fw
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
zapret_custom_daemons()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
|
# stop logic is managed by procd
|
||||||
|
|
||||||
# PLACEHOLDER
|
# PLACEHOLDER
|
||||||
echo !!! NEED ATTENTION !!!
|
echo !!! NEED ATTENTION !!!
|
||||||
echo Start daemon\(s\)
|
echo Start daemon\(s\)
|
||||||
@ -13,8 +15,19 @@ zapret_custom_daemons()
|
|||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
||||||
{
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
# PLACEHOLDER
|
# PLACEHOLDER
|
||||||
echo !!! NEED ATTENTION !!!
|
echo !!! NEED ATTENTION !!!
|
||||||
echo Configure iptables for required actions
|
echo Configure iptables for required actions
|
||||||
echo Study how other sections work
|
echo Study how other sections work
|
||||||
}
|
}
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Configure nftables for required actions
|
||||||
|
echo Study how other sections work
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
zapret_custom_daemons()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
|
# stop logic is managed by procd
|
||||||
|
|
||||||
local opt
|
local opt
|
||||||
|
|
||||||
[ "$MODE_HTTP" = "1" ] && {
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
@ -19,6 +21,8 @@ zapret_custom_daemons()
|
|||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
||||||
{
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local f4 f6
|
local f4 f6
|
||||||
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:4"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
@ -27,13 +31,35 @@ zapret_custom_firewall()
|
|||||||
f4="--dport 80"
|
f4="--dport 80"
|
||||||
f6=$f4
|
f6=$f4
|
||||||
filter_apply_ipset_target f4 f6
|
filter_apply_ipset_target f4 f6
|
||||||
fw_tpws "$f4" "$f6" $TPPORT
|
fw_tpws $1 "$f4" "$f6" $TPPORT
|
||||||
}
|
}
|
||||||
|
|
||||||
[ "$MODE_HTTPS" = "1" ] && {
|
[ "$MODE_HTTPS" = "1" ] && {
|
||||||
f4="--dport 443 $first_packet_only"
|
f4="--dport 443 $first_packet_only"
|
||||||
f6=$f4
|
f6=$f4
|
||||||
filter_apply_ipset_target f4 f6
|
filter_apply_ipset_target f4 f6
|
||||||
fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
local f4 f6
|
||||||
|
local first_packet_only="ct original packets 1-4"
|
||||||
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
|
f4="tcp dport 80"
|
||||||
|
f6=$f4
|
||||||
|
nft_filter_apply_ipset_target f4 f6
|
||||||
|
nft_fw_tpws "$f4" "$f6" $TPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$MODE_HTTPS" = "1" ] && {
|
||||||
|
f4="tcp dport 443 $first_packet_only"
|
||||||
|
f6=$f4
|
||||||
|
nft_filter_apply_ipset_target f4 f6
|
||||||
|
nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
init.d/openwrt/custom.default
Normal file
20
init.d/openwrt/custom.default
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# this script contain your special code to launch daemons and configure firewall
|
||||||
|
# use helpers from "functions" file and "zapret" init script
|
||||||
|
# in case of upgrade keep this file only, do not modify others
|
||||||
|
|
||||||
|
zapret_custom_daemons()
|
||||||
|
{
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Start daemon\(s\)
|
||||||
|
echo Study how other sections work
|
||||||
|
|
||||||
|
run_daemon 1 /bin/sleep 20
|
||||||
|
}
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Configure iptables for required actions
|
||||||
|
echo Study how other sections work
|
||||||
|
}
|
@ -2,14 +2,22 @@
|
|||||||
|
|
||||||
[ -n "$ZAPRET_BASE" ] || ZAPRET_BASE=/opt/zapret
|
[ -n "$ZAPRET_BASE" ] || ZAPRET_BASE=/opt/zapret
|
||||||
. "$ZAPRET_BASE/config"
|
. "$ZAPRET_BASE/config"
|
||||||
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
|
. "$ZAPRET_BASE/common/queue.sh"
|
||||||
|
. "$ZAPRET_BASE/common/linux_iphelper.sh"
|
||||||
|
. "$ZAPRET_BASE/common/ipt.sh"
|
||||||
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
|
. "$ZAPRET_BASE/common/linux_fw.sh"
|
||||||
|
|
||||||
[ -n "$QNUM" ] || QNUM=200
|
[ -n "$QNUM" ] || QNUM=200
|
||||||
[ -n "$TPPORT" ] || TPPORT=988
|
[ -n "$TPPORT" ] || TPPORT=988
|
||||||
[ -n "$WS_USER" ] || WS_USER=daemon
|
[ -n "$WS_USER" ] || WS_USER=daemon
|
||||||
TPWS_LOCALHOST4=127.0.0.127
|
|
||||||
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
|
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
|
||||||
[ -n "$OPENWRT_LAN" ] || OPENWRT_LAN=lan
|
[ -n "$OPENWRT_LAN" ] || OPENWRT_LAN=lan
|
||||||
|
|
||||||
|
TPWS_LOCALHOST4=127.0.0.127
|
||||||
|
|
||||||
# max wait time for the link local ipv6 on the LAN interface
|
# max wait time for the link local ipv6 on the LAN interface
|
||||||
LINKLOCAL_WAIT_SEC=5
|
LINKLOCAL_WAIT_SEC=5
|
||||||
|
|
||||||
@ -26,14 +34,6 @@ 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_HTTP6="${NFQWS_OPT_DESYNC_HTTP6:-$NFQWS_OPT_DESYNC_HTTP}"
|
||||||
NFQWS_OPT_DESYNC_HTTPS6="${NFQWS_OPT_DESYNC_HTTPS6:-$NFQWS_OPT_DESYNC_HTTPS}"
|
NFQWS_OPT_DESYNC_HTTPS6="${NFQWS_OPT_DESYNC_HTTPS6:-$NFQWS_OPT_DESYNC_HTTPS}"
|
||||||
|
|
||||||
exists()
|
|
||||||
{
|
|
||||||
which "$1" >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
existf()
|
|
||||||
{
|
|
||||||
type "$1" >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# can be multiple ipv6 outgoing interfaces
|
# can be multiple ipv6 outgoing interfaces
|
||||||
@ -46,341 +46,268 @@ existf()
|
|||||||
|
|
||||||
network_find_wan_all()
|
network_find_wan_all()
|
||||||
{
|
{
|
||||||
__network_ifstatus "$1" "" "[@.route[@.target='0.0.0.0' && !@.table]].interface" "" 10 2>/dev/null && return
|
__network_ifstatus "$1" "" "[@.route[@.target='0.0.0.0' && !@.table]].interface" "" 10 2>/dev/null && return
|
||||||
network_find_wan $1
|
network_find_wan $1
|
||||||
}
|
}
|
||||||
network_find_wan6_all()
|
network_find_wan6_all()
|
||||||
{
|
{
|
||||||
__network_ifstatus "$1" "" "[@.route[@.target='::' && !@.table]].interface" "" 10 2>/dev/null && return
|
__network_ifstatus "$1" "" "[@.route[@.target='::' && !@.table]].interface" "" 10 2>/dev/null && return
|
||||||
network_find_wan6 $1
|
network_find_wan6 $1
|
||||||
}
|
}
|
||||||
|
|
||||||
ipt()
|
route_localnet()
|
||||||
{
|
{
|
||||||
iptables -C "$@" >/dev/null 2>/dev/null || iptables -I "$@"
|
for lan in $OPENWRT_LAN; do
|
||||||
}
|
network_get_device DEVICE $lan
|
||||||
ipt_del()
|
[ -n "$DEVICE" ] || continue
|
||||||
{
|
sysctl -qw net.ipv4.conf.$DEVICE.route_localnet=1
|
||||||
iptables -C "$@" >/dev/null 2>/dev/null && iptables -D "$@"
|
done
|
||||||
}
|
|
||||||
ipt6()
|
|
||||||
{
|
|
||||||
ip6tables -C "$@" >/dev/null 2>/dev/null || ip6tables -I "$@"
|
|
||||||
}
|
|
||||||
ipt6_del()
|
|
||||||
{
|
|
||||||
ip6tables -C "$@" >/dev/null 2>/dev/null && ip6tables -D "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# there's no route_localnet for ipv6
|
|
||||||
# the best we can is to route to link local of the incoming interface
|
|
||||||
# OUTPUT - can DNAT to ::1
|
|
||||||
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
|
|
||||||
# not a good idea to expose tpws to the world (bind to ::)
|
|
||||||
|
|
||||||
get_ipv6_linklocal()
|
|
||||||
{
|
|
||||||
# $1 - interface name. if empty - any interface
|
|
||||||
if exists ip ; then
|
|
||||||
local dev
|
|
||||||
[ -n "$1" ] && dev="dev $1"
|
|
||||||
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope link.*$/\1/;t;d' | head -n 1
|
|
||||||
else
|
|
||||||
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Link.*$/\1/;t;d' | head -n 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
get_ipv6_global()
|
|
||||||
{
|
|
||||||
# $1 - interface name. if empty - any interface
|
|
||||||
if exists ip ; then
|
|
||||||
local dev
|
|
||||||
[ -n "$1" ] && dev="dev $1"
|
|
||||||
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1
|
|
||||||
else
|
|
||||||
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Global.*$/\1/;t;d' | head -n 1
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dnat6_target()
|
dnat6_target()
|
||||||
{
|
{
|
||||||
# $1 - lan network name
|
# $1 - lan network name
|
||||||
# $2 - var to store target ip6
|
# $2 - var to store target ip6
|
||||||
# get target ip address for DNAT. prefer link locals
|
# get target ip address for DNAT. prefer link locals
|
||||||
# tpws should be as inaccessible from outside as possible
|
# tpws should be as inaccessible from outside as possible
|
||||||
# link local address can appear not immediately after ifup
|
# link local address can appear not immediately after ifup
|
||||||
# DNAT6_TARGET=- means attempt was made but address was not found (to avoid multiple re-attempts)
|
# DNAT6_TARGET=- means attempt was made but address was not found (to avoid multiple re-attempts)
|
||||||
|
|
||||||
local DNAT6_TARGET DVAR=DNAT6_TARGET_$1
|
local DNAT6_TARGET DVAR=DNAT6_TARGET_$1
|
||||||
DVAR=$(echo $DVAR | sed 's/[^a-zA-Z0-9_]/_/g')
|
DVAR=$(echo $DVAR | sed 's/[^a-zA-Z0-9_]/_/g')
|
||||||
eval DNAT6_TARGET="\$$DVAR"
|
eval DNAT6_TARGET="\$$DVAR"
|
||||||
[ -n "$2" ] && eval $2=''
|
[ -n "$2" ] && eval $2=''
|
||||||
|
|
||||||
[ -n "$DNAT6_TARGET" ] || {
|
[ -n "$DNAT6_TARGET" ] || {
|
||||||
# no reason to query if its down
|
# no reason to query if its down
|
||||||
network_is_up $1 || return
|
network_is_up $1 || return
|
||||||
|
|
||||||
local DEVICE
|
local DEVICE
|
||||||
network_get_device DEVICE $1
|
network_get_device DEVICE $1
|
||||||
|
|
||||||
local ct=0
|
local ct=0
|
||||||
while
|
while
|
||||||
DNAT6_TARGET=$(get_ipv6_linklocal $DEVICE)
|
DNAT6_TARGET=$(get_ipv6_linklocal $DEVICE)
|
||||||
[ -n "$DNAT6_TARGET" ] && break
|
[ -n "$DNAT6_TARGET" ] && break
|
||||||
[ "$ct" -ge "$LINKLOCAL_WAIT_SEC" ] && break
|
[ "$ct" -ge "$LINKLOCAL_WAIT_SEC" ] && break
|
||||||
echo $DEVICE: waiting for the link local for another $(($LINKLOCAL_WAIT_SEC - $ct)) seconds ...
|
echo $DEVICE: waiting for the link local for another $(($LINKLOCAL_WAIT_SEC - $ct)) seconds ...
|
||||||
ct=$(($ct+1))
|
ct=$(($ct+1))
|
||||||
sleep 1
|
sleep 1
|
||||||
do :; done
|
do :; done
|
||||||
|
|
||||||
[ -n "$DNAT6_TARGET" ] || {
|
[ -n "$DNAT6_TARGET" ] || {
|
||||||
echo $DEVICE: no link local. getting global
|
echo $DEVICE: no link local. getting global
|
||||||
DNAT6_TARGET=$(get_ipv6_global $DEVICE)
|
DNAT6_TARGET=$(get_ipv6_global $DEVICE)
|
||||||
[ -n "$DNAT6_TARGET" ] || {
|
[ -n "$DNAT6_TARGET" ] || {
|
||||||
echo $DEVICE: could not get any address
|
echo $DEVICE: could not get any address
|
||||||
DNAT6_TARGET=-
|
DNAT6_TARGET=-
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eval $DVAR="$DNAT6_TARGET"
|
eval $DVAR="$DNAT6_TARGET"
|
||||||
}
|
}
|
||||||
[ -n "$2" ] && eval $2="$DNAT6_TARGET"
|
[ -n "$2" ] && eval $2="$DNAT6_TARGET"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
set_route_localnet()
|
||||||
|
{
|
||||||
|
# $1 - 1 = enable, 0 = disable
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
local lan DEVICE
|
||||||
|
for lan in $OPENWRT_LAN; do
|
||||||
|
network_get_device DEVICE $lan
|
||||||
|
[ -n "$DEVICE" ] || continue
|
||||||
|
sysctl -q -w net.ipv4.conf.$DEVICE.route_localnet=$1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepare_route_localnet()
|
||||||
|
{
|
||||||
|
set_route_localnet 1
|
||||||
|
}
|
||||||
|
unprepare_route_localnet()
|
||||||
|
{
|
||||||
|
set_route_localnet 0
|
||||||
|
}
|
||||||
|
prepare_tpws_fw4()
|
||||||
|
{
|
||||||
|
# otherwise linux kernel will treat 127.0.0.0/8 as "martian" ip and refuse routing to it
|
||||||
|
# NOTE : kernels <3.6 do not have this feature. consider upgrading or change DNAT to REDIRECT and do not bind to 127.0.0.0/8
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
iptables -N input_rule_zapret 2>/dev/null
|
||||||
|
ipt input_rule_zapret -d $TPWS_LOCALHOST4 -j RETURN
|
||||||
|
ipta input_rule_zapret -d 127.0.0.0/8 -j DROP
|
||||||
|
ipt INPUT ! -i lo -j input_rule_zapret
|
||||||
|
|
||||||
|
prepare_route_localnet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unprepare_tpws_fw4()
|
||||||
|
{
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
unprepare_route_localnet
|
||||||
|
|
||||||
|
ipt_del INPUT ! -i lo -j input_rule_zapret
|
||||||
|
iptables -F input_rule_zapret 2>/dev/null
|
||||||
|
iptables -X input_rule_zapret 2>/dev/null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unprepare_tpws_fw()
|
||||||
|
{
|
||||||
|
unprepare_tpws_fw4
|
||||||
|
}
|
||||||
|
|
||||||
fw_nfqws_pre4()
|
fw_nfqws_pre4()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv4
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - queue number
|
# $2 - filter ipv4
|
||||||
|
# $3 - queue number
|
||||||
|
|
||||||
local DEVICE wan_iface
|
local DEVICE wan_iface
|
||||||
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
network_find_wan_all wan_iface
|
network_find_wan_all wan_iface
|
||||||
for ext_iface in $wan_iface; do
|
for ext_iface in $wan_iface; do
|
||||||
network_get_device DEVICE $ext_iface
|
network_get_device DEVICE $ext_iface
|
||||||
ipt PREROUTING -t mangle -i $DEVICE -p tcp $1 $IPSET_EXCLUDE src -j NFQUEUE --queue-num $2 --queue-bypass
|
ipt_add_del $1 PREROUTING -t mangle -i $DEVICE -p tcp $2 $IPSET_EXCLUDE src -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fw_nfqws_pre6()
|
fw_nfqws_pre6()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv6
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - queue number
|
# $2 - filter ipv6
|
||||||
|
# $3 - queue number
|
||||||
|
|
||||||
local DEVICE wan_iface
|
local DEVICE wan_iface
|
||||||
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
network_find_wan6_all wan_iface
|
network_find_wan6_all wan_iface
|
||||||
for ext_iface in $wan_iface; do
|
for ext_iface in $wan_iface; do
|
||||||
network_get_device DEVICE $ext_iface
|
network_get_device DEVICE $ext_iface
|
||||||
ipt6 PREROUTING -t mangle -i $DEVICE -p tcp $1 $IPSET_EXCLUDE6 src -j NFQUEUE --queue-num $2 --queue-bypass
|
ipt6_add_del $1 PREROUTING -t mangle -i $DEVICE -p tcp $2 $IPSET_EXCLUDE6 src -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fw_nfqws_pre()
|
fw_nfqws_pre()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv4
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - filter ipv6
|
# $2 - filter ipv4
|
||||||
# $3 - queue number
|
# $3 - filter ipv6
|
||||||
|
# $4 - queue number
|
||||||
|
|
||||||
fw_nfqws_pre4 "$1" $3
|
fw_nfqws_pre4 $1 "$2" $4
|
||||||
fw_nfqws_pre6 "$2" $3
|
fw_nfqws_pre6 $1 "$3" $4
|
||||||
}
|
}
|
||||||
fw_nfqws_post4()
|
fw_nfqws_post4()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv4
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - queue number
|
# $2 - filter ipv4
|
||||||
|
# $3 - queue number
|
||||||
|
|
||||||
local DEVICE wan_iface
|
local DEVICE wan_iface
|
||||||
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
network_find_wan_all wan_iface
|
network_find_wan_all wan_iface
|
||||||
for ext_iface in $wan_iface; do
|
for ext_iface in $wan_iface; do
|
||||||
network_get_device DEVICE $ext_iface
|
network_get_device DEVICE $ext_iface
|
||||||
ipt POSTROUTING -t mangle -o $DEVICE -p tcp $1 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $2 --queue-bypass
|
ipt_add_del $1 POSTROUTING -t mangle -o $DEVICE -p tcp $2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fw_nfqws_post6()
|
fw_nfqws_post6()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv6
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - queue number
|
# $2 - filter ipv6
|
||||||
|
# $3 - queue number
|
||||||
|
|
||||||
local DEVICE wan_iface
|
local DEVICE wan_iface
|
||||||
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
network_find_wan6_all wan_iface
|
network_find_wan6_all wan_iface
|
||||||
for ext_iface in $wan_iface; do
|
for ext_iface in $wan_iface; do
|
||||||
network_get_device DEVICE $ext_iface
|
network_get_device DEVICE $ext_iface
|
||||||
ipt6 POSTROUTING -t mangle -o $DEVICE -p tcp $1 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $2 --queue-bypass
|
ipt6_add_del $1 POSTROUTING -t mangle -o $DEVICE -p tcp $2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fw_nfqws_post()
|
fw_nfqws_post()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv4
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - filter ipv6
|
# $2 - filter ipv4
|
||||||
# $3 - queue number
|
# $3 - filter ipv6
|
||||||
|
# $4 - queue number
|
||||||
|
|
||||||
fw_nfqws_post4 "$1" $3
|
fw_nfqws_post4 $1 "$2" $4
|
||||||
fw_nfqws_post6 "$2" $3
|
fw_nfqws_post6 $1 "$3" $4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IPT_OWNER="-m owner ! --uid-owner $WS_USER"
|
IPT_OWNER="-m owner ! --uid-owner $WS_USER"
|
||||||
fw_tpws4()
|
fw_tpws4()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv6
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - tpws port
|
# $2 - filter ipv4
|
||||||
|
# $3 - tpws port
|
||||||
|
|
||||||
local DEVICE wan_iface
|
local lan DEVICE ext_iface wan_iface
|
||||||
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
network_find_wan_all wan_iface
|
network_find_wan_all wan_iface
|
||||||
for ext_iface in $wan_iface; do
|
for ext_iface in $wan_iface; do
|
||||||
network_get_device DEVICE $ext_iface
|
network_get_device DEVICE $ext_iface
|
||||||
ipt OUTPUT -t nat -o $DEVICE $IPT_OWNER -p tcp $1 $IPSET_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$2
|
ipt_add_del $1 OUTPUT -t nat -o $DEVICE $IPT_OWNER -p tcp $2 $IPSET_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3
|
||||||
done
|
done
|
||||||
|
[ "$1" = 1 ] && prepare_tpws_fw4
|
||||||
# allow localnet route only to special tpws IP
|
for lan in $OPENWRT_LAN; do
|
||||||
iptables -N input_rule_zapret 2>/dev/null
|
network_get_device DEVICE $lan
|
||||||
ipt input_rule_zapret -d 127.0.0.0/8 -j DROP
|
[ -n "$DEVICE" ] || continue
|
||||||
ipt input_rule_zapret -d $TPWS_LOCALHOST4 -j RETURN
|
ipt_add_del $1 PREROUTING -t nat -i $DEVICE -p tcp $2 $IPSET_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3
|
||||||
|
done
|
||||||
for lan in $OPENWRT_LAN; do
|
}
|
||||||
network_get_device DEVICE $lan
|
|
||||||
[ -n "$DEVICE" ] || continue
|
|
||||||
ipt prerouting_rule -t nat -i $DEVICE -p tcp $1 $IPSET_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$2
|
|
||||||
ipt input_rule -i $DEVICE -j input_rule_zapret
|
|
||||||
sysctl -qw net.ipv4.conf.$DEVICE.route_localnet=1
|
|
||||||
done
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fw_tpws6()
|
fw_tpws6()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv6
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - tpws port
|
# $2 - filter ipv6
|
||||||
|
# $3 - tpws port
|
||||||
|
|
||||||
local DEVICE wan_iface DNAT6
|
local lan DEVICE ext_iface wan_iface DNAT6
|
||||||
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
network_find_wan6_all wan_iface
|
network_find_wan6_all wan_iface
|
||||||
for ext_iface in $wan_iface; do
|
for ext_iface in $wan_iface; do
|
||||||
network_get_device DEVICE $ext_iface
|
network_get_device DEVICE $ext_iface
|
||||||
ipt6 OUTPUT -t nat -o $DEVICE $IPT_OWNER -p tcp $1 $IPSET_EXCLUDE6 dst -j DNAT --to [::1]:$2
|
ipt6_add_del $1 OUTPUT -t nat -o $DEVICE $IPT_OWNER -p tcp $2 $IPSET_EXCLUDE6 dst -j DNAT --to [::1]:$3
|
||||||
done
|
done
|
||||||
for lan in $OPENWRT_LAN; do
|
for lan in $OPENWRT_LAN; do
|
||||||
network_get_device DEVICE $lan
|
network_get_device DEVICE $lan
|
||||||
[ -n "$DEVICE" ] || continue
|
[ -n "$DEVICE" ] || continue
|
||||||
dnat6_target $lan DNAT6
|
dnat6_target $lan DNAT6
|
||||||
[ "$DNAT6" != '-' ] && ipt6 PREROUTING -t nat -i $DEVICE -p tcp $1 $IPSET_EXCLUDE6 dst -j DNAT --to [$DNAT6]:$2
|
[ "$DNAT6" != '-' ] && ipt6_add_del $1 PREROUTING -t nat -i $DEVICE -p tcp $2 $IPSET_EXCLUDE6 dst -j DNAT --to [$DNAT6]:$3
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fw_tpws()
|
fw_tpws()
|
||||||
{
|
{
|
||||||
# $1 - filter ipv4
|
# $1 - 1 - add, 0 - del
|
||||||
# $2 - filter ipv6
|
# $2 - filter ipv4
|
||||||
# $3 - tpws port
|
# $3 - filter ipv6
|
||||||
|
# $4 - tpws port
|
||||||
|
|
||||||
fw_tpws4 "$1" $3
|
fw_tpws4 $1 "$2" $4
|
||||||
fw_tpws6 "$2" $3
|
fw_tpws6 $1 "$3" $4
|
||||||
}
|
}
|
||||||
|
|
||||||
filter_apply_port_target()
|
|
||||||
{
|
|
||||||
# $1 - var name of iptables filter
|
|
||||||
local f
|
|
||||||
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
|
||||||
f="-m multiport --dports 80,443"
|
|
||||||
elif [ "$MODE_HTTPS" = "1" ]; then
|
|
||||||
f="--dport 443"
|
|
||||||
elif [ "$MODE_HTTP" = "1" ]; then
|
|
||||||
f="--dport 80"
|
|
||||||
else
|
|
||||||
echo WARNING !!! HTTP and HTTPS are both disabled
|
|
||||||
fi
|
|
||||||
eval $1="\"\$$1 $f\""
|
|
||||||
}
|
|
||||||
filter_apply_ipset_target4()
|
|
||||||
{
|
|
||||||
# $1 - var name of ipv4 iptables filter
|
|
||||||
if [ "$MODE_FILTER" = "ipset" ]; then
|
|
||||||
eval $1="\"\$$1 -m set --match-set zapret dst\""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
filter_apply_ipset_target6()
|
|
||||||
{
|
|
||||||
# $1 - var name of ipv4 iptables filter
|
|
||||||
if [ "$MODE_FILTER" = "ipset" ]; then
|
|
||||||
eval $1="\"\$$1 -m set --match-set zapret6 dst\""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
filter_apply_ipset_target()
|
|
||||||
{
|
|
||||||
# $1 - var name of ipv4 iptables filter
|
|
||||||
# $2 - var name of ipv6 iptables filter
|
|
||||||
filter_apply_ipset_target4 $1
|
|
||||||
filter_apply_ipset_target6 $2
|
|
||||||
}
|
|
||||||
|
|
||||||
get_nfqws_qnums()
|
|
||||||
{
|
|
||||||
# $1 - var name for ipv4 http
|
|
||||||
# $2 - var name for ipv4 https
|
|
||||||
# $3 - var name for ipv6 http
|
|
||||||
# $4 - var name for ipv6 https
|
|
||||||
local _qn _qns _qn6 _qns6
|
|
||||||
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
|
||||||
_qn=$QNUM
|
|
||||||
_qns=$_qn
|
|
||||||
[ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || _qns=$(($QNUM+1))
|
|
||||||
}
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
|
||||||
_qn6=$(($QNUM+2))
|
|
||||||
_qns6=$(($QNUM+3))
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
|
||||||
if [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then
|
|
||||||
_qn6=$_qn;
|
|
||||||
elif [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then
|
|
||||||
_qn6=$_qns;
|
|
||||||
fi
|
|
||||||
if [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then
|
|
||||||
_qns6=$_qn;
|
|
||||||
elif [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then
|
|
||||||
_qns6=$_qns;
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
[ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP6" ] && _qns6=$_qn6;
|
|
||||||
}
|
|
||||||
if [ "$MODE_HTTP" = 1 ]; then
|
|
||||||
eval $1=$_qn
|
|
||||||
eval $3=$_qn6
|
|
||||||
else
|
|
||||||
eval $1=
|
|
||||||
eval $3=
|
|
||||||
fi
|
|
||||||
if [ "$MODE_HTTPS" = 1 ]; then
|
|
||||||
eval $2=$_qns
|
|
||||||
eval $4=$_qns6
|
|
||||||
else
|
|
||||||
eval $2=
|
|
||||||
eval $4=
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
create_ipset()
|
create_ipset()
|
||||||
{
|
{
|
||||||
echo "Creating ipset"
|
echo "Creating ip list table (firewall type $FWTYPE)"
|
||||||
"$IPSET_CR" "$@"
|
"$IPSET_CR" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
is_flow_offload_avail()
|
|
||||||
{
|
|
||||||
# $1 = '' for ipv4, '6' for ipv6
|
|
||||||
grep -q FLOWOFFLOAD /proc/net/ip$1_tables_targets
|
|
||||||
}
|
|
||||||
list_nfqws_rules()
|
list_nfqws_rules()
|
||||||
{
|
{
|
||||||
# $1 = '' for ipv4, '6' for ipv6
|
# $1 = '' for ipv4, '6' for ipv6
|
||||||
@ -390,7 +317,7 @@ list_nfqws_rules()
|
|||||||
}
|
}
|
||||||
reverse_nfqws_rule()
|
reverse_nfqws_rule()
|
||||||
{
|
{
|
||||||
sed -e 's/-o /-i /' -e 's/--dport /--sport /' -e 's/--dports /--sports /' -e 's/ dst$/ src/' -e 's/ dst / src /'
|
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'
|
||||||
}
|
}
|
||||||
apply_flow_offloading_enable_rule()
|
apply_flow_offloading_enable_rule()
|
||||||
{
|
{
|
||||||
@ -411,15 +338,19 @@ apply_flow_offloading_exempt_rule()
|
|||||||
echo applying ipv${v:-4} flow offloading exemption : $i
|
echo applying ipv${v:-4} flow offloading exemption : $i
|
||||||
ip${v}tables -A $i
|
ip${v}tables -A $i
|
||||||
}
|
}
|
||||||
|
flow_offloading_unexempt_v()
|
||||||
|
{
|
||||||
|
ipt$1_del FORWARD -j forwarding_rule_zapret
|
||||||
|
ip$1tables -F forwarding_rule_zapret 2>/dev/null
|
||||||
|
ip$1tables -X forwarding_rule_zapret 2>/dev/null
|
||||||
|
}
|
||||||
flow_offloading_exempt_v()
|
flow_offloading_exempt_v()
|
||||||
{
|
{
|
||||||
# $1 = '' for ipv4, '6' for ipv6
|
# $1 = '' for ipv4, '6' for ipv6
|
||||||
|
|
||||||
is_flow_offload_avail $1 || return 0
|
is_ipt_flow_offload_avail $1 || return 0
|
||||||
|
|
||||||
ipt$1_del forwarding_rule -j forwarding_rule_zapret
|
flow_offloading_unexempt_v $1
|
||||||
ip$1tables -F forwarding_rule_zapret 2>/dev/null
|
|
||||||
ip$1tables -X forwarding_rule_zapret 2>/dev/null
|
|
||||||
|
|
||||||
[ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && {
|
[ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && {
|
||||||
ip$1tables -N forwarding_rule_zapret
|
ip$1tables -N forwarding_rule_zapret
|
||||||
@ -436,7 +367,7 @@ flow_offloading_exempt_v()
|
|||||||
|
|
||||||
apply_flow_offloading_enable_rule $1
|
apply_flow_offloading_enable_rule $1
|
||||||
|
|
||||||
ipt$1 forwarding_rule -j forwarding_rule_zapret
|
ipt$1 FORWARD -j forwarding_rule_zapret
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
@ -446,75 +377,137 @@ flow_offloading_exempt()
|
|||||||
[ "$DISABLE_IPV4" = "1" ] || flow_offloading_exempt_v
|
[ "$DISABLE_IPV4" = "1" ] || flow_offloading_exempt_v
|
||||||
[ "$DISABLE_IPV6" = "1" ] || flow_offloading_exempt_v 6
|
[ "$DISABLE_IPV6" = "1" ] || flow_offloading_exempt_v 6
|
||||||
}
|
}
|
||||||
|
flow_offloading_unexempt()
|
||||||
|
|
||||||
zapret_apply_firewall()
|
|
||||||
{
|
{
|
||||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4"
|
[ "$DISABLE_IPV4" = "1" ] || flow_offloading_unexempt_v
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
[ "$DISABLE_IPV6" = "1" ] || flow_offloading_unexempt_v 6
|
||||||
local f4 f6 qn qns qn6 qns6
|
}
|
||||||
|
|
||||||
# always create ipsets. ip_exclude ipset is required
|
|
||||||
create_ipset no-update
|
|
||||||
|
nft_fill_ifsets()
|
||||||
case "${MODE_OVERRIDE:-$MODE}" in
|
{
|
||||||
tpws)
|
local script elements i wan_iface DEVICE DLAN DWAN DWAN6 ALLDEVS flags
|
||||||
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
|
|
||||||
echo both http and https are disabled. not applying redirection.
|
# if large sets exist nft works very ineffectively
|
||||||
else
|
# looks like it analyzes the whole table blob to find required data pieces
|
||||||
filter_apply_port_target f4
|
# calling all in one shot helps not to waste cpu time many times
|
||||||
f6=$f4
|
|
||||||
filter_apply_ipset_target f4 f6
|
script="flush set inet $ZAPRET_NFT_TABLE wanif
|
||||||
fw_tpws "$f4" "$f6" $TPPORT
|
flush set inet $ZAPRET_NFT_TABLE wanif6
|
||||||
fi
|
flush set inet $ZAPRET_NFT_TABLE lanif"
|
||||||
;;
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
nfqws)
|
network_find_wan_all wan_iface
|
||||||
# quite complex but we need to minimize nfqws processes to save RAM
|
for i in $wan_iface; do
|
||||||
get_nfqws_qnums qn qns qn6 qns6
|
network_get_device DEVICE $i
|
||||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
DWAN="$DWAN $DEVICE"
|
||||||
filter_apply_port_target f4
|
done
|
||||||
f4="$f4 $first_packet_only"
|
[ -n "$DWAN" ] && {
|
||||||
filter_apply_ipset_target4 f4
|
make_comma_list elements $DWAN
|
||||||
fw_nfqws_post4 "$f4 $desync" $qn
|
script="${script}
|
||||||
else
|
add element inet $ZAPRET_NFT_TABLE wanif { $elements }"
|
||||||
if [ -n "$qn" ]; then
|
}
|
||||||
f4="--dport 80"
|
}
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
filter_apply_ipset_target4 f4
|
network_find_wan6_all wan_iface
|
||||||
fw_nfqws_post4 "$f4 $desync" $qn
|
for i in $wan_iface; do
|
||||||
fi
|
network_get_device DEVICE $i
|
||||||
if [ -n "$qns" ]; then
|
DWAN6="$DWAN6 $DEVICE"
|
||||||
f4="--dport 443 $first_packet_only"
|
done
|
||||||
filter_apply_ipset_target4 f4
|
[ -n "$DWAN6" ] && {
|
||||||
fw_nfqws_post4 "$f4 $desync" $qns
|
make_comma_list elements $DWAN6
|
||||||
fi
|
script="${script}
|
||||||
fi
|
add element inet $ZAPRET_NFT_TABLE wanif6 { $elements }"
|
||||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
}
|
||||||
filter_apply_port_target f6
|
}
|
||||||
f6="$f6 $first_packet_only"
|
for i in $OPENWRT_LAN; do
|
||||||
filter_apply_ipset_target6 f6
|
network_get_device DEVICE $i
|
||||||
fw_nfqws_post6 "$f6 $desync" $qn6
|
DLAN="$DLAN $DEVICE"
|
||||||
else
|
done
|
||||||
if [ -n "$qn6" ]; then
|
[ -n "$DLAN" ] && {
|
||||||
f6="--dport 80"
|
make_comma_list elements $DLAN
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
script="${script}
|
||||||
filter_apply_ipset_target6 f6
|
add element inet $ZAPRET_NFT_TABLE lanif { $elements }"
|
||||||
fw_nfqws_post6 "$f6 $desync" $qn6
|
}
|
||||||
fi
|
echo "$script" | nft -f -
|
||||||
if [ -n "$qns6" ]; then
|
|
||||||
f6="--dport 443 $first_packet_only"
|
[ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && {
|
||||||
filter_apply_ipset_target6 f6
|
ALLDEVS=$(for i in $DLAN $DWAN $DWAN6; do echo $i; done | sort -u | xargs)
|
||||||
fw_nfqws_post6 "$f6 $desync" $qns6
|
[ "$FLOWOFFLOAD" = 'hardware' ] && nft_hw_offload_supported $ALLDEVS && flags=offload
|
||||||
fi
|
nft_create_or_update_flowtable "$flags" $ALLDEVS
|
||||||
fi
|
}
|
||||||
;;
|
}
|
||||||
custom)
|
|
||||||
existf zapret_custom_firewall && zapret_custom_firewall
|
nft_fw_tpws4()
|
||||||
;;
|
{
|
||||||
esac
|
# $1 - filter ipv4
|
||||||
|
# $2 - tpws port
|
||||||
flow_offloading_exempt
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
return 0
|
nft_add_rule dnat_output skuid != $WS_USER oifname @wanif meta l4proto tcp $1 ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$2
|
||||||
|
nft_add_rule dnat_pre iifname @lanif meta l4proto tcp $1 ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$2
|
||||||
|
prepare_route_localnet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_tpws6()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv6
|
||||||
|
# $2 - tpws port
|
||||||
|
|
||||||
|
local lan DEVICE DNAT6
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
|
nft_add_rule dnat_output skuid != $WS_USER oifname @wanif6 meta l4proto tcp $1 ip6 daddr != @nozapret6 dnat ip6 to [::1]:$2
|
||||||
|
for lan in $OPENWRT_LAN; do
|
||||||
|
network_get_device DEVICE $lan
|
||||||
|
[ -n "$DEVICE" ] || continue
|
||||||
|
dnat6_target $lan DNAT6
|
||||||
|
[ "$DNAT6" != '-' ] && nft_add_rule dnat_pre iifname $DEVICE meta l4proto tcp $1 ip6 daddr != @nozapret6 dnat ip6 to [$DNAT6]:$2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_tpws()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv4
|
||||||
|
# $2 - filter ipv6
|
||||||
|
# $3 - tpws port
|
||||||
|
|
||||||
|
nft_fw_tpws4 "$1" $3
|
||||||
|
nft_fw_tpws6 "$2" $3
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_fw_nfqws_post4()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv4
|
||||||
|
# $2 - queue number
|
||||||
|
|
||||||
|
local DEVICE wan_iface rule
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
rule="oifname @wanif meta l4proto tcp $1 ip daddr != @nozapret"
|
||||||
|
nft_add_rule postrouting $rule queue num $2 bypass
|
||||||
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_nfqws_post6()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv6
|
||||||
|
# $2 - queue number
|
||||||
|
|
||||||
|
local DEVICE wan_iface rule
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
|
rule="oifname @wanif6 meta l4proto tcp $1 ip6 daddr != @nozapret6"
|
||||||
|
nft_add_rule postrouting $rule queue num $2 bypass
|
||||||
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_nfqws_post()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv4
|
||||||
|
# $2 - filter ipv6
|
||||||
|
# $3 - queue number
|
||||||
|
|
||||||
|
nft_fw_nfqws_post4 "$1" $3
|
||||||
|
nft_fw_nfqws_post6 "$2" $3
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,24 @@ USE_PROCD=1
|
|||||||
# after network
|
# after network
|
||||||
START=21
|
START=21
|
||||||
|
|
||||||
|
my_extra_command() {
|
||||||
|
local cmd="$1"
|
||||||
|
local help="$2"
|
||||||
|
|
||||||
|
local extra="$(printf "%-16s%s" "${cmd}" "${help}")"
|
||||||
|
EXTRA_HELP="${EXTRA_HELP} ${extra}
|
||||||
|
"
|
||||||
|
EXTRA_COMMANDS="${EXTRA_COMMANDS} ${cmd}"
|
||||||
|
}
|
||||||
|
my_extra_command stop_fw "Stop zapret firewall (noop in iptables+fw3 case)"
|
||||||
|
my_extra_command start_fw "Start zapret firewall (noop in iptables+fw3 case)"
|
||||||
|
my_extra_command restart_fw "Restart zapret firewall (noop in iptables+fw3 case)"
|
||||||
|
my_extra_command reload_ifsets "Reload interface lists (nftables only)"
|
||||||
|
my_extra_command list_ifsets "Display interface lists (nftables only)"
|
||||||
|
my_extra_command list_table "Display zapret nftable (nftables only)"
|
||||||
|
my_extra_command stop_daemons "Stop zapret daemons only (=stop in iptables+fw3 case)"
|
||||||
|
my_extra_command start_daemons "Start zapret daemons only (=start in iptables+fw3 case)"
|
||||||
|
my_extra_command restart_daemons "Restart zapret firewall only (=restart in iptables+fw3 case)"
|
||||||
|
|
||||||
SCRIPT=$(readlink /etc/init.d/zapret)
|
SCRIPT=$(readlink /etc/init.d/zapret)
|
||||||
if [ -n "$SCRIPT" ]; then
|
if [ -n "$SCRIPT" ]; then
|
||||||
@ -12,10 +30,12 @@ if [ -n "$SCRIPT" ]; then
|
|||||||
else
|
else
|
||||||
ZAPRET_BASE=/opt/zapret
|
ZAPRET_BASE=/opt/zapret
|
||||||
fi
|
fi
|
||||||
|
|
||||||
. "$ZAPRET_BASE/init.d/openwrt/functions"
|
. "$ZAPRET_BASE/init.d/openwrt/functions"
|
||||||
|
|
||||||
|
|
||||||
# !!!!! in openwrt firewall rules are configured separately
|
# !!!!! in old openwrt 21.x- with iptables firewall rules are configured separately
|
||||||
|
# !!!!! in new openwrt >21.x with nftables firewall is configured here
|
||||||
|
|
||||||
PIDDIR=/var/run
|
PIDDIR=/var/run
|
||||||
|
|
||||||
@ -23,7 +43,6 @@ PIDDIR=/var/run
|
|||||||
NFQWS_OPT_BASE="--user=$WS_USER --dpi-desync-fwmark=$DESYNC_MARK"
|
NFQWS_OPT_BASE="--user=$WS_USER --dpi-desync-fwmark=$DESYNC_MARK"
|
||||||
|
|
||||||
[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
|
[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
|
||||||
TPWS_LOCALHOST4=127.0.0.127
|
|
||||||
HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt.gz"
|
HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt.gz"
|
||||||
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt"
|
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts.txt"
|
||||||
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts-user.txt"
|
[ -f "$HOSTLIST" ] || HOSTLIST="$ZAPRET_BASE/ipset/zapret-hosts-user.txt"
|
||||||
@ -104,7 +123,8 @@ tpws_apply_socks_binds()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
start_service() {
|
start_daemons_procd()
|
||||||
|
{
|
||||||
local opt qn qns qn6 qns6
|
local opt qn qns qn6 qns6
|
||||||
|
|
||||||
case "${MODE_OVERRIDE:-$MODE}" in
|
case "${MODE_OVERRIDE:-$MODE}" in
|
||||||
@ -149,3 +169,61 @@ start_service() {
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
start_daemons()
|
||||||
|
{
|
||||||
|
rc_procd start_daemons_procd "$@"
|
||||||
|
}
|
||||||
|
stop_daemons()
|
||||||
|
{
|
||||||
|
procd_kill "$(basename ${basescript:-$initscript})" "$1"
|
||||||
|
}
|
||||||
|
restart_daemons()
|
||||||
|
{
|
||||||
|
stop_daemons
|
||||||
|
start_daemons
|
||||||
|
}
|
||||||
|
|
||||||
|
start_fw()
|
||||||
|
{
|
||||||
|
zapret_apply_firewall
|
||||||
|
}
|
||||||
|
stop_fw()
|
||||||
|
{
|
||||||
|
zapret_unapply_firewall
|
||||||
|
}
|
||||||
|
restart_fw()
|
||||||
|
{
|
||||||
|
stop_fw
|
||||||
|
start_fw
|
||||||
|
}
|
||||||
|
reload_ifsets()
|
||||||
|
{
|
||||||
|
zapret_reload_ifsets
|
||||||
|
}
|
||||||
|
list_ifsets()
|
||||||
|
{
|
||||||
|
zapret_list_ifsets
|
||||||
|
}
|
||||||
|
list_table()
|
||||||
|
{
|
||||||
|
zapret_list_table
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service()
|
||||||
|
{
|
||||||
|
start_daemons_procd
|
||||||
|
[ "$INIT_APPLY_FW" != "1" ] || {
|
||||||
|
linux_fwtype
|
||||||
|
openwrt_fw3_integration || start_fw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service()
|
||||||
|
{
|
||||||
|
# this procedure is called from stop()
|
||||||
|
# stop() already stop daemons
|
||||||
|
[ "$INIT_APPLY_FW" != "1" ] || {
|
||||||
|
linux_fwtype
|
||||||
|
openwrt_fw3_integration || stop_fw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -22,3 +22,13 @@ zapret_custom_firewall()
|
|||||||
echo Configure iptables for required actions
|
echo Configure iptables for required actions
|
||||||
echo Study how other sections work
|
echo Study how other sections work
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Configure nftables for required actions
|
||||||
|
echo Study how other sections work
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
zapret_custom_daemons()
|
zapret_custom_daemons()
|
||||||
{
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local opt
|
local opt
|
||||||
|
|
||||||
[ "$MODE_HTTP" = "1" ] && {
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
@ -19,6 +21,8 @@ zapret_custom_daemons()
|
|||||||
}
|
}
|
||||||
zapret_custom_firewall()
|
zapret_custom_firewall()
|
||||||
{
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
local f4 f6
|
local f4 f6
|
||||||
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:4"
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||||
@ -37,3 +41,25 @@ zapret_custom_firewall()
|
|||||||
fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM
|
fw_nfqws_post $1 "$f4 $desync" "$f6 $desync" $QNUM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
local f4 f6
|
||||||
|
local first_packet_only="ct original packets 1-4"
|
||||||
|
local desync="mark and $DESYNC_MARK == 0"
|
||||||
|
|
||||||
|
[ "$MODE_HTTP" = "1" ] && {
|
||||||
|
f4="tcp dport 80"
|
||||||
|
f6=$f4
|
||||||
|
nft_filter_apply_ipset_target f4 f6
|
||||||
|
nft_fw_tpws "$f4" "$f6" $TPPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
[ "$MODE_HTTPS" = "1" ] && {
|
||||||
|
f4="tcp dport 443 $first_packet_only"
|
||||||
|
f6=$f4
|
||||||
|
nft_filter_apply_ipset_target f4 f6
|
||||||
|
nft_fw_nfqws_post "$f4 $desync" "$f6 $desync" $QNUM
|
||||||
|
}
|
||||||
|
}
|
||||||
|
34
init.d/sysv/custom.default
Normal file
34
init.d/sysv/custom.default
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# this script contain your special code to launch daemons and configure firewall
|
||||||
|
# use helpers from "functions" file
|
||||||
|
# in case of upgrade keep this file only, do not modify others
|
||||||
|
|
||||||
|
zapret_custom_daemons()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Start daemon\(s\)
|
||||||
|
echo Study how other sections work
|
||||||
|
|
||||||
|
do_daemon $1 1 /bin/sleep 20
|
||||||
|
}
|
||||||
|
zapret_custom_firewall()
|
||||||
|
{
|
||||||
|
# $1 - 1 - run, 0 - stop
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Configure iptables for required actions
|
||||||
|
echo Study how other sections work
|
||||||
|
}
|
||||||
|
|
||||||
|
zapret_custom_firewall_nft()
|
||||||
|
{
|
||||||
|
# stop logic is not required
|
||||||
|
|
||||||
|
# PLACEHOLDER
|
||||||
|
echo !!! NEED ATTENTION !!!
|
||||||
|
echo Configure nftables for required actions
|
||||||
|
echo Study how other sections work
|
||||||
|
}
|
@ -1,29 +1,16 @@
|
|||||||
# init script functions library for desktop linux systems
|
# init script functions library for desktop linux systems
|
||||||
|
|
||||||
[ -n "$ZAPRET_BASE" ] || ZAPRET_BASE=/opt/zapret
|
[ -n "$ZAPRET_BASE" ] || ZAPRET_BASE=/opt/zapret
|
||||||
# SHOULD EDIT config
|
|
||||||
. "$ZAPRET_BASE/config"
|
. "$ZAPRET_BASE/config"
|
||||||
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
|
. "$ZAPRET_BASE/common/queue.sh"
|
||||||
|
. "$ZAPRET_BASE/common/linux_iphelper.sh"
|
||||||
|
. "$ZAPRET_BASE/common/ipt.sh"
|
||||||
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
|
. "$ZAPRET_BASE/common/linux_fw.sh"
|
||||||
|
|
||||||
exists()
|
|
||||||
{
|
|
||||||
which "$1" >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
existf()
|
|
||||||
{
|
|
||||||
type "$1" >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
is_linked_to_busybox()
|
|
||||||
{
|
|
||||||
local IFS F P
|
|
||||||
|
|
||||||
IFS=:
|
|
||||||
for path in $PATH; do
|
|
||||||
F=$path/$1
|
|
||||||
P="$(readlink $F)"
|
|
||||||
if [ -z "$P" ] && [ -x $F ] && [ ! -L $F ]; then return 1; fi
|
|
||||||
[ "${P%busybox*}" != "$P" ] && return
|
|
||||||
done
|
|
||||||
}
|
|
||||||
user_exists()
|
user_exists()
|
||||||
{
|
{
|
||||||
id -u $1 >/dev/null 2>/dev/null
|
id -u $1 >/dev/null 2>/dev/null
|
||||||
@ -111,89 +98,12 @@ IPSET_EXCLUDE="-m set ! --match-set nozapret"
|
|||||||
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
|
||||||
|
|
||||||
|
|
||||||
on_off_function()
|
|
||||||
{
|
|
||||||
# $1 : function name on
|
|
||||||
# $2 : function name off
|
|
||||||
# $3 : 0 - off, 1 - on
|
|
||||||
local F="$1"
|
|
||||||
[ "$3" = "1" ] || F="$2"
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
"$F" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ipt()
|
|
||||||
{
|
|
||||||
iptables -C "$@" >/dev/null 2>/dev/null || iptables -I "$@"
|
|
||||||
}
|
|
||||||
ipt_del()
|
|
||||||
{
|
|
||||||
iptables -C "$@" >/dev/null 2>/dev/null && iptables -D "$@"
|
|
||||||
}
|
|
||||||
ipt_add_del()
|
|
||||||
{
|
|
||||||
on_off_function ipt ipt_del "$@"
|
|
||||||
}
|
|
||||||
ipt6()
|
|
||||||
{
|
|
||||||
ip6tables -C "$@" >/dev/null 2>/dev/null || ip6tables -I "$@"
|
|
||||||
}
|
|
||||||
ipt6_del()
|
|
||||||
{
|
|
||||||
ip6tables -C "$@" >/dev/null 2>/dev/null && ip6tables -D "$@"
|
|
||||||
}
|
|
||||||
ipt6_add_del()
|
|
||||||
{
|
|
||||||
on_off_function ipt6 ipt6_del "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# there's no route_localnet for ipv6
|
# there's no route_localnet for ipv6
|
||||||
# the best we can is to route to link local of the incoming interface
|
# the best we can is to route to link local of the incoming interface
|
||||||
# OUTPUT - can DNAT to ::1
|
# OUTPUT - can DNAT to ::1
|
||||||
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
|
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
|
||||||
# not a good idea to expose tpws to the world (bind to ::)
|
# not a good idea to expose tpws to the world (bind to ::)
|
||||||
|
|
||||||
get_ipv6_linklocal()
|
|
||||||
{
|
|
||||||
# $1 - interface name. if empty - any interface
|
|
||||||
local dev
|
|
||||||
[ -n "$1" ] && dev="dev $1"
|
|
||||||
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope link.*$/\1/;t;d' | head -n 1
|
|
||||||
}
|
|
||||||
get_ipv6_global()
|
|
||||||
{
|
|
||||||
# $1 - interface name. if empty - any interface
|
|
||||||
local dev
|
|
||||||
[ -n "$1" ] && dev="dev $1"
|
|
||||||
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1
|
|
||||||
}
|
|
||||||
|
|
||||||
iface_is_up()
|
|
||||||
{
|
|
||||||
# $1 - interface name
|
|
||||||
[ -f /sys/class/net/$1/operstate ] || return
|
|
||||||
local state
|
|
||||||
read state </sys/class/net/$1/operstate
|
|
||||||
[ "$state" != "down" ]
|
|
||||||
}
|
|
||||||
wait_ifup()
|
|
||||||
{
|
|
||||||
# $1 - interface name
|
|
||||||
local ct=0
|
|
||||||
while
|
|
||||||
iface_is_up $1 && return
|
|
||||||
[ "$ct" -ge "$IFUP_WAIT_SEC" ] && break
|
|
||||||
echo waiting for ifup of $1 for another $(($IFUP_WAIT_SEC - $ct)) seconds ...
|
|
||||||
ct=$(($ct+1))
|
|
||||||
sleep 1
|
|
||||||
do :; done
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dnat6_target()
|
dnat6_target()
|
||||||
{
|
{
|
||||||
# $1 - lan network name
|
# $1 - lan network name
|
||||||
@ -231,30 +141,51 @@ dnat6_target()
|
|||||||
[ -n "$2" ] && eval $2="$DNAT6_TARGET"
|
[ -n "$2" ] && eval $2="$DNAT6_TARGET"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_route_localnet()
|
||||||
|
{
|
||||||
|
# $1 - 1 = enable, 0 = disable
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
local lan
|
||||||
|
for lan in $IFACE_LAN ; do
|
||||||
|
sysctl -q -w net.ipv4.conf.$lan.route_localnet=$1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prepare_route_localnet()
|
||||||
|
{
|
||||||
|
set_route_localnet 1
|
||||||
|
}
|
||||||
|
unprepare_route_localnet()
|
||||||
|
{
|
||||||
|
set_route_localnet 0
|
||||||
|
}
|
||||||
prepare_tpws_fw4()
|
prepare_tpws_fw4()
|
||||||
{
|
{
|
||||||
# otherwise linux kernel will treat 127.0.0.0/8 as "martian" ip and refuse routing to it
|
# otherwise linux kernel will treat 127.0.0.0/8 as "martian" ip and refuse routing to it
|
||||||
# NOTE : kernels <3.6 do not have this feature. consider upgrading or change DNAT to REDIRECT and do not bind to 127.0.0.0/8
|
# NOTE : kernels <3.6 do not have this feature. consider upgrading or change DNAT to REDIRECT and do not bind to 127.0.0.0/8
|
||||||
[ -n "$IFACE_LAN" ] && {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
iptables -N input_rule_zapret 2>/dev/null
|
[ -n "$IFACE_LAN" ] && {
|
||||||
iptables -F input_rule_zapret
|
local lan
|
||||||
iptables -A input_rule_zapret -d $TPWS_LOCALHOST4 -j RETURN
|
iptables -N input_rule_zapret 2>/dev/null
|
||||||
iptables -A input_rule_zapret -d 127.0.0.0/8 -j DROP
|
iptables -F input_rule_zapret
|
||||||
for lan in $IFACE_LAN ; do
|
iptables -A input_rule_zapret -d $TPWS_LOCALHOST4 -j RETURN
|
||||||
ipt INPUT -i $lan -j input_rule_zapret
|
iptables -A input_rule_zapret -d 127.0.0.0/8 -j DROP
|
||||||
sysctl -q -w net.ipv4.conf.$lan.route_localnet=1
|
ipt INPUT ! -i lo -j input_rule_zapret
|
||||||
done
|
prepare_route_localnet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unprepare_tpws_fw4()
|
unprepare_tpws_fw4()
|
||||||
{
|
{
|
||||||
[ -n "$IFACE_LAN" ] && {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
for lan in $IFACE_LAN ; do
|
[ -n "$IFACE_LAN" ] && {
|
||||||
ipt_del INPUT -i $lan -j input_rule_zapret
|
local lan
|
||||||
sysctl -q -w net.ipv4.conf.$lan.route_localnet=0
|
unprepare_route_localnet
|
||||||
done
|
ipt_del INPUT ! -i lo -j input_rule_zapret
|
||||||
iptables -F input_rule_zapret 2>/dev/null
|
iptables -F input_rule_zapret 2>/dev/null
|
||||||
iptables -X input_rule_zapret 2>/dev/null
|
iptables -X input_rule_zapret 2>/dev/null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unprepare_tpws_fw()
|
unprepare_tpws_fw()
|
||||||
@ -263,7 +194,7 @@ unprepare_tpws_fw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
print_op()
|
ipt_print_op()
|
||||||
{
|
{
|
||||||
if [ "$1" = "1" ]; then
|
if [ "$1" = "1" ]; then
|
||||||
echo "Adding ip$4tables rule for $3 : $2"
|
echo "Adding ip$4tables rule for $3 : $2"
|
||||||
@ -279,7 +210,7 @@ fw_tpws4()
|
|||||||
# $3 - tpws port
|
# $3 - tpws port
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
[ "$1" = 1 ] && prepare_tpws_fw4
|
[ "$1" = 1 ] && prepare_tpws_fw4
|
||||||
print_op $1 "$2" "tpws (port $3)"
|
ipt_print_op $1 "$2" "tpws (port $3)"
|
||||||
for lan in $IFACE_LAN ; do
|
for lan in $IFACE_LAN ; do
|
||||||
ipt_add_del $1 PREROUTING -t nat -i $lan -p tcp $2 $IPSET_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3
|
ipt_add_del $1 PREROUTING -t nat -i $lan -p tcp $2 $IPSET_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3
|
||||||
done
|
done
|
||||||
@ -298,7 +229,7 @@ fw_tpws6()
|
|||||||
# $2 - iptable filter for ipv6
|
# $2 - iptable filter for ipv6
|
||||||
# $3 - tpws port
|
# $3 - tpws port
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
print_op $1 "$2" "tpws (port $3)" 6
|
ipt_print_op $1 "$2" "tpws (port $3)" 6
|
||||||
local DNAT6
|
local DNAT6
|
||||||
for lan in $IFACE_LAN ; do
|
for lan in $IFACE_LAN ; do
|
||||||
dnat6_target $lan DNAT6
|
dnat6_target $lan DNAT6
|
||||||
@ -330,7 +261,7 @@ fw_nfqws_pre4()
|
|||||||
# $2 - iptable filter for ipv4
|
# $2 - iptable filter for ipv4
|
||||||
# $3 - queue number
|
# $3 - queue number
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
print_op $1 "$2" "nfqws prerouting (qnum $3)"
|
ipt_print_op $1 "$2" "nfqws prerouting (qnum $3)"
|
||||||
if [ -n "$IFACE_WAN" ]; then
|
if [ -n "$IFACE_WAN" ]; then
|
||||||
for wan in $IFACE_WAN; do
|
for wan in $IFACE_WAN; do
|
||||||
ipt_add_del $1 PREROUTING -t mangle -i $wan -p tcp $2 $IPSET_EXCLUDE src -j NFQUEUE --queue-num $3 --queue-bypass
|
ipt_add_del $1 PREROUTING -t mangle -i $wan -p tcp $2 $IPSET_EXCLUDE src -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
@ -346,7 +277,7 @@ fw_nfqws_pre6()
|
|||||||
# $2 - iptable filter for ipv6
|
# $2 - iptable filter for ipv6
|
||||||
# $3 - queue number
|
# $3 - queue number
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
print_op $1 "$2" "nfqws prerouting (qnum $3)" 6
|
ipt_print_op $1 "$2" "nfqws prerouting (qnum $3)" 6
|
||||||
if [ -n "$IFACE_WAN" ]; then
|
if [ -n "$IFACE_WAN" ]; then
|
||||||
for wan in $IFACE_WAN; do
|
for wan in $IFACE_WAN; do
|
||||||
ipt6_add_del $1 PREROUTING -t mangle -i $wan -p tcp $2 $IPSET_EXCLUDE6 src -j NFQUEUE --queue-num $3 --queue-bypass
|
ipt6_add_del $1 PREROUTING -t mangle -i $wan -p tcp $2 $IPSET_EXCLUDE6 src -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
@ -371,7 +302,7 @@ fw_nfqws_post4()
|
|||||||
# $2 - iptable filter for ipv4
|
# $2 - iptable filter for ipv4
|
||||||
# $3 - queue number
|
# $3 - queue number
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
print_op $1 "$2" "nfqws postrouting (qnum $3)"
|
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)"
|
||||||
if [ -n "$IFACE_WAN" ]; then
|
if [ -n "$IFACE_WAN" ]; then
|
||||||
for wan in $IFACE_WAN; do
|
for wan in $IFACE_WAN; do
|
||||||
ipt_add_del $1 POSTROUTING -t mangle -o $wan -p tcp $2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass
|
ipt_add_del $1 POSTROUTING -t mangle -o $wan -p tcp $2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
@ -387,7 +318,7 @@ fw_nfqws_post6()
|
|||||||
# $2 - iptable filter for ipv6
|
# $2 - iptable filter for ipv6
|
||||||
# $3 - queue number
|
# $3 - queue number
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
print_op $1 "$2" "nfqws postrouting (qnum $3)" 6
|
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" 6
|
||||||
if [ -n "$IFACE_WAN" ]; then
|
if [ -n "$IFACE_WAN" ]; then
|
||||||
for wan in $IFACE_WAN; do
|
for wan in $IFACE_WAN; do
|
||||||
ipt6_add_del $1 POSTROUTING -t mangle -o $wan -p tcp $2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass
|
ipt6_add_del $1 POSTROUTING -t mangle -o $wan -p tcp $2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass
|
||||||
@ -407,6 +338,11 @@ fw_nfqws_post()
|
|||||||
fw_nfqws_post6 $1 "$3" $4
|
fw_nfqws_post6 $1 "$3" $4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter_apply_hostlist_target()
|
||||||
|
{
|
||||||
|
# $1 - var name of tpws or nfqws params
|
||||||
|
[ "$MODE_FILTER" = "hostlist" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
|
||||||
|
}
|
||||||
|
|
||||||
run_daemon()
|
run_daemon()
|
||||||
{
|
{
|
||||||
@ -506,96 +442,6 @@ do_nfqws()
|
|||||||
do_daemon $1 $2 "$NFQWS" "$NFQWS_OPT_BASE $3"
|
do_daemon $1 $2 "$NFQWS" "$NFQWS_OPT_BASE $3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
filter_apply_port_target()
|
|
||||||
{
|
|
||||||
# $1 - var name of iptables filter
|
|
||||||
local f
|
|
||||||
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
|
|
||||||
f="-m multiport --dports 80,443"
|
|
||||||
elif [ "$MODE_HTTPS" = "1" ]; then
|
|
||||||
f="--dport 443"
|
|
||||||
elif [ "$MODE_HTTP" = "1" ]; then
|
|
||||||
f="--dport 80"
|
|
||||||
else
|
|
||||||
echo WARNING !!! HTTP and HTTPS are both disabled
|
|
||||||
fi
|
|
||||||
eval $1="\"\$$1 $f\""
|
|
||||||
}
|
|
||||||
|
|
||||||
filter_apply_ipset_target4()
|
|
||||||
{
|
|
||||||
# $1 - var name of ipv4 iptables filter
|
|
||||||
if [ "$MODE_FILTER" = "ipset" ]; then
|
|
||||||
eval $1="\"\$$1 -m set --match-set zapret dst\""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
filter_apply_ipset_target6()
|
|
||||||
{
|
|
||||||
# $1 - var name of ipv4 iptables filter
|
|
||||||
if [ "$MODE_FILTER" = "ipset" ]; then
|
|
||||||
eval $1="\"\$$1 -m set --match-set zapret6 dst\""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
filter_apply_ipset_target()
|
|
||||||
{
|
|
||||||
# $1 - var name of ipv4 iptables filter
|
|
||||||
# $2 - var name of ipv6 iptables filter
|
|
||||||
filter_apply_ipset_target4 $1
|
|
||||||
filter_apply_ipset_target6 $2
|
|
||||||
}
|
|
||||||
filter_apply_hostlist_target()
|
|
||||||
{
|
|
||||||
# $1 - var name of tpws or nfqws params
|
|
||||||
[ "$MODE_FILTER" = "hostlist" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\""
|
|
||||||
}
|
|
||||||
|
|
||||||
get_nfqws_qnums()
|
|
||||||
{
|
|
||||||
# $1 - var name for ipv4 http
|
|
||||||
# $2 - var name for ipv4 https
|
|
||||||
# $3 - var name for ipv6 http
|
|
||||||
# $4 - var name for ipv6 https
|
|
||||||
local _qn _qns _qn6 _qns6
|
|
||||||
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
|
||||||
_qn=$QNUM
|
|
||||||
_qns=$_qn
|
|
||||||
[ "$NFQWS_OPT_DESYNC_HTTP" = "$NFQWS_OPT_DESYNC_HTTPS" ] || _qns=$(($QNUM+1))
|
|
||||||
}
|
|
||||||
[ "$DISABLE_IPV6" = "1" ] || {
|
|
||||||
_qn6=$(($QNUM+2))
|
|
||||||
_qns6=$(($QNUM+3))
|
|
||||||
[ "$DISABLE_IPV4" = "1" ] || {
|
|
||||||
if [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then
|
|
||||||
_qn6=$_qn;
|
|
||||||
elif [ "$NFQWS_OPT_DESYNC_HTTP6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then
|
|
||||||
_qn6=$_qns;
|
|
||||||
fi
|
|
||||||
if [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP" ]; then
|
|
||||||
_qns6=$_qn;
|
|
||||||
elif [ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTPS" ]; then
|
|
||||||
_qns6=$_qns;
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
[ "$NFQWS_OPT_DESYNC_HTTPS6" = "$NFQWS_OPT_DESYNC_HTTP6" ] && _qns6=$_qn6;
|
|
||||||
}
|
|
||||||
if [ "$MODE_HTTP" = 1 ]; then
|
|
||||||
eval $1=$_qn
|
|
||||||
eval $3=$_qn6
|
|
||||||
else
|
|
||||||
eval $1=
|
|
||||||
eval $3=
|
|
||||||
fi
|
|
||||||
if [ "$MODE_HTTPS" = 1 ]; then
|
|
||||||
eval $2=$_qns
|
|
||||||
eval $4=$_qns6
|
|
||||||
else
|
|
||||||
eval $2=
|
|
||||||
eval $4=
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
tpws_apply_socks_binds()
|
tpws_apply_socks_binds()
|
||||||
{
|
{
|
||||||
local o
|
local o
|
||||||
@ -613,95 +459,11 @@ tpws_apply_socks_binds()
|
|||||||
|
|
||||||
create_ipset()
|
create_ipset()
|
||||||
{
|
{
|
||||||
echo "Creating ipset"
|
echo "Creating ip list table (firewall type $FWTYPE)"
|
||||||
"$IPSET_CR" "$@"
|
"$IPSET_CR" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
zapret_do_firewall()
|
|
||||||
{
|
|
||||||
# $1 - 1 - add, 0 - del
|
|
||||||
|
|
||||||
local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4"
|
|
||||||
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
|
|
||||||
local f4 f6 qn qns qn6 qns6
|
|
||||||
|
|
||||||
# always create ipsets. ip_exclude ipset is required
|
|
||||||
[ "$1" != "1" ] || create_ipset no-update
|
|
||||||
|
|
||||||
case "${MODE_OVERRIDE:-$MODE}" in
|
|
||||||
tpws)
|
|
||||||
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
|
|
||||||
echo both http and https are disabled. not applying redirection.
|
|
||||||
else
|
|
||||||
filter_apply_port_target f4
|
|
||||||
f6=$f4
|
|
||||||
filter_apply_ipset_target f4 f6
|
|
||||||
fw_tpws $1 "$f4" "$f6" $TPPORT
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
nfqws)
|
|
||||||
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
|
|
||||||
echo both http and https are disabled. not applying redirection.
|
|
||||||
else
|
|
||||||
get_nfqws_qnums qn qns qn6 qns6
|
|
||||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
|
|
||||||
filter_apply_port_target f4
|
|
||||||
f4="$f4 $first_packet_only"
|
|
||||||
filter_apply_ipset_target4 f4
|
|
||||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
|
||||||
else
|
|
||||||
if [ -n "$qn" ]; then
|
|
||||||
f4="--dport 80"
|
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
|
|
||||||
filter_apply_ipset_target4 f4
|
|
||||||
fw_nfqws_post4 $1 "$f4 $desync" $qn
|
|
||||||
fi
|
|
||||||
if [ -n "$qns" ]; then
|
|
||||||
f4="--dport 443 $first_packet_only"
|
|
||||||
filter_apply_ipset_target4 f4
|
|
||||||
fw_nfqws_post4 $1 "$f4 $desync" $qns
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
|
|
||||||
filter_apply_port_target f6
|
|
||||||
f6="$f6 $first_packet_only"
|
|
||||||
filter_apply_ipset_target6 f6
|
|
||||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
|
||||||
else
|
|
||||||
if [ -n "$qn6" ]; then
|
|
||||||
f6="--dport 80"
|
|
||||||
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
|
|
||||||
filter_apply_ipset_target6 f6
|
|
||||||
fw_nfqws_post6 $1 "$f6 $desync" $qn6
|
|
||||||
fi
|
|
||||||
if [ -n "$qns6" ]; then
|
|
||||||
f6="--dport 443 $first_packet_only"
|
|
||||||
filter_apply_ipset_target6 f6
|
|
||||||
fw_nfqws_post6 $1 "$f6 $desync" $qns6
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
custom)
|
|
||||||
existf zapret_custom_firewall && zapret_custom_firewall $1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
[ "$1" = 0 ] && unprepare_tpws_fw
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
zapret_apply_firewall()
|
|
||||||
{
|
|
||||||
zapret_do_firewall 1 "$@"
|
|
||||||
}
|
|
||||||
zapret_unapply_firewall()
|
|
||||||
{
|
|
||||||
zapret_do_firewall 0 "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
zapret_do_daemons()
|
zapret_do_daemons()
|
||||||
{
|
{
|
||||||
# $1 - 1 - run, 0 - stop
|
# $1 - 1 - run, 0 - stop
|
||||||
@ -749,7 +511,6 @@ zapret_do_daemons()
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
zapret_run_daemons()
|
zapret_run_daemons()
|
||||||
{
|
{
|
||||||
zapret_do_daemons 1 "$@"
|
zapret_do_daemons 1 "$@"
|
||||||
@ -758,3 +519,120 @@ zapret_stop_daemons()
|
|||||||
{
|
{
|
||||||
zapret_do_daemons 0 "$@"
|
zapret_do_daemons 0 "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nft_fill_ifsets()
|
||||||
|
{
|
||||||
|
local script elements i ALLDEVS flags
|
||||||
|
|
||||||
|
# if large sets exist nft works very ineffectively
|
||||||
|
# looks like it analyzes the whole table blob to find required data pieces
|
||||||
|
# calling all in one shot helps not to waste cpu time many times
|
||||||
|
|
||||||
|
script="flush set inet $ZAPRET_NFT_TABLE wanif
|
||||||
|
flush set inet $ZAPRET_NFT_TABLE wanif6
|
||||||
|
flush set inet $ZAPRET_NFT_TABLE lanif"
|
||||||
|
|
||||||
|
[ -n "$IFACE_LAN" ] && {
|
||||||
|
make_comma_list elements $IFACE_LAN
|
||||||
|
script="${script}
|
||||||
|
add element inet $ZAPRET_NFT_TABLE lanif { $elements }"
|
||||||
|
}
|
||||||
|
[ -n "$IFACE_WAN" ] && {
|
||||||
|
make_comma_list elements $IFACE_WAN
|
||||||
|
script="${script}
|
||||||
|
add element inet $ZAPRET_NFT_TABLE wanif { $elements }
|
||||||
|
add element inet $ZAPRET_NFT_TABLE wanif6 { $elements }"
|
||||||
|
}
|
||||||
|
echo "$script" | nft -f -
|
||||||
|
|
||||||
|
[ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && {
|
||||||
|
ALLDEVS=$(for i in $IFACE_LAN $IFACE_WAN; do echo $i; done | sort -u | xargs)
|
||||||
|
[ -n "$ALLDEVS" ] && {
|
||||||
|
[ "$FLOWOFFLOAD" = 'hardware' ] && nft_hw_offload_supported $ALLDEVS && flags=offload
|
||||||
|
nft_create_or_update_flowtable "$flags" $ALLDEVS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_print_op()
|
||||||
|
{
|
||||||
|
echo "Adding nftables ipv$3 rule for $2 : $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_fw_tpws4()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv4
|
||||||
|
# $2 - tpws port
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
nft_print_op "$1" "tpws (port $2)" 4
|
||||||
|
nft_add_rule dnat_output skuid != $WS_USER ${IFACE_WAN:+oifname @wanif }meta l4proto tcp $1 ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$2
|
||||||
|
[ -n "$IFACE_LAN" ] && {
|
||||||
|
prepare_route_localnet
|
||||||
|
nft_add_rule dnat_pre iifname @lanif meta l4proto tcp $1 ip daddr != @nozapret dnat ip to $TPWS_LOCALHOST4:$2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_tpws6()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv6
|
||||||
|
# $2 - tpws port
|
||||||
|
|
||||||
|
local lan DNAT6
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
|
nft_print_op "$1" "tpws (port $2)" 6
|
||||||
|
nft_add_rule dnat_output skuid != $WS_USER ${IFACE_WAN:+oifname @wanif6 }meta l4proto tcp $1 ip6 daddr != @nozapret6 dnat ip6 to [::1]:$2
|
||||||
|
for lan in $IFACE_LAN ; do
|
||||||
|
dnat6_target $lan DNAT6
|
||||||
|
[ "$DNAT6" != '-' ] && nft_add_rule dnat_pre iifname $lan meta l4proto tcp $1 ip6 daddr != @nozapret6 dnat ip6 to [$DNAT6]:$2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_tpws()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv4
|
||||||
|
# $2 - filter ipv6
|
||||||
|
# $3 - tpws port
|
||||||
|
|
||||||
|
nft_fw_tpws4 "$1" $3
|
||||||
|
nft_fw_tpws6 "$2" $3
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_fw_nfqws_post4()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv4
|
||||||
|
# $2 - queue number
|
||||||
|
|
||||||
|
local rule
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV4" = "1" ] || {
|
||||||
|
nft_print_op "$1" "nfqws postrouting (qnum $2)" 4
|
||||||
|
rule="${IFACE_WAN:+oifname @wanif }meta l4proto tcp $1 ip daddr != @nozapret"
|
||||||
|
nft_add_rule postrouting $rule queue num $2 bypass
|
||||||
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_nfqws_post6()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv6
|
||||||
|
# $2 - queue number
|
||||||
|
|
||||||
|
local DEVICE rule
|
||||||
|
|
||||||
|
[ "$DISABLE_IPV6" = "1" ] || {
|
||||||
|
nft_print_op "$1" "nfqws postrouting (qnum $2)" 6
|
||||||
|
rule="${IFACE_WAN:+oifname @wanif6 }meta l4proto tcp $1 ip6 daddr != @nozapret6"
|
||||||
|
nft_add_rule postrouting $rule queue num $2 bypass
|
||||||
|
nft_add_nfqws_flow_exempt_rule "$rule"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nft_fw_nfqws_post()
|
||||||
|
{
|
||||||
|
# $1 - filter ipv4
|
||||||
|
# $2 - filter ipv6
|
||||||
|
# $3 - queue number
|
||||||
|
|
||||||
|
nft_fw_nfqws_post4 "$1" $3
|
||||||
|
nft_fw_nfqws_post6 "$2" $3
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@ DESC=anti-zapret
|
|||||||
do_start()
|
do_start()
|
||||||
{
|
{
|
||||||
zapret_run_daemons
|
zapret_run_daemons
|
||||||
[ "$INIT_APPLY_FW" != "1" ] || zapret_apply_firewall
|
[ "$INIT_APPLY_FW" != "1" ] || { zapret_apply_firewall; }
|
||||||
}
|
}
|
||||||
do_stop()
|
do_stop()
|
||||||
{
|
{
|
||||||
@ -40,32 +40,42 @@ case "$1" in
|
|||||||
do_start
|
do_start
|
||||||
;;
|
;;
|
||||||
|
|
||||||
start-fw)
|
start-fw|start_fw)
|
||||||
zapret_apply_firewall
|
zapret_apply_firewall
|
||||||
;;
|
;;
|
||||||
stop-fw)
|
stop-fw|stop_fw)
|
||||||
zapret_unapply_firewall
|
zapret_unapply_firewall
|
||||||
;;
|
;;
|
||||||
|
|
||||||
restart-fw)
|
restart-fw|restart_fw)
|
||||||
zapret_unapply_firewall
|
zapret_unapply_firewall
|
||||||
zapret_apply_firewall
|
zapret_apply_firewall
|
||||||
;;
|
;;
|
||||||
|
|
||||||
start-daemons)
|
start-daemons|start_daemons)
|
||||||
zapret_run_daemons
|
zapret_run_daemons
|
||||||
;;
|
;;
|
||||||
stop-daemons)
|
stop-daemons|stop_daemons)
|
||||||
zapret_stop_daemons
|
zapret_stop_daemons
|
||||||
;;
|
;;
|
||||||
restart-daemons)
|
restart-daemons|restart_daemons)
|
||||||
zapret_stop_daemons
|
zapret_stop_daemons
|
||||||
zapret_run_daemons
|
zapret_run_daemons
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
reload-ifsets|reload_ifsets)
|
||||||
|
zapret_reload_ifsets
|
||||||
|
;;
|
||||||
|
list-ifsets|list_ifsets)
|
||||||
|
zapret_list_ifsets
|
||||||
|
;;
|
||||||
|
list-table|list_table)
|
||||||
|
zapret_list_table
|
||||||
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
N=/etc/init.d/$NAME
|
N=/etc/init.d/$NAME
|
||||||
echo "Usage: $N {start|stop|restart|start-fw|stop-fw|restart-fw|start-daemons|stop-daemons|restart-daemons}" >&2
|
echo "Usage: $N {start|stop|restart|start-fw|stop-fw|restart-fw|start-daemons|stop-daemons|restart-daemons|reload-ifsets|list-ifsets|list-table}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
634
install_easy.sh
634
install_easy.sh
@ -9,64 +9,23 @@ ZAPRET_CONFIG="$EXEDIR/config"
|
|||||||
ZAPRET_BASE="$EXEDIR"
|
ZAPRET_BASE="$EXEDIR"
|
||||||
|
|
||||||
. "$ZAPRET_CONFIG"
|
. "$ZAPRET_CONFIG"
|
||||||
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
|
. "$ZAPRET_BASE/common/elevate.sh"
|
||||||
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
|
. "$ZAPRET_BASE/common/dialog.sh"
|
||||||
|
. "$ZAPRET_BASE/common/ipt.sh"
|
||||||
|
. "$ZAPRET_BASE/common/installer.sh"
|
||||||
|
|
||||||
# install target
|
# install target
|
||||||
ZAPRET_TARGET=/opt/zapret
|
ZAPRET_TARGET=/opt/zapret
|
||||||
|
|
||||||
GET_LIST="$IPSET_DIR/get_config.sh"
|
GET_LIST="$IPSET_DIR/get_config.sh"
|
||||||
GET_LIST_PREFIX=/ipset/get_
|
|
||||||
INIT_SCRIPT=/etc/init.d/zapret
|
|
||||||
|
|
||||||
[ -n "$TPPORT" ] || TPPORT=988
|
[ -n "$TPPORT" ] || TPPORT=988
|
||||||
|
|
||||||
SYSTEMD_DIR=/lib/systemd
|
|
||||||
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
|
|
||||||
[ -d "$SYSTEMD_DIR" ] && SYSTEMD_SYSTEM_DIR="$SYSTEMD_DIR/system"
|
|
||||||
|
|
||||||
ECHON="echo -n"
|
|
||||||
|
|
||||||
exists()
|
|
||||||
{
|
|
||||||
which $1 >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
whichq()
|
|
||||||
{
|
|
||||||
which $1 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
MD5=md5sum
|
MD5=md5sum
|
||||||
exists $MD5 || MD5=md5
|
exists $MD5 || MD5=md5
|
||||||
|
|
||||||
contains()
|
|
||||||
{
|
|
||||||
# check if substring $2 contains in $1
|
|
||||||
[ "${1#*$2}" != "$1" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
exitp()
|
|
||||||
{
|
|
||||||
local A
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo press enter to continue
|
|
||||||
read A
|
|
||||||
exit $1
|
|
||||||
}
|
|
||||||
|
|
||||||
require_root()
|
|
||||||
{
|
|
||||||
local exe
|
|
||||||
echo \* checking privileges
|
|
||||||
[ $(id -u) -ne "0" ] && {
|
|
||||||
echo root is required
|
|
||||||
exe="$EXEDIR/$(basename "$0")"
|
|
||||||
exists sudo && exec sudo "$exe"
|
|
||||||
exists su && exec su root -c "$exe"
|
|
||||||
echo su or sudo not found
|
|
||||||
exitp 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sedi()
|
sedi()
|
||||||
{
|
{
|
||||||
# MacOS doesnt support -i without parameter. busybox doesnt support -i with parameter.
|
# MacOS doesnt support -i without parameter. busybox doesnt support -i with parameter.
|
||||||
@ -78,58 +37,6 @@ sedi()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
read_yes_no()
|
|
||||||
{
|
|
||||||
# $1 - default (Y/N)
|
|
||||||
local A
|
|
||||||
read A
|
|
||||||
[ -z "$A" ] || ([ "$A" != "Y" ] && [ "$A" != "y" ] && [ "$A" != "N" ] && [ "$A" != "n" ]) && A=$1
|
|
||||||
[ "$A" = "Y" ] || [ "$A" = "y" ] || [ "$A" = "1" ]
|
|
||||||
}
|
|
||||||
ask_yes_no()
|
|
||||||
{
|
|
||||||
# $1 - default (Y/N or 0/1)
|
|
||||||
# $2 - text
|
|
||||||
local DEFAULT=$1
|
|
||||||
[ "$1" = "1" ] && DEFAULT=Y
|
|
||||||
[ "$1" = "0" ] && DEFAULT=N
|
|
||||||
[ -z "$DEFAULT" ] && DEFAULT=N
|
|
||||||
$ECHON "$2 (default : $DEFAULT) (Y/N) ? "
|
|
||||||
read_yes_no $DEFAULT
|
|
||||||
}
|
|
||||||
ask_yes_no_var()
|
|
||||||
{
|
|
||||||
# $1 - variable name for answer : 0/1
|
|
||||||
# $2 - text
|
|
||||||
local DEFAULT
|
|
||||||
eval DEFAULT="\$$1"
|
|
||||||
if ask_yes_no "$DEFAULT" "$2"; then
|
|
||||||
eval $1=1
|
|
||||||
else
|
|
||||||
eval $1=0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
on_off_function()
|
|
||||||
{
|
|
||||||
# $1 : function name on
|
|
||||||
# $2 : function name off
|
|
||||||
# $3 : 0 - off, 1 - on
|
|
||||||
local F="$1"
|
|
||||||
[ "$3" = "1" ] || F="$2"
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
"$F" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
get_dir_inode()
|
|
||||||
{
|
|
||||||
local dir="$1"
|
|
||||||
[ -L "$dir" ] && dir=$(readlink "$dir")
|
|
||||||
ls -id "$dir" | awk '{print $1}'
|
|
||||||
}
|
|
||||||
|
|
||||||
random()
|
random()
|
||||||
{
|
{
|
||||||
# $1 - min, $2 - max
|
# $1 - min, $2 - max
|
||||||
@ -144,96 +51,6 @@ random()
|
|||||||
echo $(( ($r % ($2-$1+1)) + $1 ))
|
echo $(( ($r % ($2-$1+1)) + $1 ))
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_var_checked()
|
|
||||||
{
|
|
||||||
# $1 - file name
|
|
||||||
# $2 - var name
|
|
||||||
local sed="sed -nre s/^[[:space:]]*$2=[\\\"|\']?([^\\\"|\']*)[\\\"|\']?/\1/p"
|
|
||||||
local v="$($sed <"$1" | tail -n 1)"
|
|
||||||
eval $2=\"$v\"
|
|
||||||
}
|
|
||||||
parse_vars_checked()
|
|
||||||
{
|
|
||||||
# $1 - file name
|
|
||||||
# $2,$3,... - var names
|
|
||||||
local f="$1"
|
|
||||||
shift
|
|
||||||
while [ -n "$1" ]; do
|
|
||||||
parse_var_checked "$f" $1
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
}
|
|
||||||
edit_file()
|
|
||||||
{
|
|
||||||
# $1 - file name
|
|
||||||
local ed="$EDITOR"
|
|
||||||
[ -n "$ed" ] || {
|
|
||||||
for e in mcedit nano vi; do
|
|
||||||
exists "$e" && {
|
|
||||||
ed="$e"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
done
|
|
||||||
}
|
|
||||||
[ -n "$ed" ] && "$ed" "$1"
|
|
||||||
}
|
|
||||||
edit_vars()
|
|
||||||
{
|
|
||||||
# $1,$2,... - var names
|
|
||||||
local n=1 var v tmp="/tmp/zvars"
|
|
||||||
rm -f "$tmp"
|
|
||||||
while [ 1=1 ]; do
|
|
||||||
eval var="\$$n"
|
|
||||||
[ -n "$var" ] || break
|
|
||||||
eval v="\$$var"
|
|
||||||
echo $var=\"$v\" >>"$tmp"
|
|
||||||
n=$(($n+1))
|
|
||||||
done
|
|
||||||
edit_file "$tmp" && parse_vars_checked "$tmp" "$@"
|
|
||||||
rm -f "$tmp"
|
|
||||||
}
|
|
||||||
|
|
||||||
check_system()
|
|
||||||
{
|
|
||||||
echo \* checking system
|
|
||||||
|
|
||||||
SYSTEM=""
|
|
||||||
SYSTEMCTL=$(whichq systemctl)
|
|
||||||
|
|
||||||
local UNAME=$(uname)
|
|
||||||
if [ "$UNAME" = "Linux" ]; then
|
|
||||||
# do not use 'exe' because it requires root
|
|
||||||
local INIT=$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)
|
|
||||||
[ -L "$INIT" ] && INIT=$(readlink "$INIT")
|
|
||||||
INIT=$(basename "$INIT")
|
|
||||||
# some distros include systemctl without systemd
|
|
||||||
if [ -d "$SYSTEMD_DIR" ] && [ -x "$SYSTEMCTL" ] && [ "$INIT" = "systemd" ]; then
|
|
||||||
SYSTEM=systemd
|
|
||||||
elif exists rc-update && [ "$INIT" = "openrc-init" ]; then
|
|
||||||
SYSTEM=openrc
|
|
||||||
elif [ -f "/etc/openwrt_release" ] && exists opkg && exists uci && [ "$INIT" = "procd" ] ; then
|
|
||||||
SYSTEM=openwrt
|
|
||||||
else
|
|
||||||
echo system is not either systemd, openrc or openwrt based
|
|
||||||
echo easy installer can set up config settings but can\'t configure auto start
|
|
||||||
echo you have to do it manually. check readme.txt for manual setup info.
|
|
||||||
if ask_yes_no N "do you want to continue"; then
|
|
||||||
SYSTEM=linux
|
|
||||||
else
|
|
||||||
exitp 5
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif [ "$UNAME" = "Darwin" ]; then
|
|
||||||
SYSTEM=macos
|
|
||||||
# MacOS echo from /bin/sh does not support -n
|
|
||||||
ECHON=printf
|
|
||||||
else
|
|
||||||
echo easy installer only supports Linux and MacOS. check readme.txt for supported systems and manual setup info.
|
|
||||||
exitp 5
|
|
||||||
fi
|
|
||||||
echo system is based on $SYSTEM
|
|
||||||
}
|
|
||||||
|
|
||||||
check_readonly_system()
|
check_readonly_system()
|
||||||
{
|
{
|
||||||
local RO
|
local RO
|
||||||
@ -304,43 +121,6 @@ install_binaries()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
find_str_in_list()
|
|
||||||
{
|
|
||||||
[ -n "$1" ] && {
|
|
||||||
for v in $2; do
|
|
||||||
[ "$v" = "$1" ] && return 0
|
|
||||||
done
|
|
||||||
}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
ask_list()
|
|
||||||
{
|
|
||||||
# $1 - mode var
|
|
||||||
# $2 - space separated value list
|
|
||||||
# $3 - (optional) default value
|
|
||||||
local M_DEFAULT
|
|
||||||
eval M_DEFAULT="\$$1"
|
|
||||||
local M_ALL=$M_DEFAULT
|
|
||||||
local M=""
|
|
||||||
local m
|
|
||||||
|
|
||||||
[ -n "$3" ] && { find_str_in_list "$M_DEFAULT" "$2" || M_DEFAULT="$3" ;}
|
|
||||||
|
|
||||||
n=1
|
|
||||||
for m in $2; do
|
|
||||||
echo $n : $m
|
|
||||||
n=$(($n+1))
|
|
||||||
done
|
|
||||||
$ECHON "your choice (default : $M_DEFAULT) : "
|
|
||||||
read m
|
|
||||||
[ -n "$m" ] && M=$(echo $2 | cut -d ' ' -f$m 2>/dev/null)
|
|
||||||
[ -z "$M" ] && M="$M_DEFAULT"
|
|
||||||
echo selected : $M
|
|
||||||
eval $1="\"$M\""
|
|
||||||
|
|
||||||
[ "$M" != "$M_OLD" ]
|
|
||||||
}
|
|
||||||
write_config_var()
|
write_config_var()
|
||||||
{
|
{
|
||||||
# $1 - mode var
|
# $1 - mode var
|
||||||
@ -488,6 +268,17 @@ select_ipv6()
|
|||||||
fi
|
fi
|
||||||
[ "$old6" != "$DISABLE_IPV6" ] && write_config_var DISABLE_IPV6
|
[ "$old6" != "$DISABLE_IPV6" ] && write_config_var DISABLE_IPV6
|
||||||
}
|
}
|
||||||
|
select_fwtype()
|
||||||
|
{
|
||||||
|
echo
|
||||||
|
[ $(get_ram_mb) -le 400 ] && {
|
||||||
|
echo WARNING ! you are running a low RAM system
|
||||||
|
echo WARNING ! nft requires lots of RAM to load huge ip sets, much more than ipsets require
|
||||||
|
echo WARNING ! if you need large lists it may be necessary to fall back to iptables+ipset firewall
|
||||||
|
}
|
||||||
|
echo select firewall type :
|
||||||
|
ask_list FWTYPE "iptables nftables" "$FWTYPE" && write_config_var FWTYPE
|
||||||
|
}
|
||||||
|
|
||||||
ask_config()
|
ask_config()
|
||||||
{
|
{
|
||||||
@ -497,7 +288,7 @@ ask_config()
|
|||||||
|
|
||||||
ask_config_offload()
|
ask_config_offload()
|
||||||
{
|
{
|
||||||
is_flow_offload_avail && {
|
[ "$FWTYPE" = nftables ] || is_ipt_flow_offload_avail && {
|
||||||
echo
|
echo
|
||||||
echo flow offloading can greatly increase speed on slow devices and high speed links \(usually 150+ mbits\)
|
echo flow offloading can greatly increase speed on slow devices and high speed links \(usually 150+ mbits\)
|
||||||
echo unfortuantely its not compatible with most nfqws options. nfqws traffic must be exempted from flow offloading.
|
echo unfortuantely its not compatible with most nfqws options. nfqws traffic must be exempted from flow offloading.
|
||||||
@ -510,20 +301,6 @@ ask_config_offload()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_free_space_mb()
|
|
||||||
{
|
|
||||||
df -m $PWD | awk '/[0-9]%/{print $(NF-2)}'
|
|
||||||
}
|
|
||||||
get_ram_kb()
|
|
||||||
{
|
|
||||||
grep MemTotal /proc/meminfo | awk '{print $2}'
|
|
||||||
}
|
|
||||||
get_ram_mb()
|
|
||||||
{
|
|
||||||
local R=$(get_ram_kb)
|
|
||||||
echo $(($R/1024))
|
|
||||||
}
|
|
||||||
|
|
||||||
ask_config_tmpdir()
|
ask_config_tmpdir()
|
||||||
{
|
{
|
||||||
# ask tmpdir change for low ram systems with enough free disk space
|
# ask tmpdir change for low ram systems with enough free disk space
|
||||||
@ -643,7 +420,7 @@ copy_openwrt()
|
|||||||
[ -d "$2" ] || mkdir -p "$2"
|
[ -d "$2" ] || mkdir -p "$2"
|
||||||
|
|
||||||
mkdir "$2/tpws" "$2/nfq" "$2/ip2net" "$2/mdig" "$2/binaries" "$2/binaries/$ARCH" "$2/init.d" "$2/tmp"
|
mkdir "$2/tpws" "$2/nfq" "$2/ip2net" "$2/mdig" "$2/binaries" "$2/binaries/$ARCH" "$2/init.d" "$2/tmp"
|
||||||
cp -R "$1/ipset" "$2"
|
cp -R "$1/common" "$1/ipset" "$2"
|
||||||
cp -R "$1/init.d/openwrt" "$2/init.d"
|
cp -R "$1/init.d/openwrt" "$2/init.d"
|
||||||
cp "$1/config" "$1/install_easy.sh" "$1/uninstall_easy.sh" "$1/install_bin.sh" "$1/blockcheck.sh" "$2"
|
cp "$1/config" "$1/install_easy.sh" "$1/uninstall_easy.sh" "$1/install_bin.sh" "$1/blockcheck.sh" "$2"
|
||||||
cp "$BINDIR/tpws" "$BINDIR/nfqws" "$BINDIR/ip2net" "$BINDIR/mdig" "$2/binaries/$ARCH"
|
cp "$BINDIR/tpws" "$BINDIR/nfqws" "$BINDIR/ip2net" "$BINDIR/mdig" "$2/binaries/$ARCH"
|
||||||
@ -718,19 +495,34 @@ check_prerequisites_linux()
|
|||||||
{
|
{
|
||||||
echo \* checking prerequisites
|
echo \* checking prerequisites
|
||||||
|
|
||||||
if exists iptables && exists ip6tables ; then
|
local s cmd PKGS UTILS req="curl curl"
|
||||||
echo iptables present
|
case "$FWTYPE" in
|
||||||
else
|
iptables)
|
||||||
# looks like it's a limited system. will not guess how to install base tools
|
req="$req iptables iptables ip6tables iptables ipset ipset"
|
||||||
echo '! iptables/ip6tables NOT present. you must install them manually.'
|
;;
|
||||||
exitp 5
|
nftables)
|
||||||
fi
|
req="$req nft nftables"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if exists ipset && exists curl ; then
|
PKGS=$(for s in $req; do echo $s; done |
|
||||||
echo ipset and curl are present
|
while read cmd; do
|
||||||
|
read pkg
|
||||||
|
exists $cmd || echo $pkg
|
||||||
|
done | sort -u | xargs)
|
||||||
|
UTILS=$(for s in $req; do echo $s; done |
|
||||||
|
while read cmd; do
|
||||||
|
read pkg
|
||||||
|
echo $cmd
|
||||||
|
done | sort -u | xargs)
|
||||||
|
|
||||||
|
if [ -z "$PKGS" ] ; then
|
||||||
|
echo required utilities exist : $UTILS
|
||||||
else
|
else
|
||||||
echo \* installing prerequisites
|
echo \* installing prerequisites
|
||||||
|
|
||||||
|
echo packages required : $PKGS
|
||||||
|
|
||||||
APTGET=$(whichq apt-get)
|
APTGET=$(whichq apt-get)
|
||||||
YUM=$(whichq yum)
|
YUM=$(whichq yum)
|
||||||
PACMAN=$(whichq pacman)
|
PACMAN=$(whichq pacman)
|
||||||
@ -739,39 +531,42 @@ check_prerequisites_linux()
|
|||||||
APK=$(whichq apk)
|
APK=$(whichq apk)
|
||||||
if [ -x "$APTGET" ] ; then
|
if [ -x "$APTGET" ] ; then
|
||||||
"$APTGET" update
|
"$APTGET" update
|
||||||
"$APTGET" install -y --no-install-recommends ipset curl dnsutils || {
|
"$APTGET" install -y --no-install-recommends $PKGS dnsutils || {
|
||||||
echo could not install prerequisites
|
echo could not install prerequisites
|
||||||
exitp 6
|
exitp 6
|
||||||
}
|
}
|
||||||
elif [ -x "$YUM" ] ; then
|
elif [ -x "$YUM" ] ; then
|
||||||
"$YUM" -y install curl ipset || {
|
"$YUM" -y install $PKGS || {
|
||||||
echo could not install prerequisites
|
echo could not install prerequisites
|
||||||
exitp 6
|
exitp 6
|
||||||
}
|
}
|
||||||
elif [ -x "$PACMAN" ] ; then
|
elif [ -x "$PACMAN" ] ; then
|
||||||
"$PACMAN" -Syy
|
"$PACMAN" -Syy
|
||||||
"$PACMAN" --noconfirm -S ipset curl || {
|
"$PACMAN" --noconfirm -S $PKGS || {
|
||||||
echo could not install prerequisites
|
echo could not install prerequisites
|
||||||
exitp 6
|
exitp 6
|
||||||
}
|
}
|
||||||
elif [ -x "$ZYPPER" ] ; then
|
elif [ -x "$ZYPPER" ] ; then
|
||||||
"$ZYPPER" --non-interactive install ipset curl || {
|
"$ZYPPER" --non-interactive install $PKGS || {
|
||||||
echo could not install prerequisites
|
echo could not install prerequisites
|
||||||
exitp 6
|
exitp 6
|
||||||
}
|
}
|
||||||
elif [ -x "$EOPKG" ] ; then
|
elif [ -x "$EOPKG" ] ; then
|
||||||
"$EOPKG" -y install ipset curl || {
|
"$EOPKG" -y install $PKGS || {
|
||||||
echo could not install prerequisites
|
echo could not install prerequisites
|
||||||
exitp 6
|
exitp 6
|
||||||
}
|
}
|
||||||
elif [ -x "$APK" ] ; then
|
elif [ -x "$APK" ] ; then
|
||||||
"$APK" add ipset curl || {
|
"$APK" update
|
||||||
|
# for alpine
|
||||||
|
[ "$FWTYPE" = iptables ] && [ -n "$($APK list ip6tables)" ] && PKGS="$PKGS ip6tables"
|
||||||
|
"$APK" add $PKGS || {
|
||||||
echo could not install prerequisites
|
echo could not install prerequisites
|
||||||
exitp 6
|
exitp 6
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
echo supported package manager not found
|
echo supported package manager not found
|
||||||
echo you must manually install : ipset curl
|
echo you must manually install : $UTILS
|
||||||
exitp 5
|
exitp 5
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -795,25 +590,6 @@ service_install_systemd()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
service_stop_systemd()
|
|
||||||
{
|
|
||||||
echo \* stopping zapret service
|
|
||||||
|
|
||||||
"$SYSTEMCTL" daemon-reload
|
|
||||||
"$SYSTEMCTL" disable zapret
|
|
||||||
"$SYSTEMCTL" stop zapret
|
|
||||||
}
|
|
||||||
|
|
||||||
service_start_systemd()
|
|
||||||
{
|
|
||||||
echo \* starting zapret service
|
|
||||||
|
|
||||||
"$SYSTEMCTL" start zapret || {
|
|
||||||
echo could not start zapret service
|
|
||||||
exitp 30
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_install_systemd()
|
timer_install_systemd()
|
||||||
{
|
{
|
||||||
echo \* installing zapret-list-update timer
|
echo \* installing zapret-list-update timer
|
||||||
@ -851,59 +627,6 @@ download_list()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end_with_newline()
|
|
||||||
{
|
|
||||||
local c=$(tail -c 1)
|
|
||||||
[ "$c" = "" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
crontab_del_quiet()
|
|
||||||
{
|
|
||||||
exists crontab || return
|
|
||||||
|
|
||||||
CRONTMP=/tmp/cron.tmp
|
|
||||||
crontab -l >$CRONTMP 2>/dev/null
|
|
||||||
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
|
||||||
grep -v "$GET_LIST_PREFIX" $CRONTMP >$CRONTMP.2
|
|
||||||
crontab $CRONTMP.2
|
|
||||||
rm -f $CRONTMP.2
|
|
||||||
fi
|
|
||||||
rm -f $CRONTMP
|
|
||||||
}
|
|
||||||
|
|
||||||
crontab_add()
|
|
||||||
{
|
|
||||||
# $1 - hour min
|
|
||||||
# $2 - hour max
|
|
||||||
[ -x "$GET_LIST" ] && {
|
|
||||||
echo \* adding crontab entry
|
|
||||||
|
|
||||||
if exists crontab; then
|
|
||||||
CRONTMP=/tmp/cron.tmp
|
|
||||||
crontab -l >$CRONTMP 2>/dev/null
|
|
||||||
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
|
||||||
echo some entries already exist in crontab. check if this is corrent :
|
|
||||||
grep "$GET_LIST_PREFIX" $CRONTMP
|
|
||||||
else
|
|
||||||
end_with_newline <"$CRONTMP" || echo >>"$CRONTMP"
|
|
||||||
echo "$(random 0 59) $(random $1 $2) */2 * * $GET_LIST" >>$CRONTMP
|
|
||||||
crontab $CRONTMP
|
|
||||||
fi
|
|
||||||
rm -f $CRONTMP
|
|
||||||
else
|
|
||||||
echo '!!! CRON IS ABSENT !!! LISTS AUTO UPDATE WILL NOT WORK !!!'
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cron_ensure_running()
|
|
||||||
{
|
|
||||||
# if no crontabs present in /etc/cron openwrt init script does not launch crond. this is default
|
|
||||||
[ "$SYSTEM" = "openwrt" ] && {
|
|
||||||
/etc/init.d/cron enable
|
|
||||||
/etc/init.d/cron start
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dnstest()
|
dnstest()
|
||||||
{
|
{
|
||||||
@ -930,10 +653,11 @@ install_systemd()
|
|||||||
require_root
|
require_root
|
||||||
check_readonly_system
|
check_readonly_system
|
||||||
check_location copy_all
|
check_location copy_all
|
||||||
check_prerequisites_linux
|
|
||||||
service_stop_systemd
|
|
||||||
install_binaries
|
|
||||||
check_dns
|
check_dns
|
||||||
|
service_stop_systemd
|
||||||
|
select_fwtype
|
||||||
|
check_prerequisites_linux
|
||||||
|
install_binaries
|
||||||
select_ipv6
|
select_ipv6
|
||||||
ask_config
|
ask_config
|
||||||
service_install_systemd
|
service_install_systemd
|
||||||
@ -945,66 +669,19 @@ install_systemd()
|
|||||||
service_start_systemd
|
service_start_systemd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
install_sysv_init()
|
|
||||||
{
|
|
||||||
# $1 - "0"=disable
|
|
||||||
echo \* installing init script
|
|
||||||
|
|
||||||
[ -x "$INIT_SCRIPT" ] && {
|
|
||||||
"$INIT_SCRIPT" stop
|
|
||||||
"$INIT_SCRIPT" disable
|
|
||||||
}
|
|
||||||
ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
|
|
||||||
[ "$1" != "0" ] && "$INIT_SCRIPT" enable
|
|
||||||
}
|
|
||||||
|
|
||||||
install_openrc_init()
|
|
||||||
{
|
|
||||||
# $1 - "0"=disable
|
|
||||||
echo \* installing init script
|
|
||||||
|
|
||||||
[ -x "$INIT_SCRIPT" ] && {
|
|
||||||
"$INIT_SCRIPT" stop
|
|
||||||
rc-update del zapret
|
|
||||||
}
|
|
||||||
ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
|
|
||||||
[ "$1" != "0" ] && rc-update add zapret
|
|
||||||
}
|
|
||||||
|
|
||||||
service_start_sysv()
|
|
||||||
{
|
|
||||||
[ -x "$INIT_SCRIPT" ] && {
|
|
||||||
echo \* starting zapret service
|
|
||||||
"$INIT_SCRIPT" start || {
|
|
||||||
echo could not start zapret service
|
|
||||||
exitp 30
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
service_stop_sysv()
|
|
||||||
{
|
|
||||||
[ -x "$INIT_SCRIPT" ] && {
|
|
||||||
echo \* stopping zapret service
|
|
||||||
"$INIT_SCRIPT" stop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_install_sysv()
|
_install_sysv()
|
||||||
{
|
{
|
||||||
# $1 - install init script
|
# $1 - install init script
|
||||||
INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret"
|
|
||||||
|
|
||||||
check_bins
|
check_bins
|
||||||
require_root
|
require_root
|
||||||
check_readonly_system
|
check_readonly_system
|
||||||
check_location copy_all
|
check_location copy_all
|
||||||
check_prerequisites_linux
|
|
||||||
service_stop_sysv
|
|
||||||
install_binaries
|
|
||||||
check_dns
|
check_dns
|
||||||
|
service_stop_sysv
|
||||||
|
select_fwtype
|
||||||
|
check_prerequisites_linux
|
||||||
|
install_binaries
|
||||||
select_ipv6
|
select_ipv6
|
||||||
ask_config
|
ask_config
|
||||||
$1
|
$1
|
||||||
@ -1017,11 +694,13 @@ _install_sysv()
|
|||||||
|
|
||||||
install_sysv()
|
install_sysv()
|
||||||
{
|
{
|
||||||
|
INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret"
|
||||||
_install_sysv install_sysv_init
|
_install_sysv install_sysv_init
|
||||||
}
|
}
|
||||||
|
|
||||||
install_openrc()
|
install_openrc()
|
||||||
{
|
{
|
||||||
|
INIT_SCRIPT_SRC="$EXEDIR/init.d/openrc/zapret"
|
||||||
_install_sysv install_openrc_init
|
_install_sysv install_openrc_init
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1033,9 +712,10 @@ install_linux()
|
|||||||
check_bins
|
check_bins
|
||||||
require_root
|
require_root
|
||||||
check_location copy_all
|
check_location copy_all
|
||||||
|
check_dns
|
||||||
|
select_fwtype
|
||||||
check_prerequisites_linux
|
check_prerequisites_linux
|
||||||
install_binaries
|
install_binaries
|
||||||
check_dns
|
|
||||||
select_ipv6
|
select_ipv6
|
||||||
ask_config
|
ask_config
|
||||||
download_list
|
download_list
|
||||||
@ -1051,45 +731,22 @@ install_linux()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
check_kmod()
|
|
||||||
{
|
|
||||||
[ -f "/lib/modules/$(uname -r)/$1.ko" ]
|
|
||||||
}
|
|
||||||
check_package_exists_openwrt()
|
|
||||||
{
|
|
||||||
[ -n "$(opkg list $1)" ]
|
|
||||||
}
|
|
||||||
check_package_openwrt()
|
|
||||||
{
|
|
||||||
[ -n "$(opkg list-installed $1)" ]
|
|
||||||
}
|
|
||||||
check_packages_openwrt()
|
|
||||||
{
|
|
||||||
for pkg in $@; do
|
|
||||||
check_package_openwrt $pkg || return
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
is_linked_to_busybox()
|
|
||||||
{
|
|
||||||
local IFS F P
|
|
||||||
|
|
||||||
IFS=:
|
|
||||||
for path in $PATH; do
|
|
||||||
F=$path/$1
|
|
||||||
P="$(readlink $F)"
|
|
||||||
if [ -z "$P" ] && [ -x $F ] && [ ! -L $F ]; then return 1; fi
|
|
||||||
[ "${P%busybox*}" != "$P" ] && return
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
check_prerequisites_openwrt()
|
check_prerequisites_openwrt()
|
||||||
{
|
{
|
||||||
echo \* checking prerequisites
|
echo \* checking prerequisites
|
||||||
|
|
||||||
local PKGS="iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra ipset curl"
|
local PKGS="curl" PKGS UPD=0
|
||||||
[ "$DISABLE_IPV6" != "1" ] && PKGS="$PKGS ip6tables-mod-nat ip6tables-extra"
|
|
||||||
local UPD=0
|
case "$FWTYPE" in
|
||||||
|
iptables)
|
||||||
|
PKGS="ipset iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra"
|
||||||
|
[ "$DISABLE_IPV6" != "1" ] && PKGS="$PKGS ip6tables-mod-nat ip6tables-extra"
|
||||||
|
;;
|
||||||
|
nftables)
|
||||||
|
PKGS="nftables kmod-nft-nat kmod-nft-offload kmod-nft-queue"
|
||||||
|
[ "$DISABLE_IPV6" != "1" ] && PKGS="$PKGS kmod-nft-nat6"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
if check_packages_openwrt $PKGS ; then
|
if check_packages_openwrt $PKGS ; then
|
||||||
echo everything is present
|
echo everything is present
|
||||||
@ -1149,111 +806,11 @@ check_prerequisites_openwrt()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openwrt_fw_section_find()
|
|
||||||
{
|
|
||||||
# $1 - fw include postfix
|
|
||||||
# echoes section number
|
|
||||||
|
|
||||||
i=0
|
|
||||||
while true
|
|
||||||
do
|
|
||||||
path=$(uci -q get firewall.@include[$i].path)
|
|
||||||
[ -n "$path" ] || break
|
|
||||||
[ "$path" = "$OPENWRT_FW_INCLUDE$1" ] && {
|
|
||||||
echo $i
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
i=$(($i+1))
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
openwrt_fw_section_del()
|
|
||||||
{
|
|
||||||
# $1 - fw include postfix
|
|
||||||
|
|
||||||
local id=$(openwrt_fw_section_find $1)
|
|
||||||
[ -n "$id" ] && {
|
|
||||||
uci delete firewall.@include[$id] && uci commit firewall
|
|
||||||
rm -f "$OPENWRT_FW_INCLUDE$1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
openwrt_fw_section_add()
|
|
||||||
{
|
|
||||||
openwrt_fw_section_find ||
|
|
||||||
{
|
|
||||||
uci add firewall include >/dev/null || return
|
|
||||||
echo -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
openwrt_fw_section_configure()
|
|
||||||
{
|
|
||||||
local id=$(openwrt_fw_section_add $1)
|
|
||||||
[ -z "$id" ] ||
|
|
||||||
! uci set firewall.@include[$id].path="$OPENWRT_FW_INCLUDE" ||
|
|
||||||
! uci set firewall.@include[$id].reload="1" ||
|
|
||||||
! uci commit firewall &&
|
|
||||||
{
|
|
||||||
echo could not add firewall include
|
|
||||||
exitp 50
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
install_openwrt_firewall()
|
|
||||||
{
|
|
||||||
echo \* installing firewall script $1
|
|
||||||
|
|
||||||
[ -n "MODE" ] || {
|
|
||||||
echo should specify MODE in $ZAPRET_CONFIG
|
|
||||||
exitp 7
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "linking : $FW_SCRIPT_SRC => $OPENWRT_FW_INCLUDE"
|
|
||||||
ln -fs "$FW_SCRIPT_SRC" "$OPENWRT_FW_INCLUDE"
|
|
||||||
|
|
||||||
openwrt_fw_section_configure $1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
restart_openwrt_firewall()
|
|
||||||
{
|
|
||||||
echo \* restarting firewall
|
|
||||||
|
|
||||||
fw3 -q restart || {
|
|
||||||
echo could not restart firewall
|
|
||||||
exitp 30
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_openwrt_firewall()
|
|
||||||
{
|
|
||||||
echo \* removing firewall script
|
|
||||||
|
|
||||||
openwrt_fw_section_del
|
|
||||||
# from old zapret versions. now we use single include
|
|
||||||
openwrt_fw_section_del 6
|
|
||||||
|
|
||||||
# free some RAM
|
|
||||||
"$IPSET_DIR/create_ipset.sh" clear
|
|
||||||
}
|
|
||||||
|
|
||||||
install_openwrt_iface_hook()
|
|
||||||
{
|
|
||||||
echo \* installing ifup hook
|
|
||||||
|
|
||||||
ln -fs "$OPENWRT_IFACE_HOOK" /etc/hotplug.d/iface
|
|
||||||
}
|
|
||||||
|
|
||||||
is_flow_offload_avail()
|
|
||||||
{
|
|
||||||
# $1 = '' for ipv4, '6' for ipv6
|
|
||||||
grep -q FLOWOFFLOAD /proc/net/ip$1_tables_targets
|
|
||||||
}
|
|
||||||
|
|
||||||
deoffload_openwrt_firewall()
|
deoffload_openwrt_firewall()
|
||||||
{
|
{
|
||||||
echo \* checking flow offloading
|
echo \* checking flow offloading
|
||||||
|
|
||||||
is_flow_offload_avail || {
|
[ "$FWTYPE" = "nftables" ] || is_ipt_flow_offload_avail || {
|
||||||
echo unavailable
|
echo unavailable
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1262,7 +819,7 @@ deoffload_openwrt_firewall()
|
|||||||
|
|
||||||
if [ "$fo" = "1" ] ; then
|
if [ "$fo" = "1" ] ; then
|
||||||
local mod=0
|
local mod=0
|
||||||
$ECHON "system wide flow offloading detected. "
|
printf "system wide flow offloading detected. "
|
||||||
case $FLOWOFFLOAD in
|
case $FLOWOFFLOAD in
|
||||||
donttouch)
|
donttouch)
|
||||||
if [ "$MODE" = "nfqws" ]; then
|
if [ "$MODE" = "nfqws" ]; then
|
||||||
@ -1303,23 +860,31 @@ install_openwrt()
|
|||||||
check_location copy_openwrt
|
check_location copy_openwrt
|
||||||
install_binaries
|
install_binaries
|
||||||
check_dns
|
check_dns
|
||||||
|
|
||||||
|
echo \* stopping current firewall rules/daemons
|
||||||
|
"$INIT_SCRIPT_SRC" stop_fw
|
||||||
|
"$INIT_SCRIPT_SRC" stop_daemons
|
||||||
|
|
||||||
|
select_fwtype
|
||||||
select_ipv6
|
select_ipv6
|
||||||
check_prerequisites_openwrt
|
check_prerequisites_openwrt
|
||||||
ask_config
|
ask_config
|
||||||
ask_config_tmpdir
|
ask_config_tmpdir
|
||||||
ask_config_offload
|
ask_config_offload
|
||||||
|
# stop and reinstall sysv init
|
||||||
install_sysv_init
|
install_sysv_init
|
||||||
# can be previous firewall preventing access
|
|
||||||
remove_openwrt_firewall
|
remove_openwrt_firewall
|
||||||
restart_openwrt_firewall
|
# free some RAM
|
||||||
|
clear_ipset
|
||||||
download_list
|
download_list
|
||||||
crontab_del_quiet
|
crontab_del_quiet
|
||||||
# router system : works 24/7. night is the best time
|
# router system : works 24/7. night is the best time
|
||||||
crontab_add 0 6
|
crontab_add 0 6
|
||||||
cron_ensure_running
|
cron_ensure_running
|
||||||
service_start_sysv
|
|
||||||
install_openwrt_iface_hook
|
install_openwrt_iface_hook
|
||||||
install_openwrt_firewall
|
# in case of nftables or iptables without fw3 sysv init script also controls firewall
|
||||||
|
[ -n "$OPENWRT_FW3" -a "$FWTYPE" = iptables ] && install_openwrt_firewall
|
||||||
|
service_start_sysv
|
||||||
deoffload_openwrt_firewall
|
deoffload_openwrt_firewall
|
||||||
restart_openwrt_firewall
|
restart_openwrt_firewall
|
||||||
}
|
}
|
||||||
@ -1332,24 +897,7 @@ remove_pf_zapret_hooks()
|
|||||||
|
|
||||||
pf_anchors_clear
|
pf_anchors_clear
|
||||||
}
|
}
|
||||||
service_install_macos()
|
|
||||||
{
|
|
||||||
echo \* installing zapret service
|
|
||||||
|
|
||||||
ln -fs /opt/zapret/init.d/macos/zapret.plist /Library/LaunchDaemons
|
|
||||||
}
|
|
||||||
service_start_macos()
|
|
||||||
{
|
|
||||||
echo \* starting zapret service
|
|
||||||
|
|
||||||
"$INIT_SCRIPT_SRC" start
|
|
||||||
}
|
|
||||||
service_stop_macos()
|
|
||||||
{
|
|
||||||
echo \* stopping zapret service
|
|
||||||
|
|
||||||
"$INIT_SCRIPT_SRC" stop
|
|
||||||
}
|
|
||||||
macos_fw_reload_trigger_clear()
|
macos_fw_reload_trigger_clear()
|
||||||
{
|
{
|
||||||
case "$MODE" in
|
case "$MODE" in
|
||||||
|
@ -2,16 +2,23 @@
|
|||||||
|
|
||||||
# create ipset or ipfw table from resolved ip's
|
# create ipset or ipfw table from resolved ip's
|
||||||
# $1=no-update - do not update ipset, only create if its absent
|
# $1=no-update - do not update ipset, only create if its absent
|
||||||
|
# $1=clear - clear ipset
|
||||||
|
|
||||||
IPSET_DIR="$(dirname "$0")"
|
IPSET_DIR="$(dirname "$0")"
|
||||||
IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
||||||
|
|
||||||
. "$IPSET_DIR/def.sh"
|
. "$IPSET_DIR/def.sh"
|
||||||
|
. "$IPSET_DIR/../common/fwtype.sh"
|
||||||
|
. "$IPSET_DIR/../common/nft.sh"
|
||||||
|
|
||||||
IPSET_CMD="$TMPDIR/ipset_cmd.txt"
|
IPSET_CMD="$TMPDIR/ipset_cmd.txt"
|
||||||
IPSET_SAVERAM_CHUNK_SIZE=20000
|
IPSET_SAVERAM_CHUNK_SIZE=20000
|
||||||
IPSET_SAVERAM_MIN_FILESIZE=131072
|
IPSET_SAVERAM_MIN_FILESIZE=131072
|
||||||
|
|
||||||
|
NFSET_TEMP="$TMPDIR/nfset_temp.txt"
|
||||||
|
NFSET_SAVERAM_MIN_FILESIZE=16384
|
||||||
|
NFSET_SAVERAM_CHUNK_SIZE=1000
|
||||||
|
|
||||||
|
|
||||||
while [ -n "$1" ]; do
|
while [ -n "$1" ]; do
|
||||||
[ "$1" = "no-update" ] && NO_UPDATE=1
|
[ "$1" = "no-update" ] && NO_UPDATE=1
|
||||||
@ -22,180 +29,266 @@ done
|
|||||||
|
|
||||||
file_extract_lines()
|
file_extract_lines()
|
||||||
{
|
{
|
||||||
# $1 - filename
|
# $1 - filename
|
||||||
# $2 - from line (starting with 0)
|
# $2 - from line (starting with 0)
|
||||||
# $3 - line count
|
# $3 - line count
|
||||||
# awk "{ err=1 } NR < $(($2+1)) { next } { print; err=0 } NR == $(($2+$3)) { exit err } END {exit err}" "$1"
|
# awk "{ err=1 } NR < $(($2+1)) { next } { print; err=0 } NR == $(($2+$3)) { exit err } END {exit err}" "$1"
|
||||||
$AWK "NR < $(($2+1)) { next } { print } NR == $(($2+$3)) { exit }" "$1"
|
$AWK "NR < $(($2+1)) { next } { print } NR == $(($2+$3)) { exit }" "$1"
|
||||||
}
|
}
|
||||||
ipset_restore_chunked()
|
ipset_restore_chunked()
|
||||||
{
|
{
|
||||||
# $1 - filename
|
# $1 - filename
|
||||||
# $2 - chunk size
|
# $2 - chunk size
|
||||||
local pos lines
|
local pos lines
|
||||||
[ -f "$1" ] || return
|
[ -f "$1" ] || return
|
||||||
lines=$(wc -l <"$1")
|
lines=$(wc -l <"$1")
|
||||||
pos=$lines
|
pos=$lines
|
||||||
while [ "$pos" -gt "0" ]; do
|
while [ "$pos" -gt "0" ]; do
|
||||||
pos=$((pos-$2))
|
pos=$((pos-$2))
|
||||||
[ "$pos" -lt "0" ] && pos=0
|
[ "$pos" -lt "0" ] && pos=0
|
||||||
file_extract_lines "$1" $pos $2 | ipset -! restore
|
file_extract_lines "$1" $pos $2 | ipset -! restore
|
||||||
sed -i "$(($pos+1)),$ d" "$1"
|
sed -i "$(($pos+1)),$ d" "$1"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ipset_get_script()
|
ipset_get_script()
|
||||||
{
|
{
|
||||||
# $1 - filename
|
# $1 - filename
|
||||||
# $2 - ipset name
|
# $2 - ipset name
|
||||||
zzcat "$1" | sort -u | sed -nEe "s/^.+$/add $2 &/p"
|
zzcat "$1" | sort -u | sed -nEe "s/^.+$/add $2 &/p"
|
||||||
}
|
}
|
||||||
|
|
||||||
ipset_restore()
|
ipset_restore()
|
||||||
{
|
{
|
||||||
# $1 - filename
|
# $1 - ipset name
|
||||||
# $2 - ipset name
|
# $2 - filename
|
||||||
# $3 - "6" = ipv6
|
|
||||||
zzexist "$1" || return
|
|
||||||
local fsize=$(zzsize "$1")
|
|
||||||
local svram=0
|
|
||||||
# do not saveram small files. file can also be gzipped
|
|
||||||
[ "$SAVERAM" = "1" ] && [ "$fsize" -ge "$IPSET_SAVERAM_MIN_FILESIZE" ] && svram=1
|
|
||||||
|
|
||||||
local T="Adding to ipset $2 "
|
zzexist "$2" || return
|
||||||
[ "$svram" = "1" ] && T="$T (saveram)"
|
local fsize=$(zzsize "$2")
|
||||||
T="$T : $f"
|
local svram=0
|
||||||
echo $T
|
# do not saveram small files. file can also be gzipped
|
||||||
|
[ "$SAVERAM" = "1" ] && [ "$fsize" -ge "$IPSET_SAVERAM_MIN_FILESIZE" ] && svram=1
|
||||||
|
|
||||||
if [ "$svram" = "1" ]; then
|
local T="Adding to ipset $1 "
|
||||||
ipset_get_script "$1" "$2" >"$IPSET_CMD"
|
[ "$svram" = "1" ] && T="$T (saveram)"
|
||||||
ipset_restore_chunked "$IPSET_CMD" $IPSET_SAVERAM_CHUNK_SIZE
|
T="$T : $f"
|
||||||
rm -f "$IPSET_CMD"
|
echo $T
|
||||||
else
|
|
||||||
ipset_get_script "$1" "$2" | ipset -! restore
|
if [ "$svram" = "1" ]; then
|
||||||
fi
|
ipset_get_script "$2" "$1" >"$IPSET_CMD"
|
||||||
|
ipset_restore_chunked "$IPSET_CMD" $IPSET_SAVERAM_CHUNK_SIZE
|
||||||
|
rm -f "$IPSET_CMD"
|
||||||
|
else
|
||||||
|
ipset_get_script "$2" "$1" | ipset -! restore
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
create_ipset()
|
create_ipset()
|
||||||
{
|
{
|
||||||
if [ "$1" -eq "6" ]; then
|
if [ "$1" -eq "6" ]; then
|
||||||
FAMILY=inet6
|
FAMILY=inet6
|
||||||
else
|
else
|
||||||
FAMILY=inet
|
FAMILY=inet
|
||||||
fi
|
fi
|
||||||
ipset create $2 $3 $4 family $FAMILY 2>/dev/null || {
|
ipset create $2 $3 $4 family $FAMILY 2>/dev/null || {
|
||||||
[ "$NO_UPDATE" = "1" ] && return
|
[ "$NO_UPDATE" = "1" ] && return
|
||||||
}
|
}
|
||||||
ipset flush $2
|
ipset flush $2
|
||||||
[ "$DO_CLEAR" = "1" ] || {
|
[ "$DO_CLEAR" = "1" ] || {
|
||||||
for f in "$5" "$6" ; do
|
for f in "$5" "$6" ; do
|
||||||
ipset_restore "$f" "$2" $1
|
ipset_restore "$2" "$f"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfset_get_script_multi()
|
||||||
|
{
|
||||||
|
# $1 - set name
|
||||||
|
# $2,$3,... - filenames
|
||||||
|
|
||||||
|
# all in one shot. this allows to merge overlapping ranges
|
||||||
|
# good but eats lots of RAM
|
||||||
|
|
||||||
|
local set=$1 nonempty N=1 f
|
||||||
|
|
||||||
|
shift
|
||||||
|
|
||||||
|
# first we need to make sure at least one element exists or nft will fail
|
||||||
|
while :
|
||||||
|
do
|
||||||
|
eval f=\$$N
|
||||||
|
[ -n "$f" ] || break
|
||||||
|
nonempty=$(zzexist "$f" && zzcat "$f" | head -n 1)
|
||||||
|
[ -n "$nonempty" ] && break
|
||||||
|
N=$(($N+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
[ -n "$nonempty" ] && {
|
||||||
|
echo "add element inet $ZAPRET_NFT_TABLE $set {"
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
zzexist "$1" && zzcat "$1" | sed -nEe "s/^.+$/&,/p"
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
echo "}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nfset_restore()
|
||||||
|
{
|
||||||
|
# $1 - set name
|
||||||
|
# $2,$3,... - filenames
|
||||||
|
|
||||||
|
echo "Adding to nfset $1 : $2 $3 $4 $5"
|
||||||
|
nfset_get_script_multi "$@" | nft -f -
|
||||||
|
}
|
||||||
|
create_nfset()
|
||||||
|
{
|
||||||
|
# $1 - family
|
||||||
|
# $2 - set name
|
||||||
|
# $3 - maxelem
|
||||||
|
# $4,$5 - list files
|
||||||
|
|
||||||
|
local policy
|
||||||
|
[ $SAVERAM = "1" ] && policy="policy memory;"
|
||||||
|
nft_create_set $2 "type ipv${1}_addr; size $3; flags interval; auto-merge; $policy" || {
|
||||||
|
[ "$NO_UPDATE" = "1" ] && return
|
||||||
|
nft flush set inet $ZAPRET_NFT_TABLE $2
|
||||||
|
}
|
||||||
|
[ "$DO_CLEAR" = "1" ] || {
|
||||||
|
nfset_restore $2 $4 $5
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
add_ipfw_table()
|
add_ipfw_table()
|
||||||
{
|
{
|
||||||
# $1 - table name
|
# $1 - table name
|
||||||
sed -nEe "s/^.+$/table $1 add &/p" | ipfw -q /dev/stdin
|
sed -nEe "s/^.+$/table $1 add &/p" | ipfw -q /dev/stdin
|
||||||
}
|
}
|
||||||
populate_ipfw_table()
|
populate_ipfw_table()
|
||||||
{
|
{
|
||||||
# $1 - table name
|
# $1 - table name
|
||||||
# $2 - ip list file
|
# $2 - ip list file
|
||||||
zzexist "$2" || return
|
zzexist "$2" || return
|
||||||
zzcat "$2" | sort -u | add_ipfw_table $1
|
zzcat "$2" | sort -u | add_ipfw_table $1
|
||||||
}
|
}
|
||||||
create_ipfw_table()
|
create_ipfw_table()
|
||||||
{
|
{
|
||||||
# $1 - table name
|
# $1 - table name
|
||||||
# $2 - table options
|
# $2 - table options
|
||||||
# $3,$4, ... - ip list files. can be v4,v6 or mixed
|
# $3,$4, ... - ip list files. can be v4,v6 or mixed
|
||||||
|
|
||||||
local name=$1
|
local name=$1
|
||||||
ipfw table "$name" create $2 2>/dev/null || {
|
ipfw table "$name" create $2 2>/dev/null || {
|
||||||
[ "$NO_UPDATE" = "1" ] && return
|
[ "$NO_UPDATE" = "1" ] && return
|
||||||
}
|
}
|
||||||
ipfw -q table $1 flush
|
ipfw -q table $1 flush
|
||||||
shift
|
shift
|
||||||
shift
|
shift
|
||||||
[ "$DO_CLEAR" = "1" ] || {
|
[ "$DO_CLEAR" = "1" ] || {
|
||||||
while [ -n "$1" ]; do
|
while [ -n "$1" ]; do
|
||||||
populate_ipfw_table $name "$1"
|
echo "Adding to ipfw table $name : $1"
|
||||||
shift
|
populate_ipfw_table $name "$1"
|
||||||
done
|
shift
|
||||||
}
|
done
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print_reloading_backend()
|
print_reloading_backend()
|
||||||
{
|
{
|
||||||
# $1 - backend name
|
# $1 - backend name
|
||||||
local s="reloading $1 backend"
|
local s="reloading $1 backend"
|
||||||
if [ "$NO_UPDATE" = 1 ]; then
|
if [ "$NO_UPDATE" = 1 ]; then
|
||||||
s="$s (no-update)"
|
s="$s (no-update)"
|
||||||
else
|
elif [ "$DO_CLEAR" = 1 ]; then
|
||||||
s="$s (forced-update)"
|
s="$s (clear)"
|
||||||
fi
|
else
|
||||||
echo $s
|
s="$s (forced-update)"
|
||||||
|
fi
|
||||||
|
echo $s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
oom_adjust_high
|
oom_adjust_high
|
||||||
|
get_fwtype
|
||||||
|
|
||||||
if [ -n "$LISTS_RELOAD" ] ; then
|
if [ -n "$LISTS_RELOAD" ] ; then
|
||||||
if [ "$LISTS_RELOAD" = "-" ] ; then
|
if [ "$LISTS_RELOAD" = "-" ] ; then
|
||||||
echo not reloading ip list backend
|
echo not reloading ip list backend
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
echo executing custom ip list reload command : $LISTS_RELOAD
|
echo executing custom ip list reload command : $LISTS_RELOAD
|
||||||
$LISTS_RELOAD
|
$LISTS_RELOAD
|
||||||
fi
|
fi
|
||||||
elif exists ipset; then
|
|
||||||
# ipset seem to buffer the whole script to memory
|
|
||||||
# on low RAM system this can cause oom errors
|
|
||||||
# in SAVERAM mode we feed script lines in portions starting from the end, while truncating source file to free /tmp space
|
|
||||||
# only /tmp is considered tmpfs. other locations mean tmpdir was redirected to a disk
|
|
||||||
SAVERAM=0
|
|
||||||
[ "$TMPDIR" = "/tmp" ] && {
|
|
||||||
RAMSIZE=$($GREP MemTotal /proc/meminfo | $AWK '{print $2}')
|
|
||||||
[ "$RAMSIZE" -lt "110000" ] && SAVERAM=1
|
|
||||||
}
|
|
||||||
print_reloading_backend ipset
|
|
||||||
[ "$DISABLE_IPV4" != "1" ] && {
|
|
||||||
create_ipset 4 $ZIPSET hash:net "$IPSET_OPT" "$ZIPLIST" "$ZIPLIST_USER"
|
|
||||||
create_ipset 4 $ZIPSET_IPBAN hash:net "$IPSET_OPT" "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN"
|
|
||||||
create_ipset 4 $ZIPSET_EXCLUDE hash:net "$IPSET_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE"
|
|
||||||
}
|
|
||||||
[ "$DISABLE_IPV6" != "1" ] && {
|
|
||||||
create_ipset 6 $ZIPSET6 hash:net "$IPSET_OPT" "$ZIPLIST6" "$ZIPLIST_USER6"
|
|
||||||
create_ipset 6 $ZIPSET_IPBAN6 hash:net "$IPSET_OPT" "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6"
|
|
||||||
create_ipset 6 $ZIPSET_EXCLUDE6 hash:net "$IPSET_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE6"
|
|
||||||
}
|
|
||||||
true
|
|
||||||
elif exists ipfw; then
|
|
||||||
print_reloading_backend "ipfw table"
|
|
||||||
if [ "$DISABLE_IPV4" != "1" ] && [ "$DISABLE_IPV6" != "1" ]; then
|
|
||||||
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT" "$ZIPLIST" "$ZIPLIST_USER" "$ZIPLIST6" "$ZIPLIST_USER6"
|
|
||||||
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT" "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN" "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6"
|
|
||||||
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE" "$ZIPLIST_EXCLUDE6"
|
|
||||||
elif [ "$DISABLE_IPV4" != "1" ]; then
|
|
||||||
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT" "$ZIPLIST" "$ZIPLIST_USER"
|
|
||||||
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT" "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN"
|
|
||||||
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE"
|
|
||||||
elif [ "$DISABLE_IPV6" != "1" ]; then
|
|
||||||
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT" "$ZIPLIST6" "$ZIPLIST_USER6"
|
|
||||||
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT" "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6"
|
|
||||||
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE6"
|
|
||||||
else
|
|
||||||
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT"
|
|
||||||
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT"
|
|
||||||
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE"
|
|
||||||
fi
|
|
||||||
true
|
|
||||||
else
|
else
|
||||||
echo no supported ip list backend found
|
case "$FWTYPE" in
|
||||||
true
|
iptables)
|
||||||
|
# ipset seem to buffer the whole script to memory
|
||||||
|
# on low RAM system this can cause oom errors
|
||||||
|
# in SAVERAM mode we feed script lines in portions starting from the end, while truncating source file to free /tmp space
|
||||||
|
# only /tmp is considered tmpfs. other locations mean tmpdir was redirected to a disk
|
||||||
|
SAVERAM=0
|
||||||
|
[ "$TMPDIR" = "/tmp" ] && {
|
||||||
|
RAMSIZE=$($GREP MemTotal /proc/meminfo | $AWK '{print $2}')
|
||||||
|
[ "$RAMSIZE" -lt "110000" ] && SAVERAM=1
|
||||||
|
}
|
||||||
|
print_reloading_backend ipset
|
||||||
|
[ "$DISABLE_IPV4" != "1" ] && {
|
||||||
|
create_ipset 4 $ZIPSET hash:net "$IPSET_OPT" "$ZIPLIST" "$ZIPLIST_USER"
|
||||||
|
create_ipset 4 $ZIPSET_IPBAN hash:net "$IPSET_OPT" "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN"
|
||||||
|
create_ipset 4 $ZIPSET_EXCLUDE hash:net "$IPSET_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE"
|
||||||
|
}
|
||||||
|
[ "$DISABLE_IPV6" != "1" ] && {
|
||||||
|
create_ipset 6 $ZIPSET6 hash:net "$IPSET_OPT" "$ZIPLIST6" "$ZIPLIST_USER6"
|
||||||
|
create_ipset 6 $ZIPSET_IPBAN6 hash:net "$IPSET_OPT" "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6"
|
||||||
|
create_ipset 6 $ZIPSET_EXCLUDE6 hash:net "$IPSET_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE6"
|
||||||
|
}
|
||||||
|
true
|
||||||
|
;;
|
||||||
|
nftables)
|
||||||
|
nft_create_table && {
|
||||||
|
SAVERAM=0
|
||||||
|
RAMSIZE=$($GREP MemTotal /proc/meminfo | $AWK '{print $2}')
|
||||||
|
[ "$RAMSIZE" -lt "420000" ] && SAVERAM=1
|
||||||
|
print_reloading_backend "nftables set"
|
||||||
|
[ "$DISABLE_IPV4" != "1" ] && {
|
||||||
|
create_nfset 4 $ZIPSET $SET_MAXELEM "$ZIPLIST" "$ZIPLIST_USER"
|
||||||
|
create_nfset 4 $ZIPSET_IPBAN $SET_MAXELEM "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN"
|
||||||
|
create_nfset 4 $ZIPSET_EXCLUDE $SET_MAXELEM_EXCLUDE "$ZIPLIST_EXCLUDE"
|
||||||
|
}
|
||||||
|
[ "$DISABLE_IPV6" != "1" ] && {
|
||||||
|
create_nfset 6 $ZIPSET6 $SET_MAXELEM "$ZIPLIST6" "$ZIPLIST_USER6"
|
||||||
|
create_nfset 6 $ZIPSET_IPBAN6 $SET_MAXELEM "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6"
|
||||||
|
create_nfset 6 $ZIPSET_EXCLUDE6 $SET_MAXELEM_EXCLUDE "$ZIPLIST_EXCLUDE6"
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
ipfw)
|
||||||
|
print_reloading_backend "ipfw table"
|
||||||
|
if [ "$DISABLE_IPV4" != "1" ] && [ "$DISABLE_IPV6" != "1" ]; then
|
||||||
|
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT" "$ZIPLIST" "$ZIPLIST_USER" "$ZIPLIST6" "$ZIPLIST_USER6"
|
||||||
|
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT" "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN" "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6"
|
||||||
|
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE" "$ZIPLIST_EXCLUDE6"
|
||||||
|
elif [ "$DISABLE_IPV4" != "1" ]; then
|
||||||
|
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT" "$ZIPLIST" "$ZIPLIST_USER"
|
||||||
|
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT" "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN"
|
||||||
|
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE"
|
||||||
|
elif [ "$DISABLE_IPV6" != "1" ]; then
|
||||||
|
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT" "$ZIPLIST6" "$ZIPLIST_USER6"
|
||||||
|
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT" "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6"
|
||||||
|
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE" "$ZIPLIST_EXCLUDE6"
|
||||||
|
else
|
||||||
|
create_ipfw_table $ZIPSET "$IPFW_TABLE_OPT"
|
||||||
|
create_ipfw_table $ZIPSET_IPBAN "$IPFW_TABLE_OPT"
|
||||||
|
create_ipfw_table $ZIPSET_EXCLUDE "$IPFW_TABLE_OPT_EXCLUDE"
|
||||||
|
fi
|
||||||
|
true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo no supported ip list backend found
|
||||||
|
true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
24
ipset/def.sh
24
ipset/def.sh
@ -4,17 +4,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
. "$IPSET_DIR/../config"
|
. "$IPSET_DIR/../config"
|
||||||
|
. "$IPSET_DIR/../common/base.sh"
|
||||||
|
|
||||||
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
[ -z "$TMPDIR" ] && TMPDIR=/tmp
|
||||||
[ -z "$GZIP_LISTS" ] && GZIP_LISTS=1
|
[ -z "$GZIP_LISTS" ] && GZIP_LISTS=1
|
||||||
|
|
||||||
[ -z "$IPSET_OPT" ] && IPSET_OPT="hashsize 262144 maxelem 2097152"
|
[ -z "$SET_MAXELEM" ] && SET_MAXELEM=262144
|
||||||
[ -z "$IPSET_OPT_EXCLUDE" ] && IPSET_OPT_EXCLUDE="hashsize 1024 maxelem 65536"
|
[ -z "$IPSET_OPT" ] && IPSET_OPT="hashsize 262144 maxelem $SET_MAXELEM"
|
||||||
|
[ -z "$SET_MAXELEM_EXCLUDE" ] && SET_MAXELEM_EXCLUDE=65536
|
||||||
|
[ -z "$IPSET_OPT_EXCLUDE" ] && IPSET_OPT_EXCLUDE="hashsize 1024 maxelem $SET_MAXELEM_EXCLUDE"
|
||||||
|
|
||||||
[ -z "$IPFW_TABLE_OPT" ] && IPFW_TABLE_OPT="algo addr:radix"
|
[ -z "$IPFW_TABLE_OPT" ] && IPFW_TABLE_OPT="algo addr:radix"
|
||||||
[ -z "$IPFW_TABLE_OPT_EXCLUDE" ] && IPFW_TABLE_OPT_EXCLUDE="algo addr:radix"
|
[ -z "$IPFW_TABLE_OPT_EXCLUDE" ] && IPFW_TABLE_OPT_EXCLUDE="algo addr:radix"
|
||||||
|
|
||||||
|
|
||||||
ZIPSET=zapret
|
ZIPSET=zapret
|
||||||
ZIPSET6=zapret6
|
ZIPSET6=zapret6
|
||||||
ZIPSET_EXCLUDE=nozapret
|
ZIPSET_EXCLUDE=nozapret
|
||||||
@ -43,10 +45,6 @@ ZUSERLIST_EXCLUDE="$IPSET_DIR/zapret-hosts-user-exclude.txt"
|
|||||||
[ -z "$MDIG_THREADS" ] && MDIG_THREADS=30
|
[ -z "$MDIG_THREADS" ] && MDIG_THREADS=30
|
||||||
|
|
||||||
|
|
||||||
exists()
|
|
||||||
{
|
|
||||||
which "$1" >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# BSD grep is damn slow with -f option. prefer GNU grep (ggrep) if present
|
# BSD grep is damn slow with -f option. prefer GNU grep (ggrep) if present
|
||||||
# MacoS in cron does not include /usr/local/bin to PATH
|
# MacoS in cron does not include /usr/local/bin to PATH
|
||||||
@ -55,9 +53,9 @@ if [ -x /usr/local/bin/ggrep ] ; then
|
|||||||
elif [ -x /usr/local/bin/grep ] ; then
|
elif [ -x /usr/local/bin/grep ] ; then
|
||||||
GREP=/usr/local/bin/grep
|
GREP=/usr/local/bin/grep
|
||||||
elif exists ggrep; then
|
elif exists ggrep; then
|
||||||
GREP=$(which ggrep)
|
GREP=$(whichq ggrep)
|
||||||
else
|
else
|
||||||
GREP=$(which grep)
|
GREP=$(whichq grep)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# GNU awk is faster
|
# GNU awk is faster
|
||||||
@ -109,7 +107,7 @@ zzcat()
|
|||||||
{
|
{
|
||||||
if [ -f "$1.gz" ]; then
|
if [ -f "$1.gz" ]; then
|
||||||
gunzip -c "$1.gz"
|
gunzip -c "$1.gz"
|
||||||
else
|
elif [ -f "$1" ]; then
|
||||||
cat "$1"
|
cat "$1"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -127,7 +125,11 @@ zzsize()
|
|||||||
{
|
{
|
||||||
local f="$1"
|
local f="$1"
|
||||||
[ -f "$1.gz" ] && f="$1.gz"
|
[ -f "$1.gz" ] && f="$1.gz"
|
||||||
wc -c <"$f" | xargs
|
if [ -f "$f" ]; then
|
||||||
|
wc -c <"$f" | xargs
|
||||||
|
else
|
||||||
|
$ECHON -n 0
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
digger()
|
digger()
|
||||||
|
@ -5,173 +5,46 @@
|
|||||||
EXEDIR="$(dirname "$0")"
|
EXEDIR="$(dirname "$0")"
|
||||||
EXEDIR="$(cd "$EXEDIR"; pwd)"
|
EXEDIR="$(cd "$EXEDIR"; pwd)"
|
||||||
IPSET_DIR="$EXEDIR/ipset"
|
IPSET_DIR="$EXEDIR/ipset"
|
||||||
|
ZAPRET_CONFIG="$EXEDIR/config"
|
||||||
|
ZAPRET_BASE="$EXEDIR"
|
||||||
|
|
||||||
GET_LIST_PREFIX=/ipset/get_
|
. "$ZAPRET_CONFIG"
|
||||||
|
. "$ZAPRET_BASE/common/base.sh"
|
||||||
SYSTEMD_DIR=/lib/systemd
|
. "$ZAPRET_BASE/common/elevate.sh"
|
||||||
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
|
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||||
[ -d "$SYSTEMD_DIR" ] && SYSTEMD_SYSTEM_DIR="$SYSTEMD_DIR/system"
|
. "$ZAPRET_BASE/common/ipt.sh"
|
||||||
|
. "$ZAPRET_BASE/common/nft.sh"
|
||||||
INIT_SCRIPT=/etc/init.d/zapret
|
. "$ZAPRET_BASE/common/pf.sh"
|
||||||
|
. "$ZAPRET_BASE/common/installer.sh"
|
||||||
exists()
|
|
||||||
{
|
|
||||||
which $1 >/dev/null 2>/dev/null
|
|
||||||
}
|
|
||||||
whichq()
|
|
||||||
{
|
|
||||||
which $1 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
exitp()
|
|
||||||
{
|
|
||||||
echo
|
|
||||||
echo press enter to continue
|
|
||||||
read A
|
|
||||||
exit $1
|
|
||||||
}
|
|
||||||
|
|
||||||
require_root()
|
|
||||||
{
|
|
||||||
local exe
|
|
||||||
echo \* checking privileges
|
|
||||||
[ $(id -u) -ne "0" ] && {
|
|
||||||
echo root is required
|
|
||||||
exe="$EXEDIR/$(basename "$0")"
|
|
||||||
exists sudo && exec sudo "$exe"
|
|
||||||
exists su && exec su root -c "$exe"
|
|
||||||
echo su or sudo not found
|
|
||||||
exitp 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
check_system()
|
|
||||||
{
|
|
||||||
echo \* checking system
|
|
||||||
|
|
||||||
SYSTEM=""
|
|
||||||
SYSTEMCTL=$(whichq systemctl)
|
|
||||||
|
|
||||||
local UNAME=$(uname)
|
|
||||||
if [ "$UNAME" = "Linux" ]; then
|
|
||||||
# do not use 'exe' because it requires root
|
|
||||||
local INIT=$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)
|
|
||||||
[ -L "$INIT" ] && INIT=$(readlink "$INIT")
|
|
||||||
INIT=$(basename "$INIT")
|
|
||||||
# some distros include systemctl without systemd
|
|
||||||
if [ -d "$SYSTEMD_DIR" ] && [ -x "$SYSTEMCTL" ] && [ "$INIT" = "systemd" ]; then
|
|
||||||
SYSTEM=systemd
|
|
||||||
elif exists rc-update && [ "$INIT" = "openrc-init" ]; then
|
|
||||||
SYSTEM=openrc
|
|
||||||
elif [ -f "/etc/openwrt_release" ] && exists opkg && exists uci && [ "$INIT" = "procd" ] ; then
|
|
||||||
SYSTEM=openwrt
|
|
||||||
else
|
|
||||||
echo system is not either systemd, openrc or openwrt based
|
|
||||||
echo check readme.txt for manual setup info.
|
|
||||||
SYSTEM=linux
|
|
||||||
fi
|
|
||||||
elif [ "$UNAME" = "Darwin" ]; then
|
|
||||||
SYSTEM=macos
|
|
||||||
# MacOS echo from /bin/sh does not support -n
|
|
||||||
ECHON=printf
|
|
||||||
else
|
|
||||||
echo easy installer only supports Linux and MacOS. check readme.txt for supported systems and manual setup info.
|
|
||||||
exitp 5
|
|
||||||
fi
|
|
||||||
echo system is based on $SYSTEM
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
crontab_del()
|
|
||||||
{
|
|
||||||
exists crontab || return
|
|
||||||
|
|
||||||
echo \* removing crontab entry
|
|
||||||
|
|
||||||
CRONTMP=/tmp/cron.tmp
|
|
||||||
crontab -l >$CRONTMP 2>/dev/null
|
|
||||||
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
|
|
||||||
echo removing following entries from crontab :
|
|
||||||
grep "$GET_LIST_PREFIX" $CRONTMP
|
|
||||||
grep -v "$GET_LIST_PREFIX" $CRONTMP >$CRONTMP.2
|
|
||||||
crontab $CRONTMP.2
|
|
||||||
rm -f $CRONTMP.2
|
|
||||||
fi
|
|
||||||
rm -f $CRONTMP
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
service_stop_systemd()
|
|
||||||
{
|
|
||||||
echo \* stopping zapret service
|
|
||||||
|
|
||||||
"$SYSTEMCTL" daemon-reload
|
|
||||||
"$SYSTEMCTL" disable zapret
|
|
||||||
"$SYSTEMCTL" stop zapret
|
|
||||||
}
|
|
||||||
|
|
||||||
service_remove_systemd()
|
|
||||||
{
|
|
||||||
echo \* removing zapret service
|
|
||||||
|
|
||||||
rm -f "$SYSTEMD_SYSTEM_DIR/zapret.service"
|
|
||||||
"$SYSTEMCTL" daemon-reload
|
|
||||||
}
|
|
||||||
|
|
||||||
timer_remove_systemd()
|
|
||||||
{
|
|
||||||
echo \* removing zapret-list-update timer
|
|
||||||
|
|
||||||
"$SYSTEMCTL" daemon-reload
|
|
||||||
"$SYSTEMCTL" disable zapret-list-update.timer
|
|
||||||
"$SYSTEMCTL" stop zapret-list-update.timer
|
|
||||||
rm -f "$SYSTEMD_SYSTEM_DIR/zapret-list-update.service" "$SYSTEMD_SYSTEM_DIR/zapret-list-update.timer"
|
|
||||||
"$SYSTEMCTL" daemon-reload
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
remove_systemd()
|
remove_systemd()
|
||||||
{
|
{
|
||||||
|
clear_ipset
|
||||||
service_stop_systemd
|
service_stop_systemd
|
||||||
service_remove_systemd
|
service_remove_systemd
|
||||||
timer_remove_systemd
|
timer_remove_systemd
|
||||||
|
nft_del_table
|
||||||
crontab_del
|
crontab_del
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
service_remove_sysv()
|
|
||||||
{
|
|
||||||
echo \* removing zapret service
|
|
||||||
|
|
||||||
[ -x "$INIT_SCRIPT" ] && {
|
|
||||||
"$INIT_SCRIPT" disable
|
|
||||||
"$INIT_SCRIPT" stop
|
|
||||||
}
|
|
||||||
rm -f "$INIT_SCRIPT"
|
|
||||||
}
|
|
||||||
|
|
||||||
service_remove_openrc()
|
|
||||||
{
|
|
||||||
echo \* removing zapret service
|
|
||||||
|
|
||||||
[ -x "$INIT_SCRIPT" ] && {
|
|
||||||
rc-update del zapret
|
|
||||||
"$INIT_SCRIPT" stop
|
|
||||||
}
|
|
||||||
rm -f "$INIT_SCRIPT"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
remove_openrc()
|
remove_openrc()
|
||||||
{
|
{
|
||||||
|
clear_ipset
|
||||||
service_remove_openrc
|
service_remove_openrc
|
||||||
|
nft_del_table
|
||||||
crontab_del
|
crontab_del
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_linux()
|
remove_linux()
|
||||||
{
|
{
|
||||||
|
INIT_SCRIPT_SRC="$EXEDIR/init.d/sysv/zapret"
|
||||||
|
|
||||||
|
clear_ipset
|
||||||
|
|
||||||
|
echo \* executing sysv init stop
|
||||||
|
"$INIT_SCRIPT_SRC" stop
|
||||||
|
|
||||||
|
nft_del_table
|
||||||
crontab_del
|
crontab_del
|
||||||
|
|
||||||
echo
|
echo
|
||||||
@ -179,97 +52,19 @@ remove_linux()
|
|||||||
echo 'you must manually remove zapret auto start from your system'
|
echo 'you must manually remove zapret auto start from your system'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
openwrt_fw_section_find()
|
|
||||||
{
|
|
||||||
# $1 - fw include postfix
|
|
||||||
# echoes section number
|
|
||||||
|
|
||||||
i=0
|
|
||||||
while true
|
|
||||||
do
|
|
||||||
path=$(uci -q get firewall.@include[$i].path)
|
|
||||||
[ -n "$path" ] || break
|
|
||||||
[ "$path" = "$OPENWRT_FW_INCLUDE$1" ] && {
|
|
||||||
echo $i
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
i=$(($i+1))
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
openwrt_fw_section_del()
|
|
||||||
{
|
|
||||||
# $1 - fw include postfix
|
|
||||||
|
|
||||||
local id=$(openwrt_fw_section_find $1)
|
|
||||||
[ -n "$id" ] && {
|
|
||||||
uci delete firewall.@include[$id] && uci commit firewall
|
|
||||||
rm -f "$OPENWRT_FW_INCLUDE$1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_openwrt_firewall()
|
|
||||||
{
|
|
||||||
echo \* removing firewall script
|
|
||||||
|
|
||||||
openwrt_fw_section_del
|
|
||||||
# from old zapret versions. now we use single include
|
|
||||||
openwrt_fw_section_del 6
|
|
||||||
|
|
||||||
# free some RAM
|
|
||||||
"$IPSET_DIR/create_ipset.sh" clear
|
|
||||||
}
|
|
||||||
|
|
||||||
restart_openwrt_firewall()
|
|
||||||
{
|
|
||||||
echo \* restarting firewall
|
|
||||||
|
|
||||||
fw3 -q restart || {
|
|
||||||
echo could not restart firewall
|
|
||||||
exitp 30
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_openwrt_iface_hook()
|
|
||||||
{
|
|
||||||
echo \* removing ifup hook
|
|
||||||
|
|
||||||
rm -f /etc/hotplug.d/iface/??-zapret
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
remove_openwrt()
|
remove_openwrt()
|
||||||
{
|
{
|
||||||
OPENWRT_FW_INCLUDE=/etc/firewall.zapret
|
OPENWRT_FW_INCLUDE=/etc/firewall.zapret
|
||||||
|
|
||||||
remove_openwrt_firewall
|
clear_ipset
|
||||||
restart_openwrt_firewall
|
|
||||||
service_remove_sysv
|
service_remove_sysv
|
||||||
|
remove_openwrt_firewall
|
||||||
remove_openwrt_iface_hook
|
remove_openwrt_iface_hook
|
||||||
|
nft_del_table
|
||||||
|
restart_openwrt_firewall
|
||||||
crontab_del
|
crontab_del
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
service_remove_macos()
|
|
||||||
{
|
|
||||||
echo \* removing zapret service
|
|
||||||
|
|
||||||
rm -f /Library/LaunchDaemons/zapret.plist
|
|
||||||
zapret_stop_daemons
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_macos_firewall()
|
|
||||||
{
|
|
||||||
echo \* removing zapret PF hooks
|
|
||||||
|
|
||||||
pf_anchors_clear
|
|
||||||
pf_anchors_del
|
|
||||||
pf_anchor_root_del
|
|
||||||
pf_anchor_root_reload
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_macos()
|
remove_macos()
|
||||||
{
|
{
|
||||||
remove_macos_firewall
|
remove_macos_firewall
|
||||||
|
Loading…
Reference in New Issue
Block a user