|
|
@ -12,7 +12,7 @@ ZAPRET_BASE="$EXEDIR" |
|
|
|
. "$ZAPRET_BASE/common/virt.sh" |
|
|
|
|
|
|
|
[ -n "$QNUM" ] || QNUM=59780 |
|
|
|
[ -n "$TPPORT" ] || TPPORT=993 |
|
|
|
[ -n "$SOCKS_PORT" ] || SOCKS_PORT=1993 |
|
|
|
[ -n "$TPWS_UID" ] || TPWS_UID=1 |
|
|
|
[ -n "$TPWS_GID" ] || TPWS_GID=3003 |
|
|
|
[ -n "$NFQWS" ] || NFQWS="$ZAPRET_BASE/nfq/nfqws" |
|
|
@ -41,7 +41,7 @@ DNSCHECK_DIGS=/tmp/digs.txt |
|
|
|
unset PF_STATUS |
|
|
|
PF_RULES_SAVE=/tmp/pf-zapret-save.conf |
|
|
|
|
|
|
|
CURL=curl |
|
|
|
unset ALL_PROXY |
|
|
|
|
|
|
|
killwait() |
|
|
|
{ |
|
|
@ -123,26 +123,6 @@ opf_prepare_dvtws() |
|
|
|
opf_dvtws_anchor $1 | pfctl -qf - |
|
|
|
pfctl -qe |
|
|
|
} |
|
|
|
mpf_tpws_anchor() |
|
|
|
{ |
|
|
|
# $1 - port |
|
|
|
case "$IPV" in |
|
|
|
4) |
|
|
|
echo "rdr pass on $LO_IFACE inet proto tcp from \!127.0.0.0/8 to any port $1 -> $LINKLOCAL port $TPPORT" |
|
|
|
echo "pass out route-to ($LO_IFACE $LINKLOCAL) inet proto tcp from any to any port $1 user { >root }" |
|
|
|
;; |
|
|
|
6) |
|
|
|
echo "rdr pass on $LO_IFACE inet6 proto tcp from \!::1 to any port $1 -> $LINKLOCAL port $TPPORT" |
|
|
|
echo "pass out route-to ($LO_IFACE $LINKLOCAL) inet6 proto tcp from any to any port $1 user { >root }" |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
mpf_prepare_tpws() |
|
|
|
{ |
|
|
|
# $1 - port |
|
|
|
mpf_tpws_anchor $1 | pfctl -qf - |
|
|
|
pfctl -qe |
|
|
|
} |
|
|
|
|
|
|
|
cleanup() |
|
|
|
{ |
|
|
@ -197,6 +177,13 @@ nft_has_nfq() |
|
|
|
return $res |
|
|
|
} |
|
|
|
|
|
|
|
mdig_resolve() |
|
|
|
{ |
|
|
|
# $1 - ip version 4/6 |
|
|
|
# $2 - hostname |
|
|
|
echo "$2" | "$MDIG" --family=$1 | head -n 1 |
|
|
|
} |
|
|
|
|
|
|
|
check_system() |
|
|
|
{ |
|
|
|
echo \* checking system |
|
|
@ -234,10 +221,6 @@ check_system() |
|
|
|
PKTWS="$DVTWS" |
|
|
|
PKTWSD=dvtws |
|
|
|
FWTYPE=mpf |
|
|
|
# will not redirect traffic for root |
|
|
|
CURL="sudo -u nobody curl" |
|
|
|
# /dev/pf requires root. hardcoded in kernel |
|
|
|
TPWS_UID=0 |
|
|
|
LO_IFACE=lo0 |
|
|
|
;; |
|
|
|
*) |
|
|
@ -308,11 +291,6 @@ check_prerequisites() |
|
|
|
echo pf is not available |
|
|
|
exitp 6 |
|
|
|
} |
|
|
|
# I dont know how to redirect traffic originating from the host itself |
|
|
|
# even with route-to trick DIOCNATLOOK fails, thus making tpws unusable |
|
|
|
# this trick works fine on MacOS but doesn't work on FreeBSD and OpenBSD |
|
|
|
# socks version is also not a solution because I can't control ip version of the resolved domain |
|
|
|
[ "$UNAME" = "OpenBSD" ] && SKIP_TPWS=1 |
|
|
|
# no divert sockets in MacOS |
|
|
|
[ "$UNAME" = "Darwin" ] && SKIP_PKTWS=1 |
|
|
|
pf_save |
|
|
@ -393,6 +371,12 @@ curl_supports_tlsmax() |
|
|
|
[ $? != 2 ] |
|
|
|
} |
|
|
|
|
|
|
|
curl_supports_connect_to() |
|
|
|
{ |
|
|
|
curl --connect-to 127.0.0.1:: -o /dev/null http://127.0.0.1:65535 2>/dev/null |
|
|
|
[ "$?" != 2 ] |
|
|
|
} |
|
|
|
|
|
|
|
hdrfile_http_code() |
|
|
|
{ |
|
|
|
# $1 - hdr file |
|
|
@ -405,12 +389,34 @@ hdrfile_location() |
|
|
|
# some DPIs return CRLF line ending |
|
|
|
tr -d '\015' <"$1" | sed -nre 's/^[Ll][Oo][Cc][Aa][Tt][Ii][Oo][Nn]:[ ]*([^ ]*)[ ]*$/\1/p' |
|
|
|
} |
|
|
|
|
|
|
|
curl_connect_to() |
|
|
|
{ |
|
|
|
# $1 - ip version : 4/6 |
|
|
|
# $2 - domain name |
|
|
|
local ip=$(mdig_resolve $1 $2) |
|
|
|
[ -n "$ip" ] && echo "--connect-to $2::[$ip]" |
|
|
|
} |
|
|
|
curl_with_dig() |
|
|
|
{ |
|
|
|
# $1 - ip version : 4/6 |
|
|
|
# $2 - domain name |
|
|
|
# $3+ - curl params |
|
|
|
local connect_to=$(curl_connect_to $1 $2) |
|
|
|
[ -n "$connect_to" ] || { |
|
|
|
echo "could not resolve ipv$1 $2" |
|
|
|
return 6 |
|
|
|
} |
|
|
|
shift ; shift |
|
|
|
ALL_PROXY="$ALL_PROXY" curl $connect_to "$@" |
|
|
|
} |
|
|
|
|
|
|
|
curl_test_http() |
|
|
|
{ |
|
|
|
# $1 - ip version : 4/6 |
|
|
|
# $2 - domain name |
|
|
|
local code loc |
|
|
|
$CURL -${1}SsD "$HDRTEMP" --max-time $CURL_MAX_TIME $CURL_OPT "http://$2" -o /dev/null 2>&1 || { |
|
|
|
curl_with_dig $1 $2 -SsD "$HDRTEMP" --max-time $CURL_MAX_TIME $CURL_OPT "http://$2" -o /dev/null 2>&1 || { |
|
|
|
code=$? |
|
|
|
rm -f "$HDRTEMP" |
|
|
|
return $code |
|
|
@ -439,7 +445,7 @@ curl_test_https_tls12() |
|
|
|
# $2 - domain name |
|
|
|
|
|
|
|
# do not use tls 1.3 to make sure server certificate is not encrypted |
|
|
|
$CURL -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.2 $TLSMAX12 "https://$2" -o /dev/null 2>&1 |
|
|
|
curl_with_dig $1 $2 -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.2 $TLSMAX12 "https://$2" -o /dev/null 2>&1 |
|
|
|
} |
|
|
|
curl_test_https_tls13() |
|
|
|
{ |
|
|
@ -447,7 +453,7 @@ curl_test_https_tls13() |
|
|
|
# $2 - domain name |
|
|
|
|
|
|
|
# force TLS1.3 mode |
|
|
|
$CURL -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.3 $TLSMAX13 "https://$2" -o /dev/null 2>&1 |
|
|
|
curl_with_dig $1 $2 -${1}ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.3 $TLSMAX13 "https://$2" -o /dev/null 2>&1 |
|
|
|
} |
|
|
|
|
|
|
|
pktws_ipt_prepare() |
|
|
@ -485,7 +491,7 @@ pktws_ipt_prepare() |
|
|
|
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} tcp dport $1 mark and 0x40000000 != 0x40000000 queue num $QNUM" |
|
|
|
# for strategies with incoming packets involved (autottl) |
|
|
|
nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }" |
|
|
|
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 ct original packets 1-1 queue num $QNUM" |
|
|
|
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 ct original packets 1 queue num $QNUM" |
|
|
|
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD) |
|
|
|
nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }" |
|
|
|
nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} mark and $DESYNC_MARK !=0 notrack" |
|
|
@ -529,45 +535,6 @@ pktws_ipt_unprepare() |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
tpws_ipt_prepare() |
|
|
|
{ |
|
|
|
# $1 - port |
|
|
|
case "$FWTYPE" in |
|
|
|
iptables) |
|
|
|
IPT OUTPUT -t nat -p tcp --dport $1 -m owner ! --uid-owner $TPWS_UID -j DNAT --to $LOCALHOST_IPT:$TPPORT |
|
|
|
;; |
|
|
|
nftables) |
|
|
|
nft add table inet $NFT_TABLE |
|
|
|
# -101 = pre dstnat |
|
|
|
nft "add chain inet $NFT_TABLE output { type nat hook output priority -102; }" |
|
|
|
nft "add rule inet $NFT_TABLE output tcp dport $1 skuid != $TPWS_UID dnat ip${IPVV} to $LOCALHOST_IPT:$TPPORT" |
|
|
|
;; |
|
|
|
ipfw) |
|
|
|
IPFW_ADD fwd $LOCALHOST,$TPPORT tcp from me to any $1 proto ip${IPV} not uid $TPWS_UID |
|
|
|
;; |
|
|
|
mpf) |
|
|
|
mpf_prepare_tpws $1 |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
tpws_ipt_unprepare() |
|
|
|
{ |
|
|
|
# $1 - port |
|
|
|
case "$FWTYPE" in |
|
|
|
iptables) |
|
|
|
IPT_DEL OUTPUT -t nat -p tcp --dport $1 -m owner ! --uid-owner $TPWS_UID -j DNAT --to $LOCALHOST_IPT:$TPPORT |
|
|
|
;; |
|
|
|
nftables) |
|
|
|
nft delete table inet $NFT_TABLE 2>/dev/null |
|
|
|
;; |
|
|
|
ipfw) |
|
|
|
IPFW_DEL |
|
|
|
;; |
|
|
|
mpf) |
|
|
|
pf_restore |
|
|
|
;; |
|
|
|
esac |
|
|
|
} |
|
|
|
pktws_start() |
|
|
|
{ |
|
|
|
case "$UNAME" in |
|
|
@ -584,7 +551,7 @@ pktws_start() |
|
|
|
} |
|
|
|
tpws_start() |
|
|
|
{ |
|
|
|
"$TPWS" --uid $TPWS_UID:$TPWS_GID --bind-addr=$LINKLOCAL%$LO_IFACE --port=$TPPORT "$@" >/dev/null & |
|
|
|
"$TPWS" --uid $TPWS_UID:$TPWS_GID --socks --bind-addr=127.0.0.1 --port=$SOCKS_PORT "$@" >/dev/null & |
|
|
|
PID=$! |
|
|
|
# give some time to initialize |
|
|
|
minsleep |
|
|
@ -643,6 +610,7 @@ tpws_curl_test() |
|
|
|
# $2 - domain |
|
|
|
# $3,$4,$5, ... - tpws params |
|
|
|
echo - checking tpws $3 $4 $5 $6 $7 $8 $9 |
|
|
|
local ALL_PROXY="socks5://127.0.0.1:$SOCKS_PORT" |
|
|
|
ws_curl_test tpws_start "$@" |
|
|
|
} |
|
|
|
pktws_curl_test() |
|
|
@ -862,7 +830,6 @@ check_domain() |
|
|
|
|
|
|
|
# in case was interrupted before |
|
|
|
pktws_ipt_unprepare $2 |
|
|
|
tpws_ipt_unprepare $2 |
|
|
|
ws_kill |
|
|
|
|
|
|
|
echo "- checking without DPI bypass" |
|
|
@ -879,17 +846,8 @@ check_domain() |
|
|
|
done |
|
|
|
|
|
|
|
echo |
|
|
|
if [ "$SUBSYS" = "pfSense" ] ; then |
|
|
|
echo "tpws tests are not possible on pfSense" |
|
|
|
report_append "ipv${IPV} $4 $1 : automated tpws tests are not possible on pfSense. check docs/bsd.txt" |
|
|
|
elif [ "$SKIP_TPWS" != 1 ]; then |
|
|
|
echo preparing tpws redirection |
|
|
|
tpws_ipt_prepare $2 |
|
|
|
|
|
|
|
if [ "$SKIP_TPWS" != 1 ]; then |
|
|
|
tpws_check_domain_bypass $1 $3 $4 |
|
|
|
|
|
|
|
echo clearing tpws redirection |
|
|
|
tpws_ipt_unprepare $2 |
|
|
|
fi |
|
|
|
|
|
|
|
echo |
|
|
@ -925,16 +883,11 @@ configure_ip_version() |
|
|
|
if [ "$IPV" = 6 ]; then |
|
|
|
LOCALHOST=::1 |
|
|
|
LOCALHOST_IPT=[${LOCALHOST}] |
|
|
|
LINKLOCAL=$LOCALHOST |
|
|
|
[ "$UNAME" = Darwin ] && LINKLOCAL=fe80::1 |
|
|
|
LINKLOCAL_IPT=[${LINKLOCAL}] |
|
|
|
IPVV=6 |
|
|
|
else |
|
|
|
IPTABLES=iptables |
|
|
|
LOCALHOST=127.0.0.1 |
|
|
|
LOCALHOST_IPT=$LOCALHOST |
|
|
|
LINKLOCAL=$LOCALHOST |
|
|
|
LINKLOCAL_IPT=$LINKLOCAL |
|
|
|
IPVV= |
|
|
|
fi |
|
|
|
IPTABLES=ip${IPVV}tables |
|
|
@ -1007,6 +960,14 @@ ask_params() |
|
|
|
echo |
|
|
|
echo NOTE ! this test should be run with zapret or any other bypass software disabled, without VPN |
|
|
|
echo |
|
|
|
|
|
|
|
curl_supports_connect_to || { |
|
|
|
echo "installed curl does not support --connect-to option. pls install at least curl 7.49" |
|
|
|
echo "current curl version:" |
|
|
|
curl --version |
|
|
|
exitp 1 |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
echo "specify domain(s) to test. multiple domains are space separated." |
|
|
|
printf "domain(s) (default: $DOMAINS) : " |
|
|
@ -1201,8 +1162,6 @@ unprepare_all() |
|
|
|
# make sure we are not in a middle state that impacts connectivity |
|
|
|
rm -f "$HDRTEMP" |
|
|
|
[ -n "$IPV" ] && { |
|
|
|
tpws_ipt_unprepare 80 |
|
|
|
tpws_ipt_unprepare 443 |
|
|
|
pktws_ipt_unprepare 80 |
|
|
|
pktws_ipt_unprepare 443 |
|
|
|
} |
|
|
|