major config re-think and re-write

This commit is contained in:
bol-van 2024-10-25 14:29:47 +03:00
parent d86aa42f48
commit 906e67af55
39 changed files with 963 additions and 1340 deletions

View File

@ -62,6 +62,10 @@ starts_with()
} }
find_str_in_list() find_str_in_list()
{ {
# $1 - string
# $2 - space separated values
local v
[ -n "$1" ] && { [ -n "$1" ] && {
for v in $2; do for v in $2; do
[ "$v" = "$1" ] && return 0 [ "$v" = "$1" ] && return 0
@ -74,6 +78,19 @@ end_with_newline()
local c="$(tail -c 1)" local c="$(tail -c 1)"
[ "$c" = "" ] [ "$c" = "" ]
} }
trim()
{
awk '{gsub(/^ +| +$/,"")}1'
}
dir_is_not_empty()
{
# $1 - directory
local n
[ -d "$1" ] || return 1
n=$(ls "$1" | wc -c | xargs)
[ "$n" != 0 ]
}
append_separator_list() append_separator_list()
{ {
@ -275,6 +292,14 @@ replace_char()
echo "$@" | tr $a $b echo "$@" | tr $a $b
} }
replace_str()
{
local a=$(echo "$1" | sed 's/\//\\\//g')
local b=$(echo "$2" | sed 's/\//\\\//g')
shift; shift
echo "$@" | sed "s/$a/$b/g"
}
setup_md5() setup_md5()
{ {
[ -n "$MD5" ] && return [ -n "$MD5" ] && return
@ -350,10 +375,41 @@ alloc_num()
std_ports() std_ports()
{ {
HTTP_PORTS=${HTTP_PORTS:-80} TPWS_PORTS_IPT=$(replace_char - : $TPWS_PORTS)
HTTPS_PORTS=${HTTPS_PORTS:-443} NFQWS_PORTS_TCP_IPT=$(replace_char - : $NFQWS_PORTS_TCP)
QUIC_PORTS=${QUIC_PORTS:-443} NFQWS_PORTS_TCP_KEEPALIVE_IPT=$(replace_char - : $NFQWS_PORTS_TCP_KEEPALIVE)
HTTP_PORTS_IPT=$(replace_char - : $HTTP_PORTS) NFQWS_PORTS_UDP_IPT=$(replace_char - : $NFQWS_PORTS_UDP)
HTTPS_PORTS_IPT=$(replace_char - : $HTTPS_PORTS) NFQWS_PORTS_UDP_KEEPALIVE_IPT=$(replace_char - : $NFQWS_PORTS_UDP_KEEPALIVE)
QUIC_PORTS_IPT=$(replace_char - : $QUIC_PORTS) }
has_bad_ws_options()
{
# $1 - nfqws/tpws opts
# ÏÐÈÌÅ×ÀÍÈÅ ÄËß ÐÀÑÏÐÎÑÒÐÀÍÈÒÅËÅÉ ÊÎÏÈÏÀÑÒÛ
# ÝÒÎÒ ÊÎÄ ÑÄÅËÀÍ ÑÏÅÖÈÀËÜÍÎ ÄËß ÂÀÑ, ×ÒÎÁÛ ÂÛ ÍÅ ÏÎÑÒÈËÈ Â ÑÅÒÜ ÏËÎÕÈÅ ÐÅÖÅÏÒÛ
# ÅÑËÈ ÂÀÌ ÕÎ×ÅÒÑß ÅÃÎ ÓÄÀËÈÒÜ È ÍÀÏÈÑÀÒÜ ÈÍÑÒÐÓÊÖÈÞ ÊÀÊ ÅÃÎ ÓÄÀËßÒÜ, ÂÛ ÄÅËÀÅÒÅ ÕÐÅÍÎÂÓÞ ÓÑËÓÃÓ. ÍÀÏÈØÈÒÅ ËÓ×ØÅ custom script.
# custom script - ÝÒÎ ÔÀÉËÈÊ, ÊÎÒÎÐÛÉ ÄÎÑÒÀÒÎ×ÍÎ ÑÊÎÏÈÐÎÂÀÒÜ Â ÍÓÆÍÓÞ ÄÈÐÅÊÒÎÐÈÞ, ×ÒÎÁÛ ÎÍ ÑÄÅËÀË ÒÎÆÅ ÑÀÌÎÅ, ÍÎ ÝÔÔÅÊÒÈÂÍÎ.
# ÔÈËÜÒÐÀÖÈß ÏÎ IPSET  ßÄÐÅ ÍÅÑÐÀÂÍÈÌÎ ÝÔÔÅÊÒÈÂÍÅÅ, ×ÅÌ ÏÅÐÅÊÈÄÛÂÀÒÜ ÂÑÅ ÏÀÊÅÒÛ Â nfqws È ÒÀÌ ÔÈËÜÒÐÎÂÀÒÜ
# --ipset ÑÓÙÅÑÒÂÓÅÒ ÒÎËÜÊÎ ÄËß ÂÈÍÄÛ È LINUX ÑÈÑÒÅÌ ÁÅÇ ipset (ÍÀÏÐÈÌÅÐ, Android).
# È ÒÎËÜÊÎ ÏÎ ÝÒÎÉ ÏÐÈ×ÈÍÅ ÎÍÎ ÍÅ ÂÛÊÈÍÓÒÎ ÏÎËÍÎÑÒÜÞ ÈÇ LINUX ÂÅÐÑÈÈ
contains "$1" "--ipset"
}
check_bad_ws_options()
{
# $1 - 0 = stop, 1 = start
# $2 - nfqws/tpws options
if [ "$1" = 1 ] && has_bad_ws_options "$2"; then
echo "!!! REFUSING TO USE BAD OPTIONS : $2"
return 1
else
return 0
fi
}
help_bad_ws_options()
{
echo "WARNING ! you have specified --ipset option"
echo "WARNING ! it would work but on $UNAME it's not the best option"
echo "WARNING ! you should use kernel mode sets. they are much more efficient."
echo "WARNING ! to use ipsets you have to write your own custom script"
echo "WARNING ! installer will stop here to prevent distribution of easy to use but bad copy-paste solutions"
} }

View File

@ -7,14 +7,8 @@ custom_runner()
shift shift
[ -f "$CUSTOM_DIR/custom" ] && {
unset -f $FUNC
. "$CUSTOM_DIR/custom"
existf $FUNC && $FUNC "$@"
}
[ -d "$CUSTOM_DIR/custom.d" ] && { [ -d "$CUSTOM_DIR/custom.d" ] && {
n=$(ls "$CUSTOM_DIR/custom.d" | wc -c | xargs) dir_is_not_empty "$CUSTOM_DIR/custom.d" && {
[ "$n" = 0 ] || {
for script in "$CUSTOM_DIR/custom.d/"*; do for script in "$CUSTOM_DIR/custom.d/"*; do
[ -f "$script" ] || continue [ -f "$script" ] || continue
unset -f $FUNC unset -f $FUNC

View File

@ -1,4 +1,4 @@
GET_LIST_PREFIX=/ipset/get_ readonly GET_LIST_PREFIX=/ipset/get_
SYSTEMD_DIR=/lib/systemd SYSTEMD_DIR=/lib/systemd
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd [ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
@ -15,13 +15,99 @@ exitp()
exit $1 exit $1
} }
extract_var_def()
{
# $1 - var name
# this sed script parses single or multi line shell var assignments with optional ' or " enclosure
sed -n \
"/^$1=\"/ {
:s1
/\".*\"/ {
p
b
}
N
t c1
b s1
:c1
}
/^$1='/ {
:s2
/'.*'/ {
p
b
}
N
t c2
b s2
:c2
}
/^$1=/p
"
}
replace_var_def()
{
# $1 - var name
# $2 - new val
# $3 - conf file
# this sed script replaces single or multi line shell var assignments with optional ' or " enclosure
local repl
if [ -z "$2" ]; then
repl="#$1="
elif contains "$2" " "; then
repl="$1=\"$2\""
else
repl="$1=$2"
fi
local script=\
"/^#*[[:space:]]*$1=\"/ {
:s1
/\".*\"/ {
c\\
$repl
b
}
N
t c1
b s1
:c1
}
/^#*[[:space:]]*$1='/ {
:s2
/'.*'/ {
c\\
$repl
b
}
N
t c2
b s2
:c2
}
/^#*[[:space:]]*$1=/c\\
$repl"
# there's incompatibility with -i option on MacOS/BSD and busybox/GNU
if [ "$UNAME" = "Linux" ]; then
sed -i -e "$script" "$3"
else
sed -i '' -e "$script" "$3"
fi
}
parse_var_checked() parse_var_checked()
{ {
# $1 - file name # $1 - file name
# $2 - var name # $2 - var name
local sed="sed -nre s/^[[:space:]]*$2=[\\\"|\']?([^\\\"|\']*)[\\\"|\']?/\1/p"
local v="$($sed <"$1" | tail -n 1)" local tmp="/tmp/zvar-pid-$$.sh"
eval $2=\"$v\" local v
cat "$1" | extract_var_def "$2" >"$tmp"
. "$tmp"
rm -f "$tmp"
eval v="\$$2"
# trim
v="$(echo "$v" | trim)"
eval $2=\""$v"\"
} }
parse_vars_checked() parse_vars_checked()
{ {
@ -48,22 +134,44 @@ edit_file()
} }
[ -n "$ed" ] && "$ed" "$1" [ -n "$ed" ] && "$ed" "$1"
} }
echo_var()
{
local v
eval v="\$$1"
if find_str_in_list $1 "$EDITVAR_NEWLINE_VARS"; then
echo "$1=\""
echo "$v\"" | sed "s/$EDITVAR_NEWLINE_DELIMETER /$EDITVAR_NEWLINE_DELIMETER\n/g"
else
if contains "$v" " "; then
echo $1=\"$v\"
else
echo $1=$v
fi
fi
}
edit_vars() edit_vars()
{ {
# $1,$2,... - var names # $1,$2,... - var names
local n=1 var v tmp="/tmp/zvars" local n=1 var tmp="/tmp/zvars-pid-$$.txt"
rm -f "$tmp" rm -f "$tmp"
while [ 1=1 ]; do while : ; do
eval var="\${$n}" eval var="\${$n}"
[ -n "$var" ] || break [ -n "$var" ] || break
eval v="\$$var" echo_var $var >> "$tmp"
echo $var=\"$v\" >>"$tmp"
n=$(($n+1)) n=$(($n+1))
done done
edit_file "$tmp" && parse_vars_checked "$tmp" "$@" edit_file "$tmp" && parse_vars_checked "$tmp" "$@"
rm -f "$tmp" rm -f "$tmp"
} }
list_vars()
{
while [ -n "$1" ] ; do
echo_var $1
shift
done
}
openrc_test() openrc_test()
{ {
exists rc-update || return 1 exists rc-update || return 1
@ -483,30 +591,14 @@ write_config_var()
# $1 - mode var # $1 - mode var
local M local M
eval M="\$$1" eval M="\$$1"
if grep -q "^$1=\|^#$1=" "$ZAPRET_CONFIG"; then
# replace / => \/ # replace / => \/
#M=${M//\//\\\/} #M=${M//\//\\\/}
M=$(echo $M | sed 's/\//\\\//g') M=$(echo $M | sed 's/\//\\\//g' | trim)
if [ -n "$M" ]; then grep -q "^[[:space:]]*$1=\|^#*[[:space:]]*$1=" "$ZAPRET_CONFIG" || {
if contains "$M" " "; then
sedi -Ee "s/^#?$1=.*$/$1=\"$M\"/" "$ZAPRET_CONFIG"
else
sedi -Ee "s/^#?$1=.*$/$1=$M/" "$ZAPRET_CONFIG"
fi
else
# write with comment at the beginning
sedi -Ee "s/^#?$1=.*$/#$1=/" "$ZAPRET_CONFIG"
fi
else
# var does not exist in config. add it # var does not exist in config. add it
contains "$M" " " && M="\"$M\"" echo $1= >>"$ZAPRET_CONFIG"
if [ -n "$M" ]; then }
echo "$1=$M" >>"$ZAPRET_CONFIG" replace_var_def $1 "$M" "$ZAPRET_CONFIG"
else
echo "#$1=$M" >>"$ZAPRET_CONFIG"
fi
fi
} }
check_prerequisites_linux() check_prerequisites_linux()

View File

@ -48,28 +48,6 @@ is_ipt_flow_offload_avail()
grep -q FLOWOFFLOAD 2>/dev/null /proc/net/ip$1_tables_targets 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="-p tcp -m multiport --dports $HTTP_PORTS_IPT,$HTTPS_PORTS_IPT"
elif [ "$MODE_HTTPS" = "1" ]; then
f="-p tcp -m multiport --dports $HTTPS_PORTS_IPT"
elif [ "$MODE_HTTP" = "1" ]; then
f="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
else
echo WARNING !!! HTTP and HTTPS are both disabled
fi
eval $1="\"\$$1 $f\""
}
filter_apply_port_target_quic()
{
# $1 - var name of nftables filter
local f
f="-p udp -m multiport --dports $QUIC_PORTS_IPT"
eval $1="\"\$$1 $f\""
}
filter_apply_ipset_target4() filter_apply_ipset_target4()
{ {
# $1 - var name of ipv4 iptables filter # $1 - var name of ipv4 iptables filter
@ -220,7 +198,7 @@ _fw_nfqws_post4()
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)"
rule="$2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass" rule="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass"
if [ -n "$4" ] ; then if [ -n "$4" ] ; then
for i in $4; do for i in $4; do
ipt_add_del $1 POSTROUTING -t mangle -o $i $rule ipt_add_del $1 POSTROUTING -t mangle -o $i $rule
@ -241,7 +219,7 @@ _fw_nfqws_post6()
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" 6 ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" 6
rule="$2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass" rule="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass"
if [ -n "$4" ] ; then if [ -n "$4" ] ; then
for i in $4; do for i in $4; do
ipt6_add_del $1 POSTROUTING -t mangle -o $i $rule ipt6_add_del $1 POSTROUTING -t mangle -o $i $rule
@ -320,27 +298,13 @@ fw_nfqws_pre()
} }
produce_reverse_nfqws_rule()
{
local rule="$1"
if contains "$rule" "$ipt_connbytes"; then
# autohostlist - need several incoming packets
# autottl - need only one incoming packet
[ "$MODE_FILTER" = autohostlist ] || rule=$(echo "$rule" | sed -re "s/$ipt_connbytes [0-9]+:[0-9]+/$ipt_connbytes 1:1/")
else
local n=1
[ "$MODE_FILTER" = autohostlist ] && n=$(first_packets_for_mode)
rule="$ipt_connbytes 1:$n $rule"
fi
echo "$rule" | reverse_nfqws_rule_stream
}
fw_reverse_nfqws_rule4() fw_reverse_nfqws_rule4()
{ {
fw_nfqws_pre4 $1 "$(produce_reverse_nfqws_rule "$2")" $3 fw_nfqws_pre4 $1 "$(reverse_nfqws_rule "$2")" $3
} }
fw_reverse_nfqws_rule6() fw_reverse_nfqws_rule6()
{ {
fw_nfqws_pre6 $1 "$(produce_reverse_nfqws_rule "$2")" $3 fw_nfqws_pre6 $1 "$(reverse_nfqws_rule "$2")" $3
} }
fw_reverse_nfqws_rule() fw_reverse_nfqws_rule()
{ {
@ -353,93 +317,66 @@ fw_reverse_nfqws_rule()
fw_reverse_nfqws_rule6 $1 "$3" $4 fw_reverse_nfqws_rule6 $1 "$3" $4
} }
ipt_first_packets()
zapret_do_firewall_rules_ipt()
{ {
local mode="${MODE_OVERRIDE:-$MODE}" # $1 - packet count
[ -n "$1" -a "$1" != keepalive ] && [ "$1" -ge 1 ] && echo "$ipt_connbytes 1:$1"
}
ipt_do_nfqws_in_out()
{
# $1 - 1 - add, 0 - del
# $2 - tcp,udp
# $3 - ports
# $4 - PKT_OUT. special value : 'keepalive'
# $5 - PKT_IN
local f4 f6 first_packets_only
[ -n "$3" ] || return
[ -n "$4" -a "$4" != 0 ] &&
{
first_packets_only="$(ipt_first_packets $4)"
f4="-p $2 -m multiport --dports $3 $first_packets_only"
f6=$f4
filter_apply_ipset_target f4 f6
fw_nfqws_post $1 "$f4" "$f6" $QNUM
}
[ -n "$5" -a "$5" != 0 ] &&
{
first_packets_only="$(ipt_first_packets $5)"
f4="-p $2 -m multiport --dports $3 $first_packets_only"
f6=$f4
filter_apply_ipset_target f4 f6
fw_reverse_nfqws_rule $1 "$f4" "$f6" $QNUM
}
}
local first_packet_only="$ipt_connbytes 1:$(first_packets_for_mode)" zapret_do_firewall_standard_rules_ipt()
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" {
local n f4 f6 qn qns qn6 qns6 # $1 - 1 - add, 0 - del
case "$mode" in local f4 f6
tpws)
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then [ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] &&
echo both http and https are disabled. not applying redirection. {
else f4="-p tcp -m multiport --dports $TPWS_PORTS_IPT"
filter_apply_port_target f4
f6=$f4 f6=$f4
filter_apply_ipset_target f4 f6 filter_apply_ipset_target f4 f6
fw_tpws $1 "$f4" "$f6" $TPPORT fw_tpws $1 "$f4" "$f6" $TPPORT
fi }
;; [ "$NFQWS_ENABLE" = 1 ] &&
{
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_IPT" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_KEEPALIVE_IPT" keepalive "$NFQWS_TCP_PKT_IN"
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_IPT" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_KEEPALIVE_IPT" keepalive "$NFQWS_UDP_PKT_IN"
}
}
nfqws) zapret_do_firewall_rules_ipt()
# quite complex but we need to minimize nfqws processes to save RAM {
get_nfqws_qnums qn qns qn6 qns6 # $1 - 1 - add, 0 - del
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
fw_reverse_nfqws_rule4 $1 "$f4" $qn
else
if [ -n "$qn" ]; then
f4="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packet_only"
filter_apply_ipset_target4 f4
fw_nfqws_post4 $1 "$f4 $desync" $qn
fw_reverse_nfqws_rule4 $1 "$f4" $qn
fi
if [ -n "$qns" ]; then
f4="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
filter_apply_ipset_target4 f4
fw_nfqws_post4 $1 "$f4 $desync" $qns
fw_reverse_nfqws_rule4 $1 "$f4" $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
fw_reverse_nfqws_rule6 $1 "$f6" $qn6
else
if [ -n "$qn6" ]; then
f6="-p tcp -m multiport --dports $HTTP_PORTS_IPT"
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packet_only"
filter_apply_ipset_target6 f6
fw_nfqws_post6 $1 "$f6 $desync" $qn6
fw_reverse_nfqws_rule6 $1 "$f6" $qn6
fi
if [ -n "$qns6" ]; then
f6="-p tcp -m multiport --dports $HTTPS_PORTS_IPT $first_packet_only"
filter_apply_ipset_target6 f6
fw_nfqws_post6 $1 "$f6 $desync" $qns6
fw_reverse_nfqws_rule6 $1 "$f6" $qns6
fi
fi
get_nfqws_qnums_quic qn qn6 zapret_do_firewall_standard_rules_ipt $1
if [ -n "$qn" ]; then
f4=
filter_apply_port_target_quic f4
f4="$f4 $first_packet_only"
filter_apply_ipset_target4 f4
fw_nfqws_post4 $1 "$f4 $desync" $qn
fi
if [ -n "$qn6" ]; then
f6=
filter_apply_port_target_quic f6
f6="$f6 $first_packet_only"
filter_apply_ipset_target6 f6
fw_nfqws_post6 $1 "$f6 $desync" $qn6
fi
;;
custom)
custom_runner zapret_custom_firewall $1 custom_runner zapret_custom_firewall $1
;;
esac
} }
zapret_do_firewall_ipt() zapret_do_firewall_ipt()
@ -452,10 +389,6 @@ zapret_do_firewall_ipt()
echo Clearing iptables echo Clearing iptables
fi fi
local mode="${MODE_OVERRIDE:-$MODE}"
[ "$mode" = "tpws-socks" ] && return 0
# always create ipsets. ip_exclude ipset is required # always create ipsets. ip_exclude ipset is required
[ "$1" = 1 ] && create_ipset no-update [ "$1" = 1 ] && create_ipset no-update

View File

@ -23,7 +23,7 @@ zapret_do_firewall()
# switch on liberal mode on zapret firewall start and switch off on zapret firewall stop # switch on liberal mode on zapret firewall start and switch off on zapret firewall stop
# this is only required for processing incoming bad RSTs. incoming rules are only applied in autohostlist mode # this is only required for processing incoming bad RSTs. incoming rules are only applied in autohostlist mode
# calling this after firewall because conntrack module can be not loaded before applying conntrack firewall rules # calling this after firewall because conntrack module can be not loaded before applying conntrack firewall rules
[ "$MODE_FILTER" = "autohostlist" -a "$MODE" != tpws -a "$MODE" != tpws-socks ] && set_conntrack_liberal_mode $1 [ "$MODE_FILTER" = "autohostlist" ] && set_conntrack_liberal_mode $1
[ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK [ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK
[ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK [ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK
@ -38,16 +38,3 @@ zapret_unapply_firewall()
{ {
zapret_do_firewall 0 "$@" zapret_do_firewall 0 "$@"
} }
first_packets_for_mode()
{
# autohostlist and autottl modes requires incoming traffic sample
# always use conntrack packet limiter or nfqws will deal with gigabytes
local n
if [ "$MODE_FILTER" = "autohostlist" ]; then
n=$((6+${AUTOHOSTLIST_RETRANS_THRESHOLD:-3}))
else
n=6
fi
echo $n
}

View File

@ -1,3 +1,5 @@
readonly HOSTLIST_MARKER="<HOSTLIST>"
find_hostlists() find_hostlists()
{ {
[ -n "$HOSTLIST_BASE" ] || HOSTLIST_BASE="$ZAPRET_BASE/ipset" [ -n "$HOSTLIST_BASE" ] || HOSTLIST_BASE="$ZAPRET_BASE/ipset"
@ -18,38 +20,33 @@ find_hostlists()
HOSTLIST_AUTO_DEBUGLOG="$HOSTLIST_BASE/zapret-hosts-auto-debug.log" HOSTLIST_AUTO_DEBUGLOG="$HOSTLIST_BASE/zapret-hosts-auto-debug.log"
} }
filter_apply_autohostlist_target()
{
# $1 - var name of tpws or nfqws params
local parm1="${AUTOHOSTLIST_FAIL_THRESHOLD:+--hostlist-auto-fail-threshold=$AUTOHOSTLIST_FAIL_THRESHOLD}"
local parm2="${AUTOHOSTLIST_FAIL_TIME:+--hostlist-auto-fail-time=$AUTOHOSTLIST_FAIL_TIME}"
local parm3 parm4
[ "$MODE" = "tpws" -o "$MODE" = "tpws-socks" ] || parm3="${AUTOHOSTLIST_RETRANS_THRESHOLD:+--hostlist-auto-retrans-threshold=$AUTOHOSTLIST_RETRANS_THRESHOLD}"
[ "$AUTOHOSTLIST_DEBUGLOG" = 1 ] && parm4="--hostlist-auto-debug=$HOSTLIST_AUTO_DEBUGLOG"
eval $1="\"\$$1 --hostlist-auto=$HOSTLIST_AUTO $parm1 $parm2 $parm3 $parm4\""
}
filter_apply_hostlist_target() filter_apply_hostlist_target()
{ {
# $1 - var name of tpws or nfqws params # $1 - var name of tpws or nfqws params
[ "$MODE_FILTER" = "hostlist" -o "$MODE_FILTER" = "autohostlist" ] || return local v parm parm1 parm2 parm3 parm4 parm5 parm6 parm7
eval v="\$$1"
local HOSTLIST_BASE HOSTLIST HOSTLIST_USER HOSTLIST_EXCLUDE contains "$v" "$HOSTLIST_MARKER" &&
{
[ "$MODE_FILTER" = hostlist -o "$MODE_FILTER" = autohostlist ] &&
{
find_hostlists find_hostlists
parm1="${HOSTLIST_USER:+--hostlist=$HOSTLIST_USER}"
[ -n "$HOSTLIST" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST\"" parm2="${HOSTLIST:+--hostlist=$HOSTLIST}"
[ -n "$HOSTLIST_USER" ] && eval $1="\"\$$1 --hostlist=$HOSTLIST_USER\"" parm3="${HOSTLIST_EXCLUDE:+--hostlist-exclude=$HOSTLIST_EXCLUDE}"
[ -n "$HOSTLIST_EXCLUDE" ] && eval $1="\"\$$1 --hostlist-exclude=$HOSTLIST_EXCLUDE\"" [ "$MODE_FILTER" = autohostlist ] &&
[ "$MODE_FILTER" = "autohostlist" ] && filter_apply_autohostlist_target $1 {
} parm4="--hostlist-auto=$HOSTLIST_AUTO"
parm5="${AUTOHOSTLIST_FAIL_THRESHOLD:+--hostlist-auto-fail-threshold=$AUTOHOSTLIST_FAIL_THRESHOLD}"
filter_apply_suffix() parm6="${AUTOHOSTLIST_FAIL_TIME:+--hostlist-auto-fail-time=$AUTOHOSTLIST_FAIL_TIME}"
{ parm7="${AUTOHOSTLIST_RETRANS_THRESHOLD:+--hostlist-auto-retrans-threshold=$AUTOHOSTLIST_RETRANS_THRESHOLD}"
# $1 - var name of tpws or nfqws params }
# $2 - suffix value parm="$parm1${parm2:+ $parm2}${parm3:+ $parm3}${parm4:+ $parm4}${parm5:+ $parm5}${parm6:+ $parm6}${parm7:+ $parm7}"
local v="${2:+ --new $2}" }
eval $1="\"\$$1$v\"" v="$(replace_str $HOSTLIST_MARKER "$parm" "$v")"
[ "$MODE_FILTER" = autohostlist -a "$AUTOHOSTLIST_DEBUGLOG" = 1 ] && {
v="$v --hostlist-auto-debug=$HOSTLIST_AUTO_DEBUGLOG"
}
eval $1=\""$v"\"
}
} }

View File

@ -86,10 +86,16 @@ cat << EOF | nft -f -
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 $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 localnet_protect ip daddr 127.0.0.0/8 drop comment "route_localnet remote access protection"
add rule inet $ZAPRET_NFT_TABLE input iif != lo jump localnet_protect add rule inet $ZAPRET_NFT_TABLE input iif != lo jump localnet_protect
add chain inet $ZAPRET_NFT_TABLE postrouting { type filter hook postrouting priority 99; } add chain inet $ZAPRET_NFT_TABLE postrouting
flush chain inet $ZAPRET_NFT_TABLE postrouting flush chain inet $ZAPRET_NFT_TABLE postrouting
add chain inet $ZAPRET_NFT_TABLE postnat { type filter hook postrouting priority 101; } add chain inet $ZAPRET_NFT_TABLE postrouting_hook { type filter hook postrouting priority 99; }
flush chain inet $ZAPRET_NFT_TABLE postrouting_hook
add rule inet $ZAPRET_NFT_TABLE postrouting_hook mark and $DESYNC_MARK == 0 jump postrouting
add chain inet $ZAPRET_NFT_TABLE postnat
flush chain inet $ZAPRET_NFT_TABLE postnat flush chain inet $ZAPRET_NFT_TABLE postnat
add chain inet $ZAPRET_NFT_TABLE postnat_hook { type filter hook postrouting priority 101; }
flush chain inet $ZAPRET_NFT_TABLE postnat_hook
add rule inet $ZAPRET_NFT_TABLE postnat_hook mark and $DESYNC_MARK == 0 jump postnat
add chain inet $ZAPRET_NFT_TABLE prerouting { type filter hook prerouting priority -99; } add chain inet $ZAPRET_NFT_TABLE prerouting { type filter hook prerouting priority -99; }
flush chain inet $ZAPRET_NFT_TABLE prerouting flush chain inet $ZAPRET_NFT_TABLE prerouting
add chain inet $ZAPRET_NFT_TABLE prenat { type filter hook prerouting priority -101; } add chain inet $ZAPRET_NFT_TABLE prenat { type filter hook prerouting priority -101; }
@ -107,6 +113,7 @@ cat << EOF | nft -f -
add set inet $ZAPRET_NFT_TABLE wanif { type ifname; } add set inet $ZAPRET_NFT_TABLE wanif { type ifname; }
add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; } add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; }
add map inet $ZAPRET_NFT_TABLE link_local { type ifname : ipv6_addr; } add map inet $ZAPRET_NFT_TABLE link_local { type ifname : ipv6_addr; }
EOF EOF
[ -n "$POSTNAT_ALL" ] && { [ -n "$POSTNAT_ALL" ] && {
nft_flush_chain predefrag_nfqws nft_flush_chain predefrag_nfqws
@ -118,6 +125,12 @@ nft_del_chains()
# do not delete all chains because of additional user hooks # do not delete all chains because of additional user hooks
# they must be inside zapret table to use nfsets # they must be inside zapret table to use nfsets
# these chains are newer. do not fail all because chains are not present
cat << EOF | nft -f - 2>/dev/null
delete chain inet $ZAPRET_NFT_TABLE postrouting_hook
delete chain inet $ZAPRET_NFT_TABLE postnat_hook
EOF
cat << EOF | nft -f - 2>/dev/null cat << EOF | nft -f - 2>/dev/null
delete chain inet $ZAPRET_NFT_TABLE dnat_output delete chain inet $ZAPRET_NFT_TABLE dnat_output
delete chain inet $ZAPRET_NFT_TABLE dnat_pre delete chain inet $ZAPRET_NFT_TABLE dnat_pre
@ -285,28 +298,6 @@ nft_apply_flow_offloading()
nft_filter_apply_port_target()
{
# $1 - var name of nftables filter
local f
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
f="tcp dport {$HTTP_PORTS,$HTTPS_PORTS}"
elif [ "$MODE_HTTPS" = "1" ]; then
f="tcp dport {$HTTPS_PORTS}"
elif [ "$MODE_HTTP" = "1" ]; then
f="tcp dport {$HTTP_PORTS}"
else
echo WARNING !!! HTTP and HTTPS are both disabled
fi
eval $1="\"\$$1 $f\""
}
nft_filter_apply_port_target_quic()
{
# $1 - var name of nftables filter
local f
f="udp dport {$QUIC_PORTS}"
eval $1="\"\$$1 $f\""
}
nft_filter_apply_ipset_target4() nft_filter_apply_ipset_target4()
{ {
# $1 - var name of ipv4 nftables filter # $1 - var name of ipv4 nftables filter
@ -592,29 +583,13 @@ zapret_list_table()
nft_produce_reverse_nfqws_rule()
{
local rule="$1"
if contains "$rule" "$nft_connbytes "; then
# autohostlist - need several incoming packets
# autottl - need only one incoming packet
[ "$MODE_FILTER" = autohostlist ] || rule=$(echo "$rule" | sed -re "s/$nft_connbytes [0-9]+-[0-9]+/$nft_connbytes 1/")
else
# old nft does not swallow 1-1
local range=1
[ "$MODE_FILTER" = autohostlist ] && range=$(first_packets_for_mode)
[ "$range" = 1 ] || range="1-$range"
rule="$nft_connbytes $range $rule"
fi
nft_reverse_nfqws_rule $rule
}
nft_fw_reverse_nfqws_rule4() nft_fw_reverse_nfqws_rule4()
{ {
nft_fw_nfqws_pre4 "$(nft_produce_reverse_nfqws_rule "$1")" $2 nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule "$1")" $2
} }
nft_fw_reverse_nfqws_rule6() nft_fw_reverse_nfqws_rule6()
{ {
nft_fw_nfqws_pre6 "$(nft_produce_reverse_nfqws_rule "$1")" $2 nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule "$1")" $2
} }
nft_fw_reverse_nfqws_rule() nft_fw_reverse_nfqws_rule()
{ {
@ -626,108 +601,75 @@ nft_fw_reverse_nfqws_rule()
nft_fw_reverse_nfqws_rule6 "$2" $3 nft_fw_reverse_nfqws_rule6 "$2" $3
} }
zapret_apply_firewall_rules_nft() nft_first_packets()
{ {
local mode="${MODE_OVERRIDE:-$MODE}" # $1 - packet count
[ -n "$1" -a "$1" != keepalive ] && [ "$1" -ge 1 ] &&
local first_packets_only {
local desync="mark and $DESYNC_MARK == 0" if [ "$1" = 1 ] ; then
local f4 f6 qn qns qn6 qns6 echo "$nft_connbytes 1"
first_packets_only="$nft_connbytes 1-$(first_packets_for_mode)"
case "$mode" in
tpws)
if [ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ]; then
echo both http and https are disabled. not applying redirection.
else else
nft_filter_apply_port_target f4 echo "$nft_connbytes 1-$1"
fi
}
}
nft_apply_nfqws_in_out()
{
# $1 - tcp,udp
# $2 - ports
# $3 - PKT_OUT. special value : 'keepalive'
# $4 - PKT_IN
local f4 f6 first_packets_only
[ -n "$2" ] || return
[ -n "$3" -a "$3" != 0 ] &&
{
first_packets_only="$(nft_first_packets $3)"
f4="$1 dport {$2} $first_packets_only"
f6=$f4
nft_filter_apply_ipset_target f4 f6
nft_fw_nfqws_post "$f4" "$f6" $QNUM
}
[ -n "$4" -a "$4" != 0 ] &&
{
first_packets_only="$(nft_first_packets $4)"
f4="$1 dport {$2} $first_packets_only"
f6=$f4
nft_filter_apply_ipset_target f4 f6
nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM
}
}
zapret_apply_firewall_standard_rules_nft()
{
local f4 f6
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] &&
{
f4="tcp dport {$TPWS_PORTS}"
f6=$f4 f6=$f4
nft_filter_apply_ipset_target f4 f6 nft_filter_apply_ipset_target f4 f6
nft_fw_tpws "$f4" "$f6" $TPPORT nft_fw_tpws "$f4" "$f6" $TPPORT
fi }
;; [ "$NFQWS_ENABLE" = 1 ] &&
nfqws) {
local POSTNAT_SAVE=$POSTNAT nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP_KEEPALIVE" keepalive "$NFQWS_TCP_PKT_IN"
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP_KEEPALIVE" keepalive "$NFQWS_UDP_PKT_IN"
}
}
POSTNAT=1 zapret_apply_firewall_rules_nft()
# quite complex but we need to minimize nfqws processes to save RAM {
get_nfqws_qnums qn qns qn6 qns6 zapret_apply_firewall_standard_rules_nft
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn" ] && [ "$qn" = "$qns" ]; then
nft_filter_apply_port_target f4
f4="$f4 $first_packets_only"
nft_filter_apply_ipset_target4 f4
nft_fw_nfqws_post4 "$f4 $desync" $qn
nft_fw_reverse_nfqws_rule4 "$f4" $qn
else
if [ -n "$qn" ]; then
f4="tcp dport {$HTTP_PORTS}"
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f4="$f4 $first_packets_only"
nft_filter_apply_ipset_target4 f4
nft_fw_nfqws_post4 "$f4 $desync" $qn
nft_fw_reverse_nfqws_rule4 "$f4" $qn
fi
if [ -n "$qns" ]; then
f4="tcp dport {$HTTPS_PORTS} $first_packets_only"
nft_filter_apply_ipset_target4 f4
nft_fw_nfqws_post4 "$f4 $desync" $qns
nft_fw_reverse_nfqws_rule4 "$f4" $qns
fi
fi
if [ "$MODE_HTTP_KEEPALIVE" != "1" ] && [ -n "$qn6" ] && [ "$qn6" = "$qns6" ]; then
nft_filter_apply_port_target f6
f6="$f6 $first_packets_only"
nft_filter_apply_ipset_target6 f6
nft_fw_nfqws_post6 "$f6 $desync" $qn6
nft_fw_reverse_nfqws_rule6 "$f6" $qn6
else
if [ -n "$qn6" ]; then
f6="tcp dport {$HTTP_PORTS}"
[ "$MODE_HTTP_KEEPALIVE" = "1" ] || f6="$f6 $first_packets_only"
nft_filter_apply_ipset_target6 f6
nft_fw_nfqws_post6 "$f6 $desync" $qn6
nft_fw_reverse_nfqws_rule6 "$f6" $qn6
fi
if [ -n "$qns6" ]; then
f6="tcp dport {$HTTPS_PORTS} $first_packets_only"
nft_filter_apply_ipset_target6 f6
nft_fw_nfqws_post6 "$f6 $desync" $qns6
nft_fw_reverse_nfqws_rule6 "$f6" $qns6
fi
fi
get_nfqws_qnums_quic qn qn6
if [ -n "$qn" ]; then
f4=
nft_filter_apply_port_target_quic f4
f4="$f4 $first_packets_only"
nft_filter_apply_ipset_target4 f4
nft_fw_nfqws_post4 "$f4 $desync" $qn
fi
if [ -n "$qn6" ]; then
f6=
nft_filter_apply_port_target_quic f6
f6="$f6 $first_packets_only"
nft_filter_apply_ipset_target6 f6
nft_fw_nfqws_post6 "$f6 $desync" $qn6
fi
POSTNAT=$POSTNAT_SAVE
;;
custom)
custom_runner zapret_custom_firewall_nft custom_runner zapret_custom_firewall_nft
;;
esac
} }
zapret_apply_firewall_nft() zapret_apply_firewall_nft()
{ {
echo Applying nftables echo Applying nftables
local mode="${MODE_OVERRIDE:-$MODE}"
[ "$mode" = "tpws-socks" ] && return 0
create_ipset no-update create_ipset no-update
nft_create_firewall nft_create_firewall
nft_fill_ifsets_overload nft_fill_ifsets_overload
@ -744,7 +686,7 @@ zapret_unapply_firewall_nft()
unprepare_route_localnet unprepare_route_localnet
nft_del_firewall nft_del_firewall
[ "$MODE" = custom ] && custom_runner zapret_custom_firewall_nft_flush custom_runner zapret_custom_firewall_nft_flush
return 0 return 0
} }
zapret_do_firewall_nft() zapret_do_firewall_nft()

View File

@ -1,5 +1,5 @@
PF_MAIN="/etc/pf.conf" PF_MAIN="/etc/pf.conf"
PF_ANCHOR_DIR=/etc/pf.anchors PF_ANCHOR_DIR="/etc/pf.anchors"
PF_ANCHOR_ZAPRET="$PF_ANCHOR_DIR/zapret" PF_ANCHOR_ZAPRET="$PF_ANCHOR_DIR/zapret"
PF_ANCHOR_ZAPRET_V4="$PF_ANCHOR_DIR/zapret-v4" PF_ANCHOR_ZAPRET_V4="$PF_ANCHOR_DIR/zapret-v4"
PF_ANCHOR_ZAPRET_V6="$PF_ANCHOR_DIR/zapret-v6" PF_ANCHOR_ZAPRET_V6="$PF_ANCHOR_DIR/zapret-v6"
@ -112,30 +112,13 @@ pf_nat_reorder_rules()
# use only first word as a key and preserve order within a single key # use only first word as a key and preserve order within a single key
sort -srfk 1,1 sort -srfk 1,1
} }
pf_anchor_port_target()
{
if [ "$MODE_HTTP" = "1" ] && [ "$MODE_HTTPS" = "1" ]; then
echo "{$HTTP_PORTS_IPT,$HTTPS_PORTS_IPT}"
elif [ "$MODE_HTTPS" = "1" ]; then
echo "{$HTTPS_PORTS_IPT}"
elif [ "$MODE_HTTP" = "1" ]; then
echo "{$HTTP_PORTS_IPT}"
fi
}
pf_anchor_zapret_v4_tpws() pf_anchor_zapret_v4_tpws()
{ {
# $1 - tpws listen port # $1 - tpws listen port
# $2 - rdr ports. defaults are used if empty # $2 - rdr ports
local rule port
if [ -n "$2" ]; then
port="{$2}"
else
port=$(pf_anchor_port_target)
fi
local rule port="{$2}"
for lan in $IFACE_LAN; do for lan in $IFACE_LAN; do
for t in $tbl; 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" echo "rdr on $lan inet proto tcp from any to $t port $port -> 127.0.0.1 port $1"
@ -158,31 +141,19 @@ pf_anchor_zapret_v4()
{ {
local tbl port local tbl port
[ "$DISABLE_IPV4" = "1" ] || { [ "$DISABLE_IPV4" = "1" ] || {
case "${MODE_OVERRIDE:-$MODE}" in {
tpws)
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST" pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
pf_anchor_zapret_v4_tpws $TPPORT custom_runner zapret_custom_firewall_v4
;; [ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && pf_anchor_zapret_v4_tpws $TPPORT "$TPWS_PORTS_IPT"
custom) } | pf_nat_reorder_rules
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
custom_runner zapret_custom_firewall_v4 | pf_nat_reorder_rules
;;
esac
} }
} }
pf_anchor_zapret_v6_tpws() pf_anchor_zapret_v6_tpws()
{ {
# $1 - tpws listen port # $1 - tpws listen port
# $2 - rdr ports. defaults are used if empty # $2 - rdr ports
local rule LL_LAN port local rule LL_LAN port="{$2}"
if [ -n "$2" ]; then
port="{$2}"
else
port=$(pf_anchor_port_target)
fi
# LAN link local is only for router # LAN link local is only for router
for lan in $IFACE_LAN; do for lan in $IFACE_LAN; do
@ -208,19 +179,12 @@ pf_anchor_zapret_v6_tpws()
pf_anchor_zapret_v6() pf_anchor_zapret_v6()
{ {
local tbl port local tbl port
[ "$DISABLE_IPV6" = "1" ] || { [ "$DISABLE_IPV6" = "1" ] || {
case "${MODE_OVERRIDE:-$MODE}" in {
tpws) pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
[ ! "$MODE_HTTP" = "1" ] && [ ! "$MODE_HTTPS" = "1" ] && return custom_runner zapret_custom_firewall_v6
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6" [ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS_IPT" ] && pf_anchor_zapret_v6_tpws $TPPORT "$TPWS_PORTS_IPT"
pf_anchor_zapret_v6_tpws $TPPORT } | pf_nat_reorder_rules
;;
custom)
pf_anchor_zapret_tables tbl zapret6-user "$ZIPLIST_USER6" zapret6 "$ZIPLIST6"
custom_runner zapret_custom_firewall_v6 | pf_nat_reorder_rules
;;
esac
} }
} }

View File

@ -9,6 +9,9 @@
# override firewall type : iptables,nftables,ipfw # override firewall type : iptables,nftables,ipfw
#FWTYPE=iptables #FWTYPE=iptables
# nftables only : set this to 0 to use pre-nat mode. default is post-nat.
# pre-nat mode disables some bypass techniques for forwarded traffic but allows to see client IP addresses in debug log
#POSTNAT=0
# options for ipsets # options for ipsets
# maximum number of elements in sets. also used for nft sets # maximum number of elements in sets. also used for nft sets
@ -40,53 +43,56 @@ GZIP_LISTS=1
# set to "-" to disable reload # set to "-" to disable reload
#LISTS_RELOAD="pfctl -f /etc/pf.conf" #LISTS_RELOAD="pfctl -f /etc/pf.conf"
# override ports # mark bit used by nfqws to prevent loop
#HTTP_PORTS=80-81,85
#HTTPS_PORTS=443,500-501
#QUIC_PORTS=443,444
# CHOOSE OPERATION MODE
# MODE : nfqws,tpws,tpws-socks,filter,custom
# nfqws : nfqws for dpi desync
# tpws : tpws transparent mode
# tpws-socks : tpws socks mode
# filter : no daemon, just create ipset or download hostlist
# custom : custom mode. should modify custom init script and add your own code
MODE=tpws
# apply fooling to http
MODE_HTTP=1
# for nfqws only. support http keep alives. enable only if DPI checks for http request in any outgoing packet
MODE_HTTP_KEEPALIVE=0
# apply fooling to https
MODE_HTTPS=1
# apply fooling to quic
MODE_QUIC=0
# none,ipset,hostlist,autohostlist
MODE_FILTER=none
# CHOOSE NFQWS DAEMON OPTIONS for DPI desync mode. run "nfq/nfqws --help" for option list
# SUFFIX VARS define additional lower priority desync profile. it's required if MODE_FILTER=hostlist and strategy has hostlist-incompatible 0-phase desync methods (syndata,wssize)
DESYNC_MARK=0x40000000 DESYNC_MARK=0x40000000
DESYNC_MARK_POSTNAT=0x20000000 DESYNC_MARK_POSTNAT=0x20000000
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-ttl6=0 --dpi-desync-fooling=badsum"
#NFQWS_OPT_DESYNC_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTP=""
#NFQWS_OPT_DESYNC_HTTP_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTPS=""
#NFQWS_OPT_DESYNC_HTTPS_SUFFIX="--wssize 1:6"
#NFQWS_OPT_DESYNC_HTTP6=""
#NFQWS_OPT_DESYNC_HTTP6_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTPS6=""
#NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="--wssize 1:6"
NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake --dpi-desync-repeats=6"
#NFQWS_OPT_DESYNC_QUIC_SUFFIX=""
#NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
#NFQWS_OPT_DESYNC_QUIC6_SUFFIX=""
# CHOOSE TPWS DAEMON OPTIONS. run "tpws/tpws --help" for option list TPWS_SOCKS_ENABLE=0
# SUFFIX VARS define additional lower priority desync profile. it's required if MODE_FILTER=hostlist and strategy has hostlist-incompatible 0-phase desync methods (mss) # tpws socks listens on this port on localhost and LAN interfaces
TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3 --oob" TPPORT_SOCKS=987
#TPWS_OPT_SUFFIX="--mss 88" # use <HOSTLIST> placeholders to engage standard hostlists and autohostlist in ipset dir
# they are replaced to empty string if MODE_FILTER does not satisfy
TPWS_SOCKS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
"
TPWS_ENABLE=0
TPWS_PORTS=80,443
# use <HOSTLIST> placeholders to engage standard hostlists and autohostlist in ipset dir
# they are replaced to empty string if MODE_FILTER does not satisfy
TPWS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
"
NFQWS_ENABLE=0
# redirect outgoing traffic with connbytes limiter applied in both directions.
NFQWS_PORTS_TCP=80,443
NFQWS_PORTS_UDP=443
# PKT_OUT means connbytes dir original
# PKT_IN means connbytes dir reply
# this is --dpi-desync-cutoff=nX kernel mode implementation for linux. it saves a lot of CPU.
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_TCP_PKT_IN=3
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_UDP_PKT_IN=0
# redirect outgoing traffic without connbytes limiter and incoming with connbytes limiter
# normally it's needed only for stateless DPI that matches every packet in a single TCP session
# typical example are plain HTTP keep alives
# this mode can be very CPU consuming. enable with care !
#NFQWS_PORTS_TCP_KEEPALIVE=80
#NFQWS_PORTS_UDP_KEEPALIVE=
# use <HOSTLIST> placeholders to engage standard hostlists and autohostlist in ipset dir
# they are replaced to empty string if MODE_FILTER does not satisfy
NFQWS_OPT="
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST>
"
# none,ipset,hostlist,autohostlist
MODE_FILTER=none
# openwrt only : donttouch,none,software,hardware # openwrt only : donttouch,none,software,hardware
FLOWOFFLOAD=donttouch FLOWOFFLOAD=donttouch

View File

@ -336,3 +336,8 @@ tpws: fixed MSS apply in transparent mode
nfqws: fixed autottl apply if desync profile changed nfqws: fixed autottl apply if desync profile changed
tpws,nfqws: fixed 100% cpu hang on gzipped list with comments tpws,nfqws: fixed 100% cpu hang on gzipped list with comments
ipset: get_refilter_ipsum.sh , get_refilter_domain.sh ipset: get_refilter_ipsum.sh , get_refilter_domain.sh
v66:
init.d: rewrite traffic interception and daemon launch parameters in config file. this break compatibility with old versions.
init.d: openwrt-minimal : tpws launch for low storage openwrt devices

View File

@ -20,12 +20,12 @@ nft delete table inet ztest
nft create table inet ztest nft create table inet ztest
nft add chain inet ztest post "{type filter hook postrouting priority mangle;}" nft add chain inet ztest post "{type filter hook postrouting priority mangle;}"
nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass
nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-4 queue num 200 bypass nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-12 queue num 200 bypass
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI # auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
nft add chain inet ztest pre "{type filter hook prerouting priority filter;}" nft add chain inet ztest pre "{type filter hook prerouting priority filter;}"
nft add rule inet ztest pre tcp sport "{80,443}" ct reply packets 1-4 queue num 200 bypass nft add rule inet ztest pre tcp sport "{80,443}" ct reply packets 1-3 queue num 200 bypass
show rules : nft list table inet ztest show rules : nft list table inet ztest

View File

@ -22,9 +22,9 @@
1) Чтобы процедура установки сработала в штатном режиме на openwrt, нужно раcсчитывать на свободное место около 1-2 Mb 1) Чтобы процедура установки сработала в штатном режиме на openwrt, нужно раcсчитывать на свободное место около 1-2 Mb
для установки самого zapret и необходимых дополнительных пакетов. для установки самого zapret и необходимых дополнительных пакетов.
Если места мало и нет возможности его увеличить за счет extroot, возможно придется отказаться от варианта Если места мало и нет возможности его увеличить за счет extroot, возможно придется отказаться от варианта
простой установки и прикручивать в ручном режиме без имеющихся скриптов запуска, либо попробовать засунуть требуемые простой установки и прикручивать в ручном режиме без имеющихся скриптов запуска.
zapret дополнительные пакеты в сжатый образ squashfs с помощью image builder и перешить этим вариантом роутер. Можно использовать облегченный tpws вариант из init.d/openwrt-minimal, либо попробовать засунуть требуемые zapret
См docs/manual_setup.txt , docs/readme.txt . дополнительные пакеты в сжатый образ squashfs с помощью image builder и перешить этим вариантом роутер.
2) Скачайте zip архив проекта с github в /tmp, распакуйте его там, 2) Скачайте zip архив проекта с github в /tmp, распакуйте его там,
либо клонируйте проект через : git clone --depth 1 https://github.com/bol-van/zapret либо клонируйте проект через : git clone --depth 1 https://github.com/bol-van/zapret
@ -83,10 +83,9 @@ iptables/nftables. В /etc/resolv.conf нельзя прописать DNS на
Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале. Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
Вероятно, все остальные домены блокированы подобным образом, но не факт. Вероятно, все остальные домены блокированы подобным образом, но не факт.
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, но для этого необходимо понимать В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
"что там за буковки". Если вы в сетях слабо разбираетесь, это не для вас. В противном случае читайте readme.txt. Необходимо понимать как работают стратегии.
zapret не может пробить блокировку по IP адресу zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
Для проверки нескольких доменов вводите их через пробел.
Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI, с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
@ -104,37 +103,68 @@ badseq может работать только на https и не работа
может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
она стабильна, на третьих полный хаос, и проще отказаться. она стабильна, на третьих полный хаос, и проще отказаться.
Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска tpws и/или nfqws
с использованием мультистратегии. Как работают мультистратегии описано в readme.txt.
Если кратко, то обычно параметры конструируются так :
"--filter-udp=443 'параметры для quic' <HOSTLIST> --new
--filter-tcp=80-443 'обьединенные параметры для http и https' <HOSTLIST>"
Или так :
"--filter-udp=443 "параметры для quic" <HOSTLIST> --new
--filter-tcp=80 'параметры для http' <HOSTLIST> --new
--filter-tcp=443 'параметры для https' <HOSTLIST>"
"<HOSTLIST>" так и пишется. Его не надо на что-то заменять. Это сделают скрипты запуска, если вы выбрали режим
фильтрации по хостлистам, и уберут в противном случае.
Если для какого-то протокола надо дурить все без стандартного хостлиста - просто уберите оттуда "<HOSTLIST>".
Можно писать свои параметры --hostlist и --hostlist-exclude для дополнительных хостлистов
или в профилях специализаций под конкретный ресурс. В последнем случае стандартный хостлист там не нужен.
Следует избегать указания собственных параметров --hostlist на листы из директории ipset.
Эта логика включена в "<HOSTLIST>".
Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
"--filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" <HOSTLIST> --new
--filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' <HOSTLIST> --new
--filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' <HOSTLIST> --new
--filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" <HOSTLIST> --new
--filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' <HOSTLIST> --new
--filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6' <HOSTLIST>"
Но здесь совсем "копи-пастный" вариант.
Чем больше вы обьедините стратегий и сократите их общее количество, тем будет лучше.
Если вам не нужно дурение отдельных протоколов, лучше всего будет их убрать из системы перехвата трафика через
параметры TPWS_PORTS, NFQWS_PORTS_TCP, NFQWS_PORTS_UDP и убрать соответствующие им профили мультистратегии.
tcp 80 - http, tcp 443 - https, udp 443 - quic.
Если используются методы нулевой фазы десинхронизации (--mss, --wssize, --dpi-desync=syndata) и режим фильтрации hostlist, Если используются методы нулевой фазы десинхронизации (--mss, --wssize, --dpi-desync=syndata) и режим фильтрации hostlist,
то все параметры, относящиеся к этим методам, следует помещать не в основные параметры (например, NFQWS_OPT_DESYNC), то все параметры, относящиеся к этим методам, следует помещать в отдельные профили мульистратегии, которые получат
а в suffix (NFQWS_OPT_DESYNC_SUFFIX). Чтобы не ошибиться, можно их продублировать и там, и там. управление до определения имени хоста. Необходимо понимать алгоритм работы мультистратегий.
Иначе они могут не работать. Самым надежным вариантом будет дублирование этих параметров на 2 профиля. Какой-нибудь сработает в зависимости
от параметра MODE_FILTER.
"--filter-tcp=80 'параметры для http' <HOSTLIST> --new
--filter-tcp=443 'параметры для https' --wssize 1:6 <HOSTLIST> --new
--filter-tcp=443 --wssize 1:6"
В этом примере wssize будет применяться всегда к порту tcp 443 вне зависимости от параметра MODE_FILTER.
Хостлист будет игнорироваться, если таковой имеется. К http применять wssize вредно и бессмысленно.
Никто не мешает использовать tpws для http, nfqws для https, либо комбинировать действие nfqws и tpws для одного протокола.
В текущем варианте скриптов запуска это делается максимально гибко и независимо друг от друга.
8) Запустите install_easy.sh. 8) Запустите install_easy.sh.
Выберите nfqws или tpws, затем согласитесь на редактирование параметров. Выберите nfqws и/или tpws, затем согласитесь на редактирование параметров.
Откроется редактор, куда впишите найденные стратегии. Откроется редактор, куда впишите созданную на предыдущем этапе стратегию.
Для nfqws отдельно настраиваются стратегии на http и https для ipv4 и ipv6.
То есть по максимуму 4 разных варианта.
NFQWS_OPT_DESYNC - это общая установка, которая применяется, если какой-либо уточняющий параметр не задан
NFQWS_OPT_DESYNC_HTTP и NFQWS_OPT_DESYNC_HTTPS заменяют стратегию для http и https.
Если у вас включен ipv6, то они так же будут применены и к ipv6. Если для ipv6 нужна другая стратегия,
то можно задать уточняющие параметры NFQWS_OPT_DESYNC_HTTP6 и NFQWS_OPT_DESYNC_HTTPS6.
Если стратегии для ipv4 и ipv6 отличаются лишь ttl, то в целях экономии ресурсов роутера (меньше процессов nfqws)
следует отказаться от использования специфических для ipv6 установок. Вместо них использовать параметры
--dpi-desync-ttl и --dpi-desync-ttl6 в общих установках. Таким способом можно заставить один процесс nfqws
обрабатывать трафик на ipv4 и на ipv6 с разным ttl.
Важным вопросом является вопрос о поддержке http keep alive.
Отвечайте N. Если вдруг на http сайтах будут хаотические сбои типа то загружается, то заглушка или сброс,
попробуйте включить поддержку keep alive. Но просто "на всякий случай" не включайте - это увеличит нагрузку на роутер.
Если это не помогает, или хаотичное поведение наблюдается и на https, то еще раз прогоните blockcheck
с установленным числом попыток проверки не менее 5. Возможно, ваш провайдер использует балансировку нагрузки,
где на разных путях установлен разный DPI.
9) На все остальные вопросы install_easy.sh отвечайте согласно выводимой аннонтации. 9) На все остальные вопросы install_easy.sh отвечайте согласно выводимой аннонтации.
10) Если ломаются отдельные незаблокированные ресурсы, следует вносить их в исключения, либо пользоваться ограничивающим 10) Если ломаются отдельные незаблокированные ресурсы, следует вносить их в исключения, либо пользоваться ограничивающим
ipset или хост листом. Читайте основной талмуд readme.txt ради подробностей. ipset или хост листом. Читайте основной талмуд readme.txt ради подробностей.
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея. Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
В некоторых случаях вы не обойдетесь без знаний и основного "талмуда". В некоторых случаях вы не обойдетесь без знаний и основного "талмуда".

View File

@ -2,7 +2,10 @@
Как обычно, компьютерная грамотность ложится полностью на вас. Как обычно, компьютерная грамотность ложится полностью на вас.
Вы должны уметь работать с консолью windows и иметь минимальные навыки обращения с командными файлами bat,cmd. Вы должны уметь работать с консолью windows и иметь минимальные навыки обращения с командными файлами bat,cmd.
Если грамотность отсутствует и возникает куча "как" на базовых вещах - проходите мимо или ищите помощь в другом месте. Если грамотность отсутствует и возникает куча "как" на базовых вещах, значит эта программа не для вас.
Разработчик не будет отвечать на вопросы из серии школы компьютерной грамотности.
Если вы все-таки хотите продолжать, задавайте вопросы в дискуссиях на github или на форумах.
Возможно, кто-то вам поможет. Но не надо писать issue на github. Они будут закрываться сразу.
Обход DPI является хакерской методикой. Под этим словом понимается метод, которому сопротивляется окружающая среда, Обход DPI является хакерской методикой. Под этим словом понимается метод, которому сопротивляется окружающая среда,
которому автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах, которому автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах,
@ -34,21 +37,22 @@
РЕШЕНИЕ "КАК ПОЛОЖЕНО" РЕШЕНИЕ "КАК ПОЛОЖЕНО"
1) Если у вас windows 7, обновляйте систему. Годами не обновляемая 7-ка может не запускать драйвер windivert. 1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip
Поддержка 32-битных x86 windows возможна, но в готовом виде отсутствует.
2) Если у вас Windows 7 x64, читайте docs/windows.txt. Без описанной там подготовки может не работать.
Для 32-битных систем Windows нет готового полного варианта, но есть собранные бинарники :
https://github.com/bol-van/zapret-win32
На windows 11 arm64 выполните arm64/install_arm64.cmd от имени администратора и перезагрузите компьютер. На windows 11 arm64 выполните arm64/install_arm64.cmd от имени администратора и перезагрузите компьютер.
Читайте docs/windows.txt Читайте docs/windows.txt
Имейте в виду, что антивирусы могут плохо реагировать на windivert. Имейте в виду, что антивирусы могут плохо реагировать на windivert.
cygwin имеет внушительный список несовместимостей с антивирусами. Многие антивирусы его ломают. cygwin так же имеет внушительный список несовместимостей с антивирусами, хотя современные антивирусы
https://www.cygwin.com/faq.html#faq.using.bloda более-менее научились с ним дружить.
Если это имеет место , используйте исключения. Если это не помогает - отключайте антивирус совсем. Если проблема имеет место , используйте исключения. Если не помогает - отключайте антивирус совсем.
2) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret. 3) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
3) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит 4) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
4) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip
5) Запустите blockcheck\blockcheck.cmd. blockcheck в начале проверяет DNS. Если выводятся сообщения о подмене адресов, то 5) Запустите blockcheck\blockcheck.cmd. blockcheck в начале проверяет DNS. Если выводятся сообщения о подмене адресов, то
первым делом нужно решить эту проблему, иначе ничего не будет работать. первым делом нужно решить эту проблему, иначе ничего не будет работать.
@ -66,10 +70,9 @@ https://www.cygwin.com/faq.html#faq.using.bloda
Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале. Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
Вероятно, все остальные домены блокированы подобным образом, но не факт. Вероятно, все остальные домены блокированы подобным образом, но не факт.
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, но для этого необходимо понимать В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
"что там за буковки". Если вы в сетях слабо разбираетесь, это не для вас. В противном случае читайте readme.txt. Необходимо понимать как работают стратегии.
zapret не может пробить блокировку по IP адресу zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
Для проверки нескольких доменов вводите их через пробел.
Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI, с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
@ -87,10 +90,58 @@ badseq может работать только на https и не работа
может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
она стабильна, на третьих полный хаос, и проще отказаться. она стабильна, на третьих полный хаос, и проще отказаться.
Если используются методы нулевой фазы десинхронизации (--wssize, --dpi-desync=syndata) и фильтр hostlist, Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
то все параметры, относящиеся к этим методам, следует помещать в следующий профиль без хостлиста, с использованием мультистратегии. Как работают мультистратегии описано в readme.txt.
к которому перейдет управление, когда имя хоста еще неизвестно.
Используйте параметр --debug для отладки вашего сценария. Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры
--wf-l3, --wf-tcp, --wf-udp.
--wf-l3 относится к версии ip протокола - ipv4 или ipv6.
--wf-tcp и --wf-udp содержат перечень портов или диапазонов портов через запятую.
Пример стандартного фильтра для перехвата http, https, quic : --wf-tcp=80,443 --wf-udp=443
Фильтр должен быть минимально необходимым. Перехват лишнего трафика приведет только к бессмысленному
расходованию ресурсов процессора и замедлению интернета.
Если кратко по мультистратегии, то обычно параметры конструируются так :
"--filter-udp=443 'параметры для quic' --new
--filter-tcp=80-443 'обьединенные параметры для http и https'"
Или так :
"--filter-udp=443 "параметры для quic" --new
--filter-tcp=80 'параметры для http' --new
--filter-tcp=443 'параметры для https'"
Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
"--filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" --new
--filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' --new
--filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' --new
--filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" --new
--filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' --new
--filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6'"
Но здесь совсем "копи-пастный" вариант.
Чем больше вы обьедините стратегий и сократите их общее количество, тем будет лучше.
Если вам не нужно дурение отдельных протоколов, лучше всего будет их убрать из системы перехвата трафика через
параметры --wf-* и убрать соответствующие им профили мультистратегии.
tcp 80 - http, tcp 443 - https, udp 443 - quic.
Если используются методы нулевой фазы десинхронизации (--mss, --wssize, --dpi-desync=syndata) и фильтрация hostlist,
то все параметры, относящиеся к этим методам, следует помещать в отдельные профили мультистратегии, которые получат
управление до определения имени хоста. Необходимо понимать алгоритм работы мультистратегий.
"--filter-tcp=80 'параметры для http' --new
--filter-tcp=443 'параметры для https' --hostlist=d:/users/user/temp/list.txt --new
--filter-tcp=443 --wssize 1:6"
autohostlist профиль приоритетен, поэтому wssize нужно писать туда :
"--filter-tcp=80 'параметры для http' --new
--filter-tcp=443 'параметры для https' --wssize 1:6 --hostlist-auto=d:/users/user/temp/autolist.txt"
В этих примерах wssize будет применяться всегда к порту tcp 443, а хостлист будет игнорироваться.
К http применять wssize вредно и бессмысленно.
7) Протестируйте найденные стратегии на winws. winws следует брать из zapret-winws. 7) Протестируйте найденные стратегии на winws. winws следует брать из zapret-winws.
Для этого откройте командную строку windows от имени администратора в директории zapret-winws. Для этого откройте командную строку windows от имени администратора в директории zapret-winws.
@ -113,10 +164,12 @@ badseq может работать только на https и не работа
Аналогично настраиваются и службы windows. Смотрите service_*.cmd Аналогично настраиваются и службы windows. Смотрите service_*.cmd
9) Если ломаются отдельные незаблокированные ресурсы, используйте хост-листы. 10) Если ломаются отдельные незаблокированные ресурсы, нужно пользоваться ограничивающим
Где они будут находиться - решайте сами. ipset или хост листом. Читайте основной талмуд readme.txt ради подробностей.
Параметры управления хост-листами точно такие же, как в *nix. Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея. Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
В некоторых случаях вы не обойдетесь без знаний и основного "толмуда". В некоторых случаях вы не обойдетесь без знаний и основного "талмуда".
Подробности и полное техническое описание расписаны в readme.txt Подробности и полное техническое описание расписаны в readme.txt

View File

@ -915,35 +915,104 @@ On openwrt by default `nftables` is selected on `firewall4` based systems.
`FWTYPE=iptables` `FWTYPE=iptables`
Main mode : With `nftables` post-NAT scheme is used by default. It allows more DPI attacks on forwarded traffic.
It's possible to use `iptables`-like pre-NAT scheme. `nfqws` will see client source IPs and display them in logs.
`#POSTNAT=0`
There'are 3 standard options configured separately and independently : `tpws-socks`, `tpws`, `nfqws`.
They can be used alone or combined. Custom scripts in `init.d/{sysv,openwrt,macos}/custom.d` are always applied.
`tpws-socks` requires daemon parameter configuration but does not require traffic interception.
Other standard options require also traffic interception.
Each standard option launches single daemon instance. Strategy differiences are managed using multi-profile scheme.
Main rule for interception is "intercept required minumum". Everything else only wastes CPU resources and slows down connection.
`--ipset` option is prohibited intentionally to disallow easy to use but ineffective user-mode filtering.
Use kernel ipsets instead. It may require custom scripts.
To use standard updatable hostlists from the `ipset` dir use `<HOSTLIST>` placeholder. It's automatically replaced
with hostlist parameters if `MODE_FILTER` variable enables hostlists and is removed otherwise.
Standard hostlists are expected in final (fallback) strategies closing groups of filter parameters.
Don't use `<HOSTLIST>` in highly specialized profiles. Use your own filter or hostlist(s).
`tpws` socks proxy mode switch
`TPWS_SOCKS_ENABLE=0`
Listening tcp port for `tpws` proxy mode.
`TPPORT_SOCKS=987`
`tpws` socks mode parameters
``` ```
tpws - tpws transparent mode TPWS_SOCKS_OPT="
tpws-socks - tpws socks mode --filter-tcp=80 --methodeol <HOSTLIST> --new
binds to localhost and LAN interface (if IFACE_LAN is specified or the system is OpenWRT). port 988 --filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
nfqws - nfqws "
filter - only fill ipset or load hostlist
custom - use custom script for running daemons and establishing firewall rules
``` ```
`MODE=tpws` `tpws` transparent mode switch
Enable http fooling : `TPWS_ENABLE=0`
`MODE_HTTP=1` `tpws` transparent mode target ports
Apply fooling to keep alive http sessions. Only applicable to nfqws. Tpws always fool keepalives. `TPWS_PORTS=80,443`
Not enabling this can save CPU time.
`MODE_HTTP_KEEPALIVE=0` `tpws` transparent mode parameters
Enable https fooling : ```
TPWS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
"
```
`MODE_HTTPS=1` `nfqws` enable switch
Enable quic fooling : `NFQWS_ENABLE=0`
`nfqws` port targets for `connbytes`-limited interception. `connbytes` allows to intercept only starting packets from connections.
This is more effective kernel-mode alternative to `nfqws --dpi-desync-cutoff=nX`.
```
NFQWS_PORTS_TCP=80,443
NFQWS_PORTS_UDP=443
```
How many starting packets should be intercepted to nfqws in each direction
```
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_TCP_PKT_IN=3
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_UDP_PKT_IN=0
```
There's kind of traffic that requires interception of entire outgoing stream.
Typically it's support for plain http keepalives and stateless DPI.
This mode of interception significantly increases CPU utilization. Use with care and only if required.
Here you specify port numbers for unlimited interception.
It's advised also to remove these ports from `connbytes`-limited interception list.
```
#NFQWS_PORTS_TCP_KEEPALIVE=80
#NFQWS_PORTS_UDP_KEEPALIVE=
```
`nfqws` parameters
```
NFQWS_OPT="
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST>
"
```
`MODE_QUIC=1`
Host filtering mode : Host filtering mode :
``` ```
@ -955,62 +1024,6 @@ autohostlist - hostlist mode + blocks auto detection
`MODE_FILTER=none` `MODE_FILTER=none`
Its possible to change manipulation options used by tpws :
`TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3"`
Additional low priority desync profile for `MODE_FILTER=hostlist`.
With multiple profile support 0-phase desync methods are no more applied with hostlist !
To apply them additional profile is required without hostlist filter.
`TPWS_OPT_SUFFIX="--mss=88"`
nfqws options for DPI desync attack:
```
DESYNC_MARK=0x40000000
DESYNC_MARK_POSTNAT=0x20000000
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum --dpi-desync-fwmark=$DESYNC_MARK"
```
Separate nfqws options for http and https and ip protocol versions 4,6:
```
NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
```
If one of `NFQWS_OPT_DESYNC_HTTP`/`NFQWS_OPT_DESYNC_HTTPS` is not defined it takes value of NFQWS_OPT_DESYNC.
If one of `NFQWS_OPT_DESYNC_HTTP6`/`NFQWS_OPT_DESYNC_HTTPS6` is not defined it takes value from
`NFQWS_OPT_DESYNC_HTTP`/`NFQWS_OPT_DESYNC_HTTPS`.
It means if only `NFQWS_OPT_DESYNC` is defined all four take its value.
If a variable is not defined, the value `NFQWS_OPT_DESYNC` is taken.
Additional low priority desync profile for `MODE_FILTER=hostlist`.
With multiple profile support 0-phase desync methods are no more applied with hostlist !
To apply them additional profile is required without hostlist filter.
```
#NFQWS_OPT_DESYNC_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTP_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTPS_SUFFIX="--wssize 1:6"
#NFQWS_OPT_DESYNC_HTTP6_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="--wssize 1:6"
```
Defaults are filled the same ways as with NFQWS_OPT_*.
Separate QUIC options for ip protocol versions :
```
NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
```
If `NFQWS_OPT_DESYNC_QUIC6` is not specified `NFQWS_OPT_DESYNC_QUIC` is taken.
flow offloading control (if supported) flow offloading control (if supported)
@ -1208,6 +1221,8 @@ After installation remove `/tmp/zapret` to free RAM.
The absolute minimum for openwrt is 64/8 system, 64/16 is comfortable, 128/extroot is recommended. The absolute minimum for openwrt is 64/8 system, 64/16 is comfortable, 128/extroot is recommended.
For low storage openwrt see `init.d/openwrt-minimal`.
### Android ### Android
Its not possible to use nfqws and tpws in transparent proxy mode without root privileges. Its not possible to use nfqws and tpws in transparent proxy mode without root privileges.

View File

@ -1,4 +1,4 @@
zapret v.65 zapret v.66
English English
------- -------
@ -952,6 +952,7 @@ TCP_USER_TIMEOUT. Под таймаутом подразумевается вр
Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии. Используйте `curl --socks5` и `curl --socks5-hostname` для проверки вашей стратегии.
Смотрите вывод --debug, чтобы убедиться в правильности настроек. Смотрите вывод --debug, чтобы убедиться в правильности настроек.
Способы получения списка заблокированных IP Способы получения списка заблокированных IP
------------------------------------------- -------------------------------------------
@ -1007,7 +1008,7 @@ Cкрипты с названием get_antifilter_* оперируют спис
Или вы можете узнать о проблеме лишь когда у вас начнет постоянно пропадать wifi, и вам придется Или вы можете узнать о проблеме лишь когда у вас начнет постоянно пропадать wifi, и вам придется
его перезагружать каждые 2 часа (метод кувалды). его перезагружать каждые 2 часа (метод кувалды).
Самые щадящие варианты по RAM - get_antifilter_allyouneed.sh, get_antifilter_ipsum.sh. Самые щадящие варианты по RAM - get_antifilter_allyouneed.sh, get_antifilter_ipsum.sh, get_refilter_*.sh.
Листы zapret-ip.txt и zapret-ipban.txt сохраняются в сжатом виде в файлы .gz. Листы zapret-ip.txt и zapret-ipban.txt сохраняются в сжатом виде в файлы .gz.
Это позволяет снизить их размер во много раз и сэкономить место на роутере. Это позволяет снизить их размер во много раз и сэкономить место на роутере.
@ -1364,86 +1365,95 @@ curl: (28) Connection timed out after 2002 milliseconds
FWTYPE=iptables FWTYPE=iptables
Основной режим : На nftables можно отключить стандартную схему перехвата трафика после NAT и перейти на перехват до NAT.
tpws - tpws в режиме transparent Это сделает невозможным применение некоторых методов дурения на проходящем трафике как в случае с iptables.
tpws-socks - tpws в режиме socks nfqws начнет получать адреса пакетов из локальной сети и отображать их в логах.
вешается на localhost и LAN интерфейс (если задан IFACE_LAN или если система - OpenWRT). порт 988 #POSTNAT=0
nfqws - nfqws
filter - только заполнить ipset или загрузить hostlist
custom - нужно самому запрограммировать запуск демонов в init скрипте и правила iptables
MODE=tpws Существует 3 стандартных опции запуска, настраиваемых раздельно и независимо : tpws-socks, tpws, nfqws.
Их можно использовать как по отдельности, так и вместе. Например, вам надо сделать комбинацию
из методов, доступных только в tpws и только в nfqws. Их можно задействовать вместе.
tpws будет прозрачно локализовывать трафик на системе и применять свое дурение, nfqws будет дурить трафик,
исходящий с самой системы после обработки на tpws.
А можно на эту же систему повесить без параметров socks proxy, чтобы получать доступ к обходу блокировок через прокси.
Таким образом, все 3 режима вполне могут задействоваться вместе.
Так же безусловно и независимо, в добавок к стандартным оцпиям, применяются все custom скрипты в init.d/{sysv,openwrt,macos}/custom.d.
Применять ли дурение к HTTP : tpws-socks требует настройки параметров tpws, но не требует перехвата трафика.
Остальные оцпии требуют раздельно настройки перехвата трафика и опции самих демонов.
Каждая опция предполагет запуск одного инстанса соответствующего демона. Все различия методов дурения
для http, https, quic и т.д. должны быть отражены через схему мультистратегий.
В этом смысле настройка похожа на вариант winws на Windows, а перенос конфигов не должен представлять больших сложностей.
Основное правило настройки перехвата - перехватывайте только необходимый минимум.
Любой перехват лишнего - это бессмысленная нагрузка на вашу систему.
Опции демонов "--ipset" использовать запрещено. Это сделано намеренно и искусственно, чтобы не поощрать простой и
работающий, но неэффективный метод на *nix системах. Используйте ipset-ы режима ядра.
При необходимости пишите и задействуйте custom scripts.
Настройки демонов можно для удобства писать на нескольких строках, используя двойные или одинарные кавычки.
Чтобы задействовать стандартные обновляемые хост-листы из ipset, используйте маркер <HOSTLIST>.
Он будет заменен на параметры, соответствующие режиму MODE_FILTER, и будут подставлены реально существующие файлы.
Если MODE_FILTER не предполагает стандартного хостлиста, <HOSTLIST> будет заменен на пустую строку.
Стандартные хостлисты следует вставлять в финальных стратегиях (стратегиях по умолчанию), закрывающих цепочки по
группе параметров фильтра. Таких мест может быть несколько.
Не нужно использовать <HOSTLIST> в узких специализациях и в тех профилях, по которым точно не будет проходить
трафик с известными протоколами, откуда поддерживается извлечение имени хоста (http, tls, quic).
MODE_HTTP=1 # включение стандартной опции tpws в режиме socks
TPWS_SOCKS_ENABLE=0
# на каком порту будет слушать tpws socks. прослушивается только localhost и LAN.
TPPORT_SOCKS=987
# параметры tpws для режима socks
TPWS_SOCKS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
"
Применять ли дурение к последовательным http запросам в одном tcp соединении (http keeaplive). # включение стандартной опции tpws в прозрачном режиме
Относится только к nfqws. Выключение данной функции способно сэкономить загрузку процессора. TPWS_ENABLE=0
tpws всегда работает с http keepalive # какие tcp порты следует перенаправлять на tpws
TPWS_PORTS=80,443
# параметры tpws для прозрачного режима
TPWS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
"
MODE_HTTP_KEEPALIVE=0 # включение стандартной опции nfqws
NFQWS_ENABLE=0
# какие tcp и udp порты следует перенаправлять на nfqws с использованием connbytes ограничителя
# connbytes позволяет из каждого соединения перенаправить только заданное количество начальных пакетов по каждому направлению - на вход и на выход
# это более эффективная kernel-mode замена параметра nfqws --dpi-desync-cutoff=nX
NFQWS_PORTS_TCP=80,443
NFQWS_PORTS_UDP=443
# сколько начальных входящих и исходящих пакетов нужно перенаправлять на nfqws по каждому направлению
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_TCP_PKT_IN=3
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_UDP_PKT_IN=0
# есть трафик, исходящий сеанс для которого необходимо перенаправлять весь без ограничителей
# типичное применение - поддержка http keepalives на stateless DPI
# это существенно нагружает процессор. использовать только если понимаете зачем. чаще всего это не нужно.
# входящий трафик ограничивается по connbytes через параметры PKT_IN
# задать порты для перенаправления на nfqws без connbytes ограничителя
# если указываете здесь какие-то порты, желательно их убрать из версии с connbytes ограничителем
#NFQWS_PORTS_TCP_KEEPALIVE=80
#NFQWS_PORTS_UDP_KEEPALIVE=
# параметры nfqws
NFQWS_OPT="
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST>
"
Применять ли дурение к HTTPS :
MODE_HTTPS=1
Применять ли дурение к QUIC :
MODE_QUIC=0
Режим фильтрации хостов : Режим фильтрации хостов :
none - применять дурение ко всем хостам none - применять дурение ко всем хостам
ipset - ограничить дурение ipset-ом zapret/zapret6 ipset - ограничить дурение ipset-ом zapret/zapret6
hostlist - ограничить дурение списком хостов из файла hostlist - ограничить дурение списком хостов из файла
autohostlist - режим hostlist + распознавание блокировок и ведения автоматического листа autohostlist - режим hostlist + распознавание блокировок и ведение автоматического листа
MODE_FILTER=none MODE_FILTER=none
Опции tpws :
TPWS_OPT="--hostspell=HOST --split-http-req=method --split-pos=3"
Дополнительный низкоприоритетный профиль десинхронизации для режимов с MODE_FILTER=hostlist.
После реализации поддержки множественных профилей режимы нулевой фазы десинхронизации больше не применяются с хостлистом !
Для их применения требуется дополнительный профиль без хостлист фильтра.
#TPWS_OPT_SUFFIX="--mss 88"
Опции nfqws для атаки десинхронизации DPI :
DESYNC_MARK=0x40000000
DESYNC_MARK_POSTNAT=0x20000000
NFQWS_OPT_DESYNC="--dpi-desync=fake --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
Задание раздельных опций nfqws для http и https и для версий ip протоколов 4,6 :
NFQWS_OPT_DESYNC_HTTP="--dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
NFQWS_OPT_DESYNC_HTTPS="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=0 --dpi-desync-fooling=badsum"
NFQWS_OPT_DESYNC_HTTP6="--dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
NFQWS_OPT_DESYNC_HTTPS6="--wssize=1:6 --dpi-desync=split --dpi-desync-ttl=5 --dpi-desync-fooling=none"
Если какая-то из переменных NFQWS_OPT_DESYNC_HTTP/NFQWS_OPT_DESYNC_HTTPS не определена,
берется значение NFQWS_OPT_DESYNC.
Если какая-то из переменных NFQWS_OPT_DESYNC_HTTP6/NFQWS_OPT_DESYNC_HTTPS6 не определена,
берется значение NFQWS_OPT_DESYNC_HTTP/NFQWS_OPT_DESYNC_HTTPS.
Дополнительный низкоприоритетный профиль десинхронизации для режимов с MODE_FILTER=hostlist.
После реализации поддержки множественных профилей режимы нулевой фазы десинхронизации больше не применяются с хостлистом !
Для их применения требуется дополнительный профиль без хостлист фильтра.
#NFQWS_OPT_DESYNC_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTP_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTPS_SUFFIX="--wssize 1:6"
#NFQWS_OPT_DESYNC_HTTP6_SUFFIX="--dpi-desync=syndata"
#NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="--wssize 1:6"
Значения по умолчанию заполняются аналогично NFQWS_OPT_*.
Опции дурения для QUIC :
NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
NFQWS_OPT_DESYNC_QUIC6="--dpi-desync=hopbyhop"
Если NFQWS_OPT_DESYNC_QUIC6 не задано, то берется NFQWS_OPT_DESYNC_QUIC.
Настройка системы управления выборочным traffic offload (только если поддерживается) Настройка системы управления выборочным traffic offload (только если поддерживается)
donttouch : выборочное управление отключено, используется системная настройка, простой инсталлятор выключает системную настройку, если она не совместима с выбранным режимом donttouch : выборочное управление отключено, используется системная настройка, простой инсталлятор выключает системную настройку, если она не совместима с выбранным режимом
none : выборочное управление отключено, простой инсталлятор выключает системную настройку none : выборочное управление отключено, простой инсталлятор выключает системную настройку
@ -1494,8 +1504,11 @@ IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5" IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5"
Настройка режима autohostlist. Настройка режима autohostlist.
При увеличении AUTOHOSTLIST_RETRANS_THRESHOLD и использовании nfqws следует пересмотреть значения параметров
NFQWS_TCP_PKT_OUT и NFQWS_UDP_PKT_OUT. Все ретрансмиссии должны быть получены nfqws, иначе триггер "зависание запроса" не сработает.
AUTOHOSTLIST_RETRANS_THRESHOLD=3 AUTOHOSTLIST_RETRANS_THRESHOLD=3
AUTOHOSTLIST_FAIL_THRESHOLD=2 AUTOHOSTLIST_FAIL_THRESHOLD=3
AUTOHOSTLIST_FAIL_TIME=60 AUTOHOSTLIST_FAIL_TIME=60
AUTOHOSTLIST_DEBUG=0 AUTOHOSTLIST_DEBUG=0
@ -1537,6 +1550,7 @@ IFACE_WAN6="henet ipsec0"
Включаются только режимы, обеспечивающие перехват транзитного трафика. Включаются только режимы, обеспечивающие перехват транзитного трафика.
Возможно определить несколько интерфейсов следующим образом : IFACE_LAN="eth0 eth1 eth2" Возможно определить несколько интерфейсов следующим образом : IFACE_LAN="eth0 eth1 eth2"
Прикручивание к системе управления фаерволом или своей системе запуска Прикручивание к системе управления фаерволом или своей системе запуска
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -1591,18 +1605,15 @@ nfset-ы принадлежат только одной таблице, след
Вариант custom Вариант custom
-------------- --------------
custom код вынесен в отдельные shell includes. custom скрипты - это маленькие shell программы, управляющие нестандартными режимами применения zapret
Поддерживается старый вариант в или частными случаями, которые не могут быть интегрированы в основную часть без загромождения и замусоривания кода.
/opt/zapret/init.d/sysv/custom Для применеия custom следует помещать файлы в следующие директории в зависимости от вашей системы :
/opt/zapret/init.d/openwrt/custom /opt/zapret/init.d/sysv/custom.d
/opt/zapret/init.d/macos/custom /opt/zapret/init.d/openwrt/custom.d
Он считается устаревшим. Актуальный вариант - помещать отдельные скрипты там же, но в директорию "custom.d". /opt/zapret/init.d/macos/custom.d
Она будет просканирована стандартным образом, т.е. в алфавитном порядке, и каждый скрипт будет применен. Директория будет просканирована в алфавитном порядке, и каждый скрипт будет применен.
Рядом имеется "custom.d.examples". Это готовые скрипты, которые можно копировать в "custom.d". Рядом имеется "custom.d.examples". Это готовые скрипты, которые можно копировать в "custom.d".
Особо стоит отметить "10-inherit-*". Они наследуют стандартные режимы nfqws/tpws/tpws-socks. Их можно взять за основу для написания собственных.
Полезно, чтобы не писать код заново. Достаточно лишь скопировать соответствующий файл.
Можно наследовать и более сложным образом.
"10-inherit-tpws4http-nfqws4https" наследует для http tpws, а для https и quic - nfqws.
Для linux пишется код в функции Для linux пишется код в функции
zapret_custom_daemons zapret_custom_daemons
@ -1637,12 +1648,9 @@ FW_EXTRA_POST добавляет код после.
В linux функции-хелперы добавляют правило в начало цепочек, то есть перед уже имеющимися. В linux функции-хелперы добавляют правило в начало цепочек, то есть перед уже имеющимися.
Поэтому специализации должны идти после более общих вариантов. Поэтому специализации должны идти после более общих вариантов.
Поэтому наследования идут с префиксом 10, а остальные custom скрипты с префиксом 50. Для macos правило обратное. Там правила добавляются в конец.
Допустим, у вас есть особые правила для IP подсети youtube. Порты те же самые. По этой же причине фаервол в Linux сначала применяется в стандартном режиме, потом custom,
Включен и общий обход. Чтобы youtube пошел приоритетом, скрипт должен применяться после а в MacOS сначала custom, потом стандартный режим.
общего обхода.
Для macos правило обратное. Там правила добавляются в конец. Поэтому inherit скрипты
имеют префикс 90.
В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout, В macos firewall-функции ничего сами никуда не заносят. Их задача - лишь выдать текст в stdout,
содержащий правила для pf-якоря. Остальное сделает обертка. содержащий правила для pf-якоря. Остальное сделает обертка.
@ -1658,8 +1666,7 @@ custom скрипты могут использовать переменные
Полезные функции можно взять из примеров скриптов. Так же смотрите "common/*.sh". Полезные функции можно взять из примеров скриптов. Так же смотрите "common/*.sh".
Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи Используя хелпер функции, вы избавитесь от необходимости учитывать все возможные случаи
типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ... типа наличия/отсутствия ipv6, является ли система роутером, имена интерфейсов, ...
Хелперы это учитывают, вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и Хелперы это учитывают. Вам нужно сосредоточиться лишь на фильтрах {ip,nf}tables и параметрах демонов.
параметрах демонов.
Простая установка Простая установка

View File

@ -15,7 +15,7 @@ Tor поддерживает "из коробки" режим transparent proxy.
4) Завернуть через iptables или nftables трафик с порта назначения 443 и на ip адреса из ipset/nfset 'zapret' на соксификатор 4) Завернуть через iptables или nftables трафик с порта назначения 443 и на ip адреса из ipset/nfset 'zapret' на соксификатор
Тоже самое сделать с ipset/nfset 'ipban' для всех tcp портов. Тоже самое сделать с ipset/nfset 'ipban' для всех tcp портов.
Буду рассматривать систему на базе openwrt, где уже установлена система обхода dpi "zapret". Буду рассматривать систему на базе openwrt, где уже установлена система обхода dpi "zapret".
Если вам не нужны функции обхода DPI, можно выбрать режим MODE=filter. Если вам не нужны функции обхода DPI, его можно не включать. Обновление фильтра от этого не зависит.
* Сделать так, чтобы все время при загрузке системы на некотором порту возникал socks * Сделать так, чтобы все время при загрузке системы на некотором порту возникал socks

View File

@ -282,6 +282,14 @@ ipt PREROUTING -t mangle -i $DEVICE -m set --match-set ipban dst -m set ! --matc
# /etc/init.d/firewall restart # /etc/init.d/firewall restart
Чтобы правила обновлялись в процессе поднятия интерфейсов в системе, нужно внести параметр "reload" в указанное место :
--- /etc/config/firewall ---
config include
option path '/etc/firewall.user'
option reload '1'
----------------------------
--- Маркировка трафика nftables --- --- Маркировка трафика nftables ---
В новых openwrt по умолчанию установлен nftables, iptables отсутствует. В новых openwrt по умолчанию установлен nftables, iptables отсутствует.

View File

@ -1,7 +1,6 @@
# this script is an example describing how to run tpws on a custom port # this script is an example describing how to run tpws on a custom port
TPWS_OPT_EXTRA=${TPWS_OPT_EXTRA:---split-pos=2} TPWS_OPT_EXTRA=${TPWS_OPT_EXTRA:---split-pos=2}
TPWS_OPT_SUFFIX_EXTRA="${TPWS_OPT_SUFFIX_EXTRA:-}"
DPORTS_EXTRA=${DPORTS_EXTRA:-20443,20444,30000-30009} DPORTS_EXTRA=${DPORTS_EXTRA:-20443,20444,30000-30009}
alloc_dnum DNUM_EXTRA_TPWS alloc_dnum DNUM_EXTRA_TPWS
@ -14,7 +13,6 @@ zapret_custom_daemons()
tpws_apply_binds opt tpws_apply_binds opt
opt="$opt $TPWS_OPT_EXTRA" opt="$opt $TPWS_OPT_EXTRA"
filter_apply_hostlist_target opt filter_apply_hostlist_target opt
filter_apply_suffix opt "$TPWS_OPT_SUFFIX_EXTRA"
do_daemon $1 $DNUM_EXTRA_TPWS "$TPWS" "$opt" do_daemon $1 $DNUM_EXTRA_TPWS "$TPWS" "$opt"
} }

View File

@ -1,18 +0,0 @@
# this custom script applies tpws mode as it would be with MODE=tpws
OVERRIDE=tpws
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1
}
zapret_custom_firewall_v4()
{
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v4
}
zapret_custom_firewall_v6()
{
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v6
}

View File

@ -1,18 +0,0 @@
# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks
OVERRIDE=tpws-socks
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
MODE_OVERRIDE=$OVERRIDE zapret_do_daemons $1
}
zapret_custom_firewall_v4()
{
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v4
}
zapret_custom_firewall_v6()
{
MODE_OVERRIDE=$OVERRIDE pf_anchor_zapret_v6
}

View File

@ -15,6 +15,7 @@ IPSET_DIR=$ZAPRET_BASE/ipset
PIDDIR=/var/run PIDDIR=/var/run
[ -n "$TPPORT" ] || TPPORT=988 [ -n "$TPPORT" ] || TPPORT=988
[ -n "$TPPORT_SOCKS" ] || TPPORT=987
[ -n "$WS_USER" ] || WS_USER=daemon [ -n "$WS_USER" ] || WS_USER=daemon
TPWS_WAIT="--bind-wait-ifup=30 --bind-wait-ip=30" 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"
@ -117,8 +118,6 @@ zapret_do_firewall()
[ "$1" = 1 -a -n "$INIT_FW_PRE_UP_HOOK" ] && $INIT_FW_PRE_UP_HOOK [ "$1" = 1 -a -n "$INIT_FW_PRE_UP_HOOK" ] && $INIT_FW_PRE_UP_HOOK
[ "$1" = 0 -a -n "$INIT_FW_PRE_DOWN_HOOK" ] && $INIT_FW_PRE_DOWN_HOOK [ "$1" = 0 -a -n "$INIT_FW_PRE_DOWN_HOOK" ] && $INIT_FW_PRE_DOWN_HOOK
case "${MODE_OVERRIDE:-$MODE}" in
tpws|filter|custom)
if [ "$1" = "1" ] ; then if [ "$1" = "1" ] ; then
pf_anchor_root || return 1 pf_anchor_root || return 1
pf_anchors_create pf_anchors_create
@ -127,8 +126,6 @@ zapret_do_firewall()
else else
pf_anchors_clear pf_anchors_clear
fi fi
;;
esac
[ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK [ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK
[ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK [ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK
@ -150,49 +147,36 @@ zapret_restart_firewall()
} }
standard_mode_daemons()
{
local opt
if [ "$1" = "1" ] && [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] ; then
echo "both ipv4 and ipv6 are disabled. nothing to do"
else
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
opt="--user=root --port=$TPPORT"
tpws_apply_binds opt
opt="$opt $TPWS_OPT"
filter_apply_hostlist_target opt
do_daemon $1 1 "$TPWS" "$opt"
}
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
opt="--socks --user=$WS_USER --port=$TPPORT_SOCKS"
tpws_apply_socks_binds opt
opt="$opt $TPWS_OPT"
filter_apply_hostlist_target opt
do_daemon $1 2 "$TPWS" "$opt"
}
fi
}
zapret_do_daemons() zapret_do_daemons()
{ {
# $1 - 1 - run, 0 - stop # $1 - 1 - run, 0 - stop
local opt standard_mode_daemons $1
case "${MODE_OVERRIDE:-$MODE}" in
tpws)
[ "$1" = "1" ] && [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && {
echo "both ipv4 and ipv6 are disabled. nothing to do"
return 0
}
# MacOS requires root. kernel hardcoded requirement for /dev/pf ioctls
opt="--user=root --port=$TPPORT"
tpws_apply_binds opt
opt="$opt $TPWS_OPT"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
do_daemon $1 1 "$TPWS" "$opt"
;;
tpws-socks)
[ "$1" = "1" ] && [ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && {
echo "both ipv4 and ipv6 are disabled. nothing to do"
return 0
}
opt="--socks --user=$WS_USER --port=$TPPORT"
tpws_apply_socks_binds opt
opt="$opt $TPWS_OPT"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
do_daemon $1 1 "$TPWS" "$opt"
;;
filter)
;;
custom)
custom_runner zapret_custom_daemons $1 custom_runner zapret_custom_daemons $1
;;
*)
echo "unsupported MODE=$MODE"
return 1
;;
esac
return 0 return 0
} }

View File

@ -1,25 +0,0 @@
# this custom script applies nfqws mode as it would be with MODE=nfqws
OVERRIDE=nfqws
zapret_custom_daemons()
{
# stop logic is managed by procd
local MODE_OVERRIDE=$OVERRIDE
start_daemons_procd
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=$OVERRIDE
zapret_apply_firewall_rules_nft
}

View File

@ -1,25 +0,0 @@
# this custom script applies tpws mode as it would be with MODE=tpws
OVERRIDE=tpws
zapret_custom_daemons()
{
# stop logic is managed by procd
local MODE_OVERRIDE=$OVERRIDE
start_daemons_procd
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=$OVERRIDE
zapret_apply_firewall_rules_nft
}

View File

@ -1,25 +0,0 @@
# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks
OVERRIDE=tpws-socks
zapret_custom_daemons()
{
# stop logic is managed by procd
local MODE_OVERRIDE=$OVERRIDE
start_daemons_procd
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=$OVERRIDE
zapret_apply_firewall_rules_nft
}

View File

@ -1,35 +0,0 @@
# this custom script demonstrates how to apply tpws to http and nfqws to https and quic
# it's desired that inherited basic rules are low priority to allow specializations and exceptions in other custom scripts
nfqws_tpws_inheritor()
{
# $1 - inherited function
# $2 - 1 - run, 0 - stop
local MODE_OVERRIDE
[ "$MODE_HTTP" = "1" ] && {
MODE_OVERRIDE=tpws MODE_HTTPS=0 MODE_QUIC=0 $1 $2
}
[ "$MODE_HTTPS" = "1" -o "$MODE_QUIC" = "1" ] && {
MODE_OVERRIDE=nfqws MODE_HTTP=0 $1 $2
}
}
zapret_custom_daemons()
{
# stop logic is managed by procd
nfqws_tpws_inheritor start_daemons_procd
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
nfqws_tpws_inheritor zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
nfqws_tpws_inheritor zapret_apply_firewall_rules_nft
}

View File

@ -1,5 +1,7 @@
# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering # this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering
# need to add to config : NFQWS_OPT_DESYNC_DHT="--dpi-desync=fake --dpi-desync-ttl=5"
# can override in config :
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---dpi-desync=tamper}"
alloc_dnum DNUM_DHT4ALL alloc_dnum DNUM_DHT4ALL
alloc_qnum QNUM_DHT4ALL alloc_qnum QNUM_DHT4ALL
@ -17,12 +19,11 @@ zapret_custom_firewall()
local f uf4 uf6 local f uf4 uf6
local first_packet_only="$ipt_connbytes 1:1" local first_packet_only="$ipt_connbytes 1:1"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
f='-p udp -m length --length 109:407 -m u32 --u32' f='-p udp -m length --length 109:407 -m u32 --u32'
uf4='0>>22&0x3C@8>>16=0x6431' uf4='0>>22&0x3C@8>>16=0x6431'
uf6='48>>16=0x6431' uf6='48>>16=0x6431'
fw_nfqws_post $1 "$f $uf4 $desync $first_packet_only" "$f $uf6 $desync $first_packet_only" $QNUM_DHT4ALL fw_nfqws_post $1 "$f $uf4 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL
} }
zapret_custom_firewall_nft() zapret_custom_firewall_nft()
@ -31,8 +32,7 @@ zapret_custom_firewall_nft()
local f local f
local first_packet_only="$nft_connbytes 1" local first_packet_only="$nft_connbytes 1"
local desync="mark and $DESYNC_MARK == 0"
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431" f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
nft_fw_nfqws_post "$f $desync $first_packet_only" "$f $desync $first_packet_only" $QNUM_DHT4ALL nft_fw_nfqws_post "$f $first_packet_only" "$f $first_packet_only" $QNUM_DHT4ALL
} }

View File

@ -1,4 +1,4 @@
# this custom script in addition to MODE=nfqws runs desync of some udp packets to discord subnets # this custom script runs desync of some udp packets to discord subnets
# idea taken from community. not tested and not optimized by author. # idea taken from community. not tested and not optimized by author.
# can override in config : # can override in config :
@ -24,7 +24,6 @@ zapret_custom_firewall()
local f local f
local first_packets_only="$ipt_connbytes 1:3" local first_packets_only="$ipt_connbytes 1:3"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
local DISCORD_PORTS_IPT=$(replace_char - : $DISCORD_PORTS) local DISCORD_PORTS_IPT=$(replace_char - : $DISCORD_PORTS)
local dest_set="-m set --match-set $DISCORD_SET_NAME dst" local dest_set="-m set --match-set $DISCORD_SET_NAME dst"
local subnet local subnet
@ -40,7 +39,7 @@ zapret_custom_firewall()
} }
f="-p udp -m multiport --dports $DISCORD_PORTS_IPT" f="-p udp -m multiport --dports $DISCORD_PORTS_IPT"
fw_nfqws_post $1 "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD fw_nfqws_post $1 "$f $first_packets_only $dest_set" "" $QNUM_DISCORD
[ "$1" = 1 ] || { [ "$1" = 1 ] || {
ipset destroy $DISCORD_SET_NAME 2>/dev/null ipset destroy $DISCORD_SET_NAME 2>/dev/null
@ -53,7 +52,6 @@ zapret_custom_firewall_nft()
local f local f
local first_packets_only="$nft_connbytes 1-3" local first_packets_only="$nft_connbytes 1-3"
local desync="mark and $DESYNC_MARK == 0"
local dest_set="ip daddr @$DISCORD_SET_NAME" local dest_set="ip daddr @$DISCORD_SET_NAME"
local subnets local subnets
@ -65,7 +63,7 @@ zapret_custom_firewall_nft()
nft_add_set_element $DISCORD_SET_NAME "$subnets" nft_add_set_element $DISCORD_SET_NAME "$subnets"
f="udp dport {$DISCORD_PORTS}" f="udp dport {$DISCORD_PORTS}"
nft_fw_nfqws_post "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD nft_fw_nfqws_post "$f $first_packets_only $dest_set" "" $QNUM_DISCORD
} }
zapret_custom_firewall_nft_flush() zapret_custom_firewall_nft_flush()

View File

@ -1,37 +0,0 @@
# this custom script runs desync to all QUIC initial packets, without ipset/hostlist filtering
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
alloc_dnum DNUM_QUIC4ALL
alloc_qnum QNUM_QUIC4ALL
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
local opt="--qnum=$QNUM_QUIC4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
run_daemon $DNUM_QUIC4ALL $NFQWS "$opt"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local f
local first_packets_only="$ipt_connbytes 1:3"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
f="-p udp -m multiport --dports $QUIC_PORTS_IPT"
fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local f
local first_packets_only="$nft_connbytes 1-3"
local desync="mark and $DESYNC_MARK == 0"
f="udp dport {$QUIC_PORTS}"
nft_fw_nfqws_post "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL
}

View File

@ -6,7 +6,6 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
. "$ZAPRET_CONFIG" . "$ZAPRET_CONFIG"
. "$ZAPRET_BASE/common/base.sh" . "$ZAPRET_BASE/common/base.sh"
. "$ZAPRET_BASE/common/fwtype.sh" . "$ZAPRET_BASE/common/fwtype.sh"
. "$ZAPRET_BASE/common/queue.sh"
. "$ZAPRET_BASE/common/linux_iphelper.sh" . "$ZAPRET_BASE/common/linux_iphelper.sh"
. "$ZAPRET_BASE/common/ipt.sh" . "$ZAPRET_BASE/common/ipt.sh"
. "$ZAPRET_BASE/common/nft.sh" . "$ZAPRET_BASE/common/nft.sh"
@ -17,6 +16,7 @@ CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
[ -n "$QNUM" ] || QNUM=200 [ -n "$QNUM" ] || QNUM=200
[ -n "$TPPORT" ] || TPPORT=988 [ -n "$TPPORT" ] || TPPORT=988
[ -n "$TPPORT_SOCKS" ] || TPPORT_SOCKS=987
[ -n "$WS_USER" ] || WS_USER=daemon [ -n "$WS_USER" ] || WS_USER=daemon
[ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000 [ -n "$DESYNC_MARK" ] || DESYNC_MARK=0x40000000
[ -n "$DESYNC_MARK_POSTNAT" ] || DESYNC_MARK_POSTNAT=0x20000000 [ -n "$DESYNC_MARK_POSTNAT" ] || DESYNC_MARK_POSTNAT=0x20000000
@ -32,8 +32,6 @@ IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
IPSET_EXCLUDE="-m set ! --match-set nozapret" IPSET_EXCLUDE="-m set ! --match-set nozapret"
IPSET_EXCLUDE6="-m set ! --match-set nozapret6" IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
apply_unspecified_desync_modes
# can be multiple ipv6 outgoing interfaces # can be multiple ipv6 outgoing interfaces
# uplink from isp, tunnelbroker, vpn, ... # uplink from isp, tunnelbroker, vpn, ...

View File

@ -114,68 +114,30 @@ tpws_apply_socks_binds()
} }
start_daemons_procd() standard_mode_daemons()
{ {
local opt qn qns qn6 qns6 local opt
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$TPWS_OPT" && {
case "${MODE_OVERRIDE:-$MODE}" in
tpws)
opt="--port=$TPPORT $TPWS_OPT" opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt filter_apply_hostlist_target opt
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
run_tpws 1 "$opt" run_tpws 1 "$opt"
;;
tpws-socks)
opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
run_tpws_socks 1 "$opt"
;;
nfqws)
# quite complex but we need to minimize nfqws processes to save RAM
get_nfqws_qnums qn qns qn6 qns6
[ -z "$qn" ] || {
opt="--qnum=$qn $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTP"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTP_SUFFIX"
run_daemon 1 "$NFQWS" "$opt"
} }
[ -z "$qns" ] || [ "$qns" = "$qn" ] || { [ "$TPWS_SOCKS_ENABLE" = 1 ] && {
opt="--qnum=$qns $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS" opt="--port=$TPPORT_SOCKS $TPWS_OPT"
filter_apply_hostlist_target opt filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS_SUFFIX" run_tpws_socks 2 "$opt"
run_daemon 2 "$NFQWS" "$opt"
} }
[ -z "$qn6" ] || [ "$qn6" = "$qn" ] || [ "$qn6" = "$qns" ] || { [ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$NFQWS_OPT" && {
opt="--qnum=$qn6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTP6" opt="--qnum=$QNUM $NFQWS_OPT"
filter_apply_hostlist_target opt filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTP6_SUFFIX"
run_daemon 3 "$NFQWS" "$opt" run_daemon 3 "$NFQWS" "$opt"
} }
[ -z "$qns6" ] || [ "$qns6" = "$qn" ] || [ "$qns6" = "$qns" ] || [ "$qns6" = "$qn6" ] || { }
opt="--qnum=$qns6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_HTTPS6"
filter_apply_hostlist_target opt start_daemons_procd()
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS6_SUFFIX" {
run_daemon 4 "$NFQWS" "$opt" standard_mode_daemons
} custom_runner zapret_custom_daemons
get_nfqws_qnums_quic qn qn6
[ -z "$qn" ] || {
opt="--qnum=$qn $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_QUIC_SUFFIX"
run_daemon 10 "$NFQWS" "$opt"
}
[ -z "$qn6" ] || [ "$qn6" = "$qn" ] || {
opt="--qnum=$qn6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC6"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_QUIC6_SUFFIX"
run_daemon 11 "$NFQWS" "$opt"
}
;;
custom)
custom_runner zapret_custom_daemons $1
;;
esac
return 0 return 0
} }

View File

@ -1,25 +0,0 @@
# this custom script applies nfqws mode as it would be with MODE=nfqws
OVERRIDE=nfqws
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_daemons $1
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=$OVERRIDE
zapret_apply_firewall_rules_nft
}

View File

@ -1,25 +0,0 @@
# this custom script applies tpws mode as it would be with MODE=tpws
OVERRIDE=tpws
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_daemons $1
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=$OVERRIDE
zapret_apply_firewall_rules_nft
}

View File

@ -1,25 +0,0 @@
# this custom script applies tpws-socks mode as it would be with MODE=tpws-socks
OVERRIDE=tpws-socks
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_daemons $1
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local MODE_OVERRIDE=$OVERRIDE
zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local MODE_OVERRIDE=$OVERRIDE
zapret_apply_firewall_rules_nft
}

View File

@ -1,35 +0,0 @@
# this custom script demonstrates how to apply tpws to http and nfqws to https and quic
# it's desired that inherited basic rules are low priority to allow specializations and exceptions in other custom scripts
nfqws_tpws_inheritor()
{
# $1 - inherited function
# $2 - 1 - run, 0 - stop
local MODE_OVERRIDE
[ "$MODE_HTTP" = "1" ] && {
MODE_OVERRIDE=tpws MODE_HTTPS=0 MODE_QUIC=0 $1 $2
}
[ "$MODE_HTTPS" = "1" -o "$MODE_QUIC" = "1" ] && {
MODE_OVERRIDE=nfqws MODE_HTTP=0 $1 $2
}
}
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
nfqws_tpws_inheritor zapret_do_daemons $1
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
nfqws_tpws_inheritor zapret_do_firewall_rules_ipt $1
}
zapret_custom_firewall_nft()
{
# stop logic is not required
nfqws_tpws_inheritor zapret_apply_firewall_rules_nft
}

View File

@ -1,5 +1,7 @@
# this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering # this custom script runs desync to DHT packets with udp payload length 101..399 , without ipset/hostlist filtering
# need to add to config : NFQWS_OPT_DESYNC_DHT="--dpi-desync=fake --dpi-desync-ttl=5"
# can override in config :
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---dpi-desync=tamper}"
alloc_dnum DNUM_DHT4ALL alloc_dnum DNUM_DHT4ALL
alloc_qnum QNUM_DHT4ALL alloc_qnum QNUM_DHT4ALL
@ -17,13 +19,11 @@ zapret_custom_firewall()
local f uf4 uf6 local f uf4 uf6
local first_packet_only="$ipt_connbytes 1:1" local first_packet_only="$ipt_connbytes 1:1"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
f='-p udp -m length --length 109:407 -m u32 --u32' f='-p udp -m length --length 109:407 -m u32 --u32'
uf4='0>>22&0x3C@8>>16=0x6431' uf4='0>>22&0x3C@8>>16=0x6431'
uf6='48>>16=0x6431' uf6='48>>16=0x6431'
fw_nfqws_post $1 "$f $uf4 $desync $first_packet_only" "$f $uf6 $desync $first_packet_only" $QNUM_DHT4ALL fw_nfqws_post $1 "$f $uf4 $first_packet_only" "$f $uf6 $first_packet_only" $QNUM_DHT4ALL
} }
zapret_custom_firewall_nft() zapret_custom_firewall_nft()
{ {
@ -31,9 +31,7 @@ zapret_custom_firewall_nft()
local f local f
local first_packet_only="$nft_connbytes 1" local first_packet_only="$nft_connbytes 1"
local desync="mark and $DESYNC_MARK == 0"
f="meta length 109-407 meta l4proto udp @th,64,16 0x6431" f="meta length 109-407 meta l4proto udp @th,64,16 0x6431"
nft_fw_nfqws_post "$f $desync $first_packet_only" "$f $desync $first_packet_only" $QNUM_DHT4ALL nft_fw_nfqws_post "$f $first_packet_only" "$f $first_packet_only" $QNUM_DHT4ALL
} }

View File

@ -1,4 +1,4 @@
# this custom script in addition to MODE=nfqws runs desync of some udp packets to discord subnets # this custom script runs desync of some udp packets to discord subnets
# idea taken from community. not tested and not optimized by author. # idea taken from community. not tested and not optimized by author.
# can override in config : # can override in config :
@ -24,7 +24,6 @@ zapret_custom_firewall()
local f local f
local first_packets_only="$ipt_connbytes 1:3" local first_packets_only="$ipt_connbytes 1:3"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
local DISCORD_PORTS_IPT=$(replace_char - : $DISCORD_PORTS) local DISCORD_PORTS_IPT=$(replace_char - : $DISCORD_PORTS)
local dest_set="-m set --match-set $DISCORD_SET_NAME dst" local dest_set="-m set --match-set $DISCORD_SET_NAME dst"
local subnet local subnet
@ -40,7 +39,7 @@ zapret_custom_firewall()
} }
f="-p udp -m multiport --dports $DISCORD_PORTS_IPT" f="-p udp -m multiport --dports $DISCORD_PORTS_IPT"
fw_nfqws_post $1 "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD fw_nfqws_post $1 "$f $first_packets_only $dest_set" "" $QNUM_DISCORD
[ "$1" = 1 ] || { [ "$1" = 1 ] || {
ipset destroy $DISCORD_SET_NAME 2>/dev/null ipset destroy $DISCORD_SET_NAME 2>/dev/null
@ -53,7 +52,6 @@ zapret_custom_firewall_nft()
local f local f
local first_packets_only="$nft_connbytes 1-3" local first_packets_only="$nft_connbytes 1-3"
local desync="mark and $DESYNC_MARK == 0"
local dest_set="ip daddr @$DISCORD_SET_NAME" local dest_set="ip daddr @$DISCORD_SET_NAME"
local subnets local subnets
@ -65,7 +63,7 @@ zapret_custom_firewall_nft()
nft_add_set_element $DISCORD_SET_NAME "$subnets" nft_add_set_element $DISCORD_SET_NAME "$subnets"
f="udp dport {$DISCORD_PORTS}" f="udp dport {$DISCORD_PORTS}"
nft_fw_nfqws_post "$f $desync $first_packets_only $dest_set" "" $QNUM_DISCORD nft_fw_nfqws_post "$f $first_packets_only $dest_set" "" $QNUM_DISCORD
} }
zapret_custom_firewall_nft_flush() zapret_custom_firewall_nft_flush()

View File

@ -1,37 +0,0 @@
# this custom script runs desync to all QUIC initial packets, without ipset/hostlist filtering
# need to add to config : NFQWS_OPT_DESYNC_QUIC="--dpi-desync=fake"
# NOTE : do not use TTL fooling. chromium QUIC engine breaks sessions if TTL expired in transit received
alloc_dnum DNUM_QUIC4ALL
alloc_qnum QNUM_QUIC4ALL
zapret_custom_daemons()
{
# $1 - 1 - run, 0 - stop
local opt="--qnum=$QNUM_QUIC4ALL $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
do_nfqws $1 $DNUM_QUIC4ALL "$opt"
}
zapret_custom_firewall()
{
# $1 - 1 - run, 0 - stop
local f
local first_packets_only="$ipt_connbytes 1:3"
local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK"
f="-p udp -m multiport --dports $QUIC_PORTS_IPT"
fw_nfqws_post $1 "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL
}
zapret_custom_firewall_nft()
{
# stop logic is not required
local f
local first_packets_only="$nft_connbytes 1-3"
local desync="mark and $DESYNC_MARK == 0"
f="udp dport {$QUIC_PORTS}"
nft_fw_nfqws_post "$f $desync $first_packets_only" "$f $desync $first_packets_only" $QNUM_QUIC4ALL
}

View File

@ -6,7 +6,6 @@ ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
. "$ZAPRET_CONFIG" . "$ZAPRET_CONFIG"
. "$ZAPRET_BASE/common/base.sh" . "$ZAPRET_BASE/common/base.sh"
. "$ZAPRET_BASE/common/fwtype.sh" . "$ZAPRET_BASE/common/fwtype.sh"
. "$ZAPRET_BASE/common/queue.sh"
. "$ZAPRET_BASE/common/linux_iphelper.sh" . "$ZAPRET_BASE/common/linux_iphelper.sh"
. "$ZAPRET_BASE/common/ipt.sh" . "$ZAPRET_BASE/common/ipt.sh"
. "$ZAPRET_BASE/common/nft.sh" . "$ZAPRET_BASE/common/nft.sh"
@ -76,9 +75,9 @@ IPSET_CR="$ZAPRET_BASE/ipset/create_ipset.sh"
[ -n "$QNUM" ] || QNUM=200 [ -n "$QNUM" ] || QNUM=200
[ -n "$NFQWS" ] || NFQWS="$ZAPRET_BASE/nfq/nfqws" [ -n "$NFQWS" ] || NFQWS="$ZAPRET_BASE/nfq/nfqws"
NFQWS_OPT_BASE="$USEROPT --dpi-desync-fwmark=$DESYNC_MARK" NFQWS_OPT_BASE="$USEROPT --dpi-desync-fwmark=$DESYNC_MARK"
apply_unspecified_desync_modes
[ -n "$TPPORT" ] || TPPORT=988 [ -n "$TPPORT" ] || TPPORT=988
[ -n "$TPPORT_SOCKS" ] || TPPORT_SOCKS=987
[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws" [ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
TPWS_LOCALHOST4=127.0.0.127 TPWS_LOCALHOST4=127.0.0.127
@ -280,69 +279,35 @@ create_ipset()
} }
standard_mode_daemons()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt
do_tpws $1 1 "$opt"
}
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
opt="--port=$TPPORT_SOCKS $TPWS_OPT"
filter_apply_hostlist_target opt
do_tpws_socks $1 2 "$opt"
}
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && {
opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT"
filter_apply_hostlist_target opt
do_nfqws $1 3 "$opt"
}
}
zapret_do_daemons() zapret_do_daemons()
{ {
# $1 - 1 - run, 0 - stop # $1 - 1 - run, 0 - stop
local opt qn qns qn6 qns6 standard_mode_daemons $1
case "${MODE_OVERRIDE:-$MODE}" in
tpws)
opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
do_tpws $1 1 "$opt"
;;
tpws-socks)
opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$TPWS_OPT_SUFFIX"
do_tpws_socks $1 1 "$opt"
;;
nfqws)
get_nfqws_qnums qn qns qn6 qns6
[ -z "$qn" ] || {
opt="--qnum=$qn $NFQWS_OPT_DESYNC_HTTP"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTP_SUFFIX"
do_nfqws $1 1 "$opt"
}
[ -z "$qns" ] || [ "$qns" = "$qn" ] || {
opt="--qnum=$qns $NFQWS_OPT_DESYNC_HTTPS"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS_SUFFIX"
do_nfqws $1 2 "$opt"
}
[ -z "$qn6" ] || [ "$qn6" = "$qn" ] || [ "$qn6" = "$qns" ] || {
opt="--qnum=$qn6 $NFQWS_OPT_DESYNC_HTTP6"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTP6_SUFFIX"
do_nfqws $1 3 "$opt"
}
[ -z "$qns6" ] || [ "$qns6" = "$qn" ] || [ "$qns6" = "$qns" ] || [ "$qns6" = "$qn6" ] || {
opt="--qnum=$qns6 $NFQWS_OPT_DESYNC_HTTPS6"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_HTTPS6_SUFFIX"
do_nfqws $1 4 "$opt"
}
get_nfqws_qnums_quic qn qn6
[ -z "$qn" ] || {
opt="--qnum=$qn $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_QUIC_SUFFIX"
do_nfqws $1 10 "$opt"
}
[ -z "$qn6" ] || [ "$qn6" = "$qn" ] || {
opt="--qnum=$qn6 $NFQWS_OPT_BASE $NFQWS_OPT_DESYNC_QUIC6"
filter_apply_hostlist_target opt
filter_apply_suffix opt "$NFQWS_OPT_DESYNC_QUIC6_SUFFIX"
do_nfqws $1 11 "$opt"
}
;;
custom)
custom_runner zapret_custom_daemons $1 custom_runner zapret_custom_daemons $1
;;
esac
return 0 return 0
} }
@ -354,4 +319,3 @@ zapret_stop_daemons()
{ {
zapret_do_daemons 0 "$@" zapret_do_daemons 0 "$@"
} }

View File

@ -5,6 +5,9 @@
EXEDIR="$(dirname "$0")" EXEDIR="$(dirname "$0")"
EXEDIR="$(cd "$EXEDIR"; pwd)" EXEDIR="$(cd "$EXEDIR"; pwd)"
ZAPRET_BASE=${ZAPRET_BASE:-"$EXEDIR"} ZAPRET_BASE=${ZAPRET_BASE:-"$EXEDIR"}
ZAPRET_TARGET=${ZAPRET_TARGET:-/opt/zapret}
ZAPRET_TARGET_RW=${ZAPRET_RW:-"$ZAPRET_TARGET"}
ZAPRET_TARGET_CONFIG="$ZAPRET_TARGET_RW/config"
ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"} ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"}
ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"} ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
ZAPRET_CONFIG_DEFAULT="$ZAPRET_BASE/config.default" ZAPRET_CONFIG_DEFAULT="$ZAPRET_BASE/config.default"
@ -24,13 +27,8 @@ IPSET_DIR="$ZAPRET_BASE/ipset"
. "$ZAPRET_BASE/common/installer.sh" . "$ZAPRET_BASE/common/installer.sh"
. "$ZAPRET_BASE/common/virt.sh" . "$ZAPRET_BASE/common/virt.sh"
# install target
ZAPRET_TARGET=${ZAPRET_TARGET:-/opt/zapret}
GET_LIST="$IPSET_DIR/get_config.sh" GET_LIST="$IPSET_DIR/get_config.sh"
[ -n "$TPPORT" ] || TPPORT=988
check_readonly_system() check_readonly_system()
{ {
local RO local RO
@ -102,112 +100,107 @@ install_binaries()
} }
} }
select_mode_mode() ws_opt_validate()
{ {
local edited v vars MODES="tpws tpws-socks nfqws filter custom" # ПРИМЕЧАНИЕ ДЛЯ РАСПРОСТРАНИТЕЛЕЙ КОПИПАСТЫ
[ "$SYSTEM" = "macos" ] && MODES="tpws tpws-socks filter custom" # ЭТОТ КОД СДЕЛАН СПЕЦИАЛЬНО ДЛЯ ВАС, ЧТОБЫ ВЫ НЕ ПОСТИЛИ В СЕТЬ ПЛОХИЕ РЕЦЕПТЫ
echo # ЕСЛИ ВАМ ХОЧЕТСЯ ЕГО УДАЛИТЬ И НАПИСАТЬ ИНСТРУКЦИЮ КАК ЕГО УДАЛЯТЬ, ВЫ ДЕЛАЕТЕ ХРЕНОВУЮ УСЛУГУ. НАПИШИТЕ ЛУЧШЕ custom script.
echo select MODE : # custom script - ЭТО ФАЙЛИК, КОТОРЫЙ ДОСТАТОЧНО СКОПИРОВАТЬ В НУЖНУЮ ДИРЕКТОРИЮ, ЧТОБЫ ОН СДЕЛАЛ ТОЖЕ САМОЕ, НО ЭФФЕКТИВНО.
ask_list MODE "$MODES" tpws && write_config_var MODE # ФИЛЬТРАЦИЯ ПО IPSET В ЯДРЕ НЕСРАВНИМО ЭФФЕКТИВНЕЕ, ЧЕМ ПЕРЕКИДЫВАТЬ ВСЕ ПАКЕТЫ В nfqws И ТАМ ФИЛЬТРОВАТЬ
# --ipset СУЩЕСТВУЕТ ТОЛЬКО ДЛЯ ВИНДЫ И LINUX СИСТЕМ БЕЗ ipset (НАПРИМЕР, Android).
# И ТОЛЬКО ПО ЭТОЙ ПРИЧИНЕ ОНО НЕ ВЫКИНУТО ПОЛНОСТЬЮ ИЗ LINUX ВЕРСИИ
has_bad_ws_options "$1" && {
help_bad_ws_options
return 1
}
return 0
}
select_mode_group()
{
# $1 - ENABLE var name
# $2 - ask text
# $3 - vars
# $4 - validator func
# $5 - validator func param var
local enabled var v edited bad Y param
case $MODE in
tpws|tpws-socks)
vars="TPWS_OPT TPWS_OPT_SUFFIX"
;;
nfqws)
vars="NFQWS_OPT_DESYNC NFQWS_OPT_DESYNC_SUFFIX NFQWS_OPT_DESYNC_HTTP NFQWS_OPT_DESYNC_HTTP_SUFFIX NFQWS_OPT_DESYNC_HTTPS NFQWS_OPT_DESYNC_HTTPS_SUFFIX NFQWS_OPT_DESYNC_HTTP6 NFQWS_OPT_DESYNC_HTTP6_SUFFIX NFQWS_OPT_DESYNC_HTTPS6 NFQWS_OPT_DESYNC_HTTPS6_SUFFIX NFQWS_OPT_DESYNC_QUIC NFQWS_OPT_DESYNC_QUIC_SUFFIX NFQWS_OPT_DESYNC_QUIC6 NFQWS_OPT_DESYNC_QUIC6_SUFFIX"
;;
esac
[ -n "$vars" ] && {
echo echo
while [ 1=1 ]; do ask_yes_no_var $1 "$2"
for var in $vars; do write_config_var $1
eval v="\$$var" eval enabled=\$$1
echo $var=\"$v\" [ "$enabled" = 1 ] && {
done echo
ask_yes_no N "do you want to edit the options" || { while : ; do
list_vars $3
bad=0; Y=N
[ -n "$4" ] && {
eval param="\$$5"
$4 "$param"; bad=$?
[ "$bad" = 1 ] && Y=Y
}
ask_yes_no $Y "do you want to edit the options" || {
[ "$bad" = 1 ] && {
echo installer will not allow to use bad options. exiting.
exitp 3
}
[ -n "$edited" ] && { [ -n "$edited" ] && {
for var in $vars; do for var in $3; do
write_config_var $var write_config_var $var
done done
} }
break break
} }
edit_vars $vars edit_vars $3
edited=1 edited=1
echo ..edited.. echo ..edited..
done done
} }
[ "$MODE" = custom ] && { }
select_mode_tpws_socks()
{
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_SOCKS_OPT"
# --ipset allowed here
select_mode_group TPWS_SOCKS_ENABLE "enable tpws socks mode on port $TPPORT_SOCKS ?" "TPPORT_SOCKS TPWS_SOCKS_OPT"
}
select_mode_tpws()
{
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="TPWS_OPT"
select_mode_group TPWS_ENABLE "enable tpws transparent mode ?" "TPWS_PORTS TPWS_OPT" ws_opt_validate TPWS_OPT
}
select_mode_nfqws()
{
local EDITVAR_NEWLINE_DELIMETER="--new" EDITVAR_NEWLINE_VARS="NFQWS_OPT"
select_mode_group NFQWS_ENABLE "enable nfqws ?" "NFQWS_PORTS_TCP NFQWS_PORTS_UDP NFQWS_TCP_PKT_OUT NFQWS_TCP_PKT_IN NFQWS_UDP_PKT_OUT NFQWS_UDP_PKT_IN NFQWS_PORTS_TCP_KEEPALIVE NFQWS_PORTS_UDP_KEEPALIVE NFQWS_OPT" ws_opt_validate NFQWS_OPT
}
select_mode_mode()
{
select_mode_tpws_socks
select_mode_tpws
[ "$UNAME" = Linux ] && select_mode_nfqws
echo echo
echo "current custom scripts :" echo "current custom scripts in $CUSTOM_DIR/custom.d:"
[ -f "$CUSTOM_DIR/custom" ] && echo "legacy custom script $CUSTOM_DIR/custom"
echo "$CUSTOM_DIR/custom.d :"
[ -d "$CUSTOM_DIR/custom.d" ] && ls "$CUSTOM_DIR/custom.d" [ -d "$CUSTOM_DIR/custom.d" ] && ls "$CUSTOM_DIR/custom.d"
echo "Make sure this is ok" echo "Make sure this is ok"
echo echo
}
}
select_mode_http()
{
[ "$MODE" != "filter" ] && [ "$MODE" != "tpws-socks" ] && {
echo
ask_yes_no_var MODE_HTTP "enable http support"
write_config_var MODE_HTTP
}
}
select_mode_keepalive()
{
[ "$MODE" = "nfqws" ] && [ "$MODE_HTTP" = "1" ] && {
echo
echo enable keep alive support only if DPI checks every outgoing packet for http signature
echo dont enable otherwise because it consumes more cpu resources
ask_yes_no_var MODE_HTTP_KEEPALIVE "enable http keep alive support"
write_config_var MODE_HTTP_KEEPALIVE
}
}
select_mode_https()
{
[ "$MODE" != "filter" ] && [ "$MODE" != "tpws-socks" ] && {
echo
ask_yes_no_var MODE_HTTPS "enable https support"
write_config_var MODE_HTTPS
}
}
select_mode_quic()
{
[ "$SUBSYS" = "keenetic" ] && {
echo
echo "WARNING ! Keenetic is not officially supported by zapret."
echo "WARNING ! This firmware requires additional manual iptables setup to support udp desync properly."
echo "WARNING ! Keenetic uses proprietary ndmmark to limit MASQUERADE."
echo "WARNING ! Desynced packets may go outside without MASQUERADE with LAN source ip."
echo "WARNING ! To fix this you need to add additional MASQUERADE rule to iptables nat table."
echo "WARNING ! Installer WILL NOT fix it for you automatically."
echo "WARNING ! If you cannot understand what it is all about - do not enable QUIC."
}
[ "$MODE" != "filter" ] && [ "$MODE" != "tpws-socks" ] && [ "$MODE" != "tpws" ] && {
echo
ask_yes_no_var MODE_QUIC "enable quic support"
write_config_var MODE_QUIC
}
} }
select_mode_filter() select_mode_filter()
{ {
local filter="none ipset hostlist autohostlist" local filter="none ipset hostlist autohostlist"
[ "$MODE" = "tpws-socks" ] && filter="none hostlist autohostlist"
echo echo
echo select filtering : echo select filtering :
ask_list MODE_FILTER "$filter" none && write_config_var MODE_FILTER ask_list MODE_FILTER "$filter" none && write_config_var MODE_FILTER
} }
select_mode() select_mode()
{ {
select_mode_mode select_mode_mode
select_mode_iface select_mode_iface
select_mode_http
select_mode_keepalive
select_mode_https
select_mode_quic
select_mode_filter select_mode_filter
} }
@ -286,7 +279,7 @@ ask_config_tmpdir()
nft_flow_offload() nft_flow_offload()
{ {
[ "$UNAME" = Linux -a "$FWTYPE" = nftables -a "$MODE" != "tpws-socks" ] && [ "$FLOWOFFLOAD" = software -o "$FLOWOFFLOAD" = hardware ] [ "$UNAME" = Linux -a "$FWTYPE" = nftables ] && [ "$FLOWOFFLOAD" = software -o "$FLOWOFFLOAD" = hardware ]
} }
ask_iface() ask_iface()
@ -338,57 +331,10 @@ select_mode_iface()
# it's not possible to instruct tpws to route outgoing connection to an interface (OS routing table decides) # it's not possible to instruct tpws to route outgoing connection to an interface (OS routing table decides)
# custom mode can also benefit from interface names (depends on custom script code) # custom mode can also benefit from interface names (depends on custom script code)
if [ "$SYSTEM" = "openwrt" ] || [ "$MODE" = "filter" ]; then return; fi [ "$SYSTEM" = "openwrt" ] && return
case "$MODE" in
tpws-socks)
echo "select LAN interface to allow socks access from your LAN. select NONE for localhost only."
echo "expect socks on tcp port $TPPORT"
ask_iface_lan ask_iface_lan
;;
tpws)
echo "select LAN interface to operate in router mode. select NONE for local outgoing traffic only."
if [ "$SYSTEM" = "macos" ]; then
echo "WARNING ! OS feature \"internet sharing\" is not supported."
echo "Only manually configured PF router is supported."
else
echo "WARNING ! This installer will not configure routing, NAT, ... for you. Its your responsibility."
fi
ask_iface_lan
;;
custom)
echo "select LAN interface for your custom script (how it works depends on your code)"
ask_iface_lan
;;
*)
nft_flow_offload && {
echo "select LAN interface for nftables flow offloading"
ask_iface_lan
}
;;
esac
case "$MODE" in
tpws)
echo "select WAN interface for $MODE operations. select ANY to operate on any interface."
[ -n "$IFACE_LAN" ] && echo "WAN filtering works only for local outgoing traffic !"
ask_iface_wan ask_iface_wan
;;
nfqws)
echo "select WAN interface for $MODE operations. select ANY to operate on any interface."
ask_iface_wan
;;
custom)
echo "select WAN interface for your custom script (how it works depends on your code)"
ask_iface_wan
;;
*)
nft_flow_offload && {
echo "select WAN interface for nftables flow offloading"
ask_iface_wan
}
;;
esac
} }
default_files() default_files()
@ -511,7 +457,9 @@ _restore_settings()
# safety check # safety check
[ -z "$f" -o "$f" = "/" ] && continue [ -z "$f" -o "$f" = "/" ] && continue
[ -f "/tmp/zapret-bkp-$i" ] && mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -f "/tmp/zapret-bkp-$i" [ -f "/tmp/zapret-bkp-$i" ] && {
mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -f "/tmp/zapret-bkp-$i"
}
[ -d "/tmp/zapret-bkp-$i" ] && { [ -d "/tmp/zapret-bkp-$i" ] && {
[ -d "$ZAPRET_TARGET/$f" ] && rm -r "$ZAPRET_TARGET/$f" [ -d "$ZAPRET_TARGET/$f" ] && rm -r "$ZAPRET_TARGET/$f"
mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -r "/tmp/zapret-bkp-$i" mv -f "/tmp/zapret-bkp-$i" "$ZAPRET_TARGET/$f" || rm -r "/tmp/zapret-bkp-$i"
@ -523,7 +471,12 @@ backup_restore_settings()
{ {
# $1 - 1 - backup, 0 - restore # $1 - 1 - backup, 0 - restore
local mode=$1 local mode=$1
on_off_function _backup_settings _restore_settings $mode "config" "init.d/sysv/custom" "init.d/sysv/custom.d" "init.d/openwrt/custom" "init.d/openwrt/custom.d" "init.d/macos/custom" "init.d/macos/custom.d" "ipset/zapret-hosts-user.txt" "ipset/zapret-hosts-user-exclude.txt" "ipset/zapret-hosts-user-ipban.txt" "ipset/zapret-hosts-auto.txt" on_off_function _backup_settings _restore_settings $mode "config" "init.d/sysv/custom.d" "init.d/openwrt/custom.d" "init.d/macos/custom.d" "ipset/zapret-hosts-user.txt" "ipset/zapret-hosts-user-exclude.txt" "ipset/zapret-hosts-user-ipban.txt" "ipset/zapret-hosts-auto.txt"
}
config_is_obsolete()
{
[ -f "$1" ] && grep -qE "^[[:space:]]*NFQWS_OPT_DESYNC=|^[[:space:]]*MODE_HTTP=|^[[:space:]]*MODE_HTTPS=|^[[:space:]]*MODE_QUIC=|^[[:space:]]*MODE=" "$1"
} }
check_location() check_location()
@ -531,11 +484,22 @@ check_location()
# $1 - copy function # $1 - copy function
echo \* checking location echo \* checking location
# use inodes in case something is linked # use inodes in case something is linked
if [ -d "$ZAPRET_TARGET" ] && [ $(get_dir_inode "$EXEDIR") = $(get_dir_inode "$ZAPRET_TARGET") ]; then if [ -d "$ZAPRET_TARGET" ] && [ $(get_dir_inode "$EXEDIR") = $(get_dir_inode "$ZAPRET_TARGET") ]; then
config_is_obsolete "$ZAPRET_CONFIG" && {
echo config file $ZAPRET_CONFIG is obsolete. cannot continue.
exitp 3
}
default_files "$ZAPRET_TARGET" "$ZAPRET_RW" default_files "$ZAPRET_TARGET" "$ZAPRET_RW"
else else
local obsolete=0 rwdir=0
config_is_obsolete "$ZAPRET_TARGET_CONFIG" && obsolete=1
[ $(get_dir_inode "$ZAPRET_BASE") = $(get_dir_inode "$ZAPRET_RW") ] || rwdir=1
[ $rwdir = 1 -a $obsolete = 1 ] && {
echo config file in custom ZAPRET_RW directory is obsolete : $ZAPRET_TARGET_CONFIG
echo you need to edit or delete it to continue. also check for obsolete custom scripts.
exitp 3
}
echo echo
echo easy install is supported only from default location : $ZAPRET_TARGET echo easy install is supported only from default location : $ZAPRET_TARGET
echo currently its run from $EXEDIR echo currently its run from $EXEDIR
@ -547,7 +511,13 @@ check_location()
echo directory needs to be replaced. config and custom scripts can be kept or replaced with clean version echo directory needs to be replaced. config and custom scripts can be kept or replaced with clean version
if ask_yes_no N "do you want to delete all files there and copy this version"; then if ask_yes_no N "do you want to delete all files there and copy this version"; then
echo echo
if [ $(get_dir_inode "$ZAPRET_BASE") = $(get_dir_inode "$ZAPRET_RW") ]; then if [ $obsolete = 1 ] ; then
echo obsolete config is detected : $ZAPRET_TARGET_RW
ask_yes_no N "impossible to keep config, custom scripts and user lists. do you want to delete them ?" || {
echo refused to delete config in $ZAPRET_TARGET. exiting
exitp 3
}
elif [ $rwdir != 1 ]; then
ask_yes_no Y "keep config, custom scripts and user lists" && keep=Y ask_yes_no Y "keep config, custom scripts and user lists" && keep=Y
[ "$keep" = "Y" ] && backup_restore_settings 1 [ "$keep" = "Y" ] && backup_restore_settings 1
fi fi
@ -755,13 +725,15 @@ deoffload_openwrt_firewall()
printf "system wide flow offloading detected. " printf "system wide flow offloading detected. "
case $FLOWOFFLOAD in case $FLOWOFFLOAD in
donttouch) donttouch)
if [ "$MODE" = "nfqws" ]; then if [ "$NFQWS_ENABLE" = "1" ]; then
echo its incompatible with nfqws tcp data tampering. disabling echo its incompatible with nfqws tcp data tampering. disabling
uci set firewall.@defaults[0].flow_offloading=0 uci set firewall.@defaults[0].flow_offloading=0
mod=1 mod=1
else else
if [ "$MODE" = "custom" ] ; then if dir_is_not_empty "$CUSTOM_DIR/custom.d" ; then
echo custom mode selected !!! only you can decide whether flow offloading is compatible echo
echo !!! CUSTOM SCRIPTS ARE PRESENT !!! only you can decide whether flow offloading is compatible.
echo !!! CUSTOM SCRIPTS ARE PRESENT !!! if they use nfqws they will not work. you have to disable system-wide offloading.
else else
echo its compatible with selected options. not disabling echo its compatible with selected options. not disabling
fi fi
@ -837,21 +809,13 @@ remove_pf_zapret_hooks()
macos_fw_reload_trigger_clear() macos_fw_reload_trigger_clear()
{ {
case "$MODE" in
tpws|tpws-socks|custom)
LISTS_RELOAD= LISTS_RELOAD=
write_config_var LISTS_RELOAD write_config_var LISTS_RELOAD
;;
esac
} }
macos_fw_reload_trigger_set() macos_fw_reload_trigger_set()
{ {
case "$MODE" in
tpws|custom)
LISTS_RELOAD="$INIT_SCRIPT_SRC reload-fw-tables" LISTS_RELOAD="$INIT_SCRIPT_SRC reload-fw-tables"
write_config_var LISTS_RELOAD write_config_var LISTS_RELOAD
;;
esac
} }
install_macos() install_macos()