blockcheck: update for new strategies. nfqws check order reworked.

This commit is contained in:
bol-van 2024-11-15 18:43:25 +03:00
parent 677feecada
commit c56e672600
3 changed files with 167 additions and 133 deletions

View File

@ -45,7 +45,6 @@ HTTP_PORT=${HTTP_PORT:-80}
HTTPS_PORT=${HTTPS_PORT:-443} HTTPS_PORT=${HTTPS_PORT:-443}
QUIC_PORT=${QUIC_PORT:-443} QUIC_PORT=${QUIC_PORT:-443}
UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org} UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org}
[ "$CURL_VERBOSE" = 1 ] && CURL_CMD=1
HDRTEMP=/tmp/zapret-hdr.txt HDRTEMP=/tmp/zapret-hdr.txt
@ -792,7 +791,7 @@ pktws_ipt_prepare()
# disable PF to avoid interferences # disable PF to avoid interferences
pf_is_avail && pfctl -qd pf_is_avail && pfctl -qd
for ip in $3; do for ip in $3; do
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted not sockarg IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted
done done
;; ;;
opf) opf)
@ -867,7 +866,7 @@ pktws_ipt_prepare_tcp()
;; ;;
ipfw) ipfw)
for ip in $2; do for ip in $2; do
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted
done done
;; ;;
esac esac
@ -994,7 +993,6 @@ ws_curl_test()
# $2 - test function # $2 - test function
# $3 - domain # $3 - domain
# $4,$5,$6, ... - ws params # $4,$5,$6, ... - ws params
local code ws_start=$1 testf=$2 dom=$3 local code ws_start=$1 testf=$2 dom=$3
shift shift
shift shift
@ -1088,7 +1086,7 @@ test_has_split()
} }
test_has_fake() test_has_fake()
{ {
contains "$1" fake [ "$1" = fake ] || starts_with "$1" fake,
} }
warn_fool() warn_fool()
{ {
@ -1105,25 +1103,34 @@ pktws_curl_test_update_vary()
# $4 - desync mode # $4 - desync mode
# $5,$6,... - strategy # $5,$6,... - strategy
local testf=$1 sec=$2 domain=$3 desync=$4 zerofake split fake local testf=$1 sec=$2 domain=$3 desync=$4 proto zerofake= splits= pos fake ret=1
shift; shift; shift; shift shift; shift; shift; shift
zerofake=http proto=http
[ "$sec" = 0 ] || zerofake=tls [ "$sec" = 0 ] || proto=tls
zerofake="--dpi-desync-fake-$zerofake=0x00000000" test_has_fake $desync && zerofake="--dpi-desync-fake-$proto=0x00000000"
test_has_split $desync && {
splits="method+2 midsld"
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
}
for fake in '' $zerofake ; do for fake in '' $zerofake ; do
for split in '' '--dpi-desync-split-pos=1' ; do if [ -n "$splits" ]; then
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" $fake $split && return 0 for pos in $splits ; do
# split-pos=1 is meaningful for DPIs searching for 16 03 in TLS. no reason to apply to http pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" --dpi-desync-split-pos=$pos $fake && {
[ "$sec" = 1 ] || break [ "$SCANLEVEL" = force ] || return 0
test_has_split $desync || break ret=0
done }
test_has_fake $desync || break done
else
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" $fake && {
[ "$SCANLEVEL" = force ] || return 0
ret=0
}
fi
done done
return 1 return $ret
} }
pktws_check_domain_http_bypass_() pktws_check_domain_http_bypass_()
@ -1132,7 +1139,10 @@ pktws_check_domain_http_bypass_()
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk # $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $3 - domain # $3 - domain
local tests='fake' ret ok ttls s f e desync pos fooling frag sec="$2" delta hostcase local ok ttls s f f2 e desync pos fooling frag sec="$2" delta splits
local need_split need_disorder need_fakedsplit need_fakeddisorder need_fake need_wssize
local splits_http='method+2 midsld method+2,midsld'
local splits_tls='2 1 sniext+1 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1'
[ "$sec" = 0 ] && { [ "$sec" = 0 ] && {
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase'; do for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase'; do
@ -1140,74 +1150,62 @@ pktws_check_domain_http_bypass_()
done done
} }
s="--dpi-desync=split2"
ok=0
pktws_curl_test_update $1 $3 $s
ret=$?
[ "$ret" = 0 ] && {
[ "$SCANLEVEL" = quick ] && return
ok=1
}
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
if [ "$sec" = 0 ]; then
pktws_curl_test_update $1 $3 $s --hostcase && {
[ "$SCANLEVEL" = quick ] && return
ok=1
}
for pos in method host; do
for hostcase in '' '--hostcase'; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-http-req=$pos $hostcase && {
[ "$SCANLEVEL" = quick ] && return
ok=1
}
done
done
else
for pos in sni sniext; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-tls=$pos && {
[ "$SCANLEVEL" = quick ] && return
ok=1
}
done
fi
for pos in 1 3 4 5 10 50; do
s="--dpi-desync=split2 --dpi-desync-split-pos=$pos"
if pktws_curl_test_update $1 $3 $s; then
[ "$SCANLEVEL" = quick ] && return
ok=1
[ "$SCANLEVEL" = force ] || break
elif [ "$sec" = 0 ]; then
pktws_curl_test_update $1 $3 $s --hostcase && [ "$SCANLEVEL" = quick ] && return
fi
done
}
[ "$ok" = 1 -a "$SCANLEVEL" != force ] || tests="$tests split fake,split2 fake,split"
pktws_curl_test_update $1 $3 --dpi-desync=disorder2
ret=$?
[ "$ret" = 0 -a "$SCANLEVEL" = quick ] && return
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
pktws_curl_test_update $1 $3 --dpi-desync=disorder2 --dpi-desync-split-pos=1
ret=$?
[ "$ret" = 0 -a "$SCANLEVEL" = quick ] && return
}
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && tests="$tests disorder fake,disorder2 fake,disorder"
ttls=$(seq -s ' ' $MIN_TTL $MAX_TTL) ttls=$(seq -s ' ' $MIN_TTL $MAX_TTL)
need_wssize=1
for e in '' '--wssize 1:6'; do for e in '' '--wssize 1:6'; do
need_split=
need_disorder=
[ -n "$e" ] && { [ -n "$e" ] && {
pktws_curl_test_update $1 $3 $e && [ "$SCANLEVEL" = quick ] && return pktws_curl_test_update $1 $3 $e && [ "$SCANLEVEL" = quick ] && return
for desync in split2 disorder2; do
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
done
} }
for desync in $tests; do
for desync in multisplit multidisorder; do
ok=0
splits="$splits_http"
[ "$sec" = 0 ] || splits="$splits_tls"
for pos in $splits; do
pktws_curl_test_update $1 $3 --dpi-desync=$desync --dpi-desync-split-pos=$pos $e && {
[ "$SCANLEVEL" = quick ] && return
ok=1
need_wssize=0
[ "$SCANLEVEL" = force ] || break
}
done
[ "$ok" = 1 -a "$SCANLEVEL" != force ] || {
case $desync in
multisplit)
need_split=1
;;
multidisorder)
need_disorder=1
;;
esac
}
done
need_fakedsplit=1
need_fakeddisorder=1
need_fake=1
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
ok=0
for ttl in $ttls; do for ttl in $ttls; do
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=$ttl $e && { pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=$ttl $e && {
[ "$SCANLEVEL" = quick ] && return [ "$SCANLEVEL" = quick ] && return
ok=1
need_wssize=0
break break
} }
done done
# only skip tests if TTL succeeded. do not skip if TTL failed but fooling succeeded
[ $ok = 1 -a "$SCANLEVEL" != force ] && {
[ "$desync" = fake ] && need_fake=0
[ "$desync" = fakedsplit ] && need_fakedsplit=0
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
}
f= f=
[ "$UNAME" = "OpenBSD" ] || f="badsum" [ "$UNAME" = "OpenBSD" ] || f="badsum"
f="$f badseq datanoack md5sig" f="$f badseq datanoack md5sig"
@ -1216,37 +1214,62 @@ pktws_check_domain_http_bypass_()
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && { pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && {
warn_fool $fooling warn_fool $fooling
[ "$SCANLEVEL" = quick ] && return [ "$SCANLEVEL" = quick ] && return
need_wssize=0
} }
done done
done done
[ "$IPV" = 6 ] && { [ "$IPV" = 6 ] && {
f="hopbyhop hopbyhop,split2 hopbyhop,disorder2 destopt destopt,split2 destopt,disorder2" f="hopbyhop ${need_split:+hopbyhop,multisplit} ${need_disorder:+hopbyhop,multidisorder} destopt ${need_split:+destopt,multisplit} ${need_disorder:+destopt,multidisorder}"
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1 ipfrag1,split2 ipfrag1,disorder2" [ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1 ${need_split:+ ipfrag1,multisplit} ${need_disorder:+ ipfrag1,multidisorder}"
for desync in $f; do for desync in $f; do
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return pktws_curl_test_update_vary $1 $2 $3 $desync $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done done
} }
for desync in split2 disorder2; do [ "$need_split" = 1 ] && {
s="--dpi-desync=$desync" f="method+2 midsld method+2,midsld"
[ "$sec" = 0 ] || f="1 midsld sniext+1 1,midsld"
for pos in $f; do
pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=$pos --dpi-desync-split-seqovl=1 $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done
[ "$sec" != 0 ] && pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=2 --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern="$ZAPRET_BASE/files/fake/tls_clienthello_iana_org.bin" $e && [ "$SCANLEVEL" = quick ] && return
}
[ "$need_disorder" = 1 ] && {
if [ "$sec" = 0 ]; then if [ "$sec" = 0 ]; then
for pos in method host; do for pos in 'method+1 method+2' 'midsld-1 midsld' 'method+1 method+2,midsld'; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=1 --dpi-desync-split-http-req=$pos $e && [ "$SCANLEVEL" = quick ] && return f="$(extract_arg 1 $pos)"
f2="$(extract_arg 2 $pos)"
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done done
else else
for pos in sni sniext; do for pos in '1 2' 'sniext sniext+1' 'midsld-1 midsld' '1 2,midsld'; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=1 --dpi-desync-split-tls=$pos $e && [ "$SCANLEVEL" = quick ] && return f=$(extract_arg 1 $pos)
f2=$(extract_arg 2 $pos)
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done done
fi fi
for pos in 2 3 4 5 10 50; do }
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=$(($pos - 1)) --dpi-desync-split-pos=$pos $e && [ "$SCANLEVEL" = quick ] && return
done
[ "$sec" != 0 -a $desync = split2 ] && {
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern="$ZAPRET_BASE/files/fake/tls_clienthello_iana_org.bin" $e && [ "$SCANLEVEL" = quick ] && return
}
done
for desync in $tests; do need_fakedsplit=1
need_fakeddisorder=1
need_fake=1
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
ok=0 ok=0
for delta in 1 2 3 4 5; do for delta in 1 2 3 4 5; do
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=1 --dpi-desync-autottl=$delta $e && ok=1 pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=1 --dpi-desync-autottl=$delta $e && ok=1
@ -1256,18 +1279,25 @@ pktws_check_domain_http_bypass_()
echo "WARNING ! although autottl worked it requires testing on multiple domains to find out reliable delta" echo "WARNING ! although autottl worked it requires testing on multiple domains to find out reliable delta"
echo "WARNING ! if a reliable delta cannot be found it's a good idea not to use autottl" echo "WARNING ! if a reliable delta cannot be found it's a good idea not to use autottl"
[ "$SCANLEVEL" = quick ] && return [ "$SCANLEVEL" = quick ] && return
need_wssize=0
[ "$SCANLEVEL" = force ] || {
[ "$desync" = fake ] && need_fake=0
[ "$desync" = fakedsplit ] && need_fakedsplit=0
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
}
} }
done done
s="http_iana_org.bin" s="http_iana_org.bin"
[ "$sec" = 0 ] || s="tls_clienthello_iana_org.bin" [ "$sec" = 0 ] || s="tls_clienthello_iana_org.bin"
for desync in syndata syndata,split2 syndata,disorder2 ; do for desync in syndata ${need_split:+syndata,multisplit} ${need_disorder:+syndata,multidisorder} ; do
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fake-syndata="$ZAPRET_BASE/files/fake/$s" $e && [ "$SCANLEVEL" = quick ] && return pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fake-syndata="$ZAPRET_BASE/files/fake/$s" $e && [ "$SCANLEVEL" = quick ] && return
done done
# do not do wssize test for http and TLS 1.3. it's useless # do not do wssize test for http and TLS 1.3. it's useless
[ "$sec" = 1 ] || break [ "$sec" = 1 ] || break
[ "$SCANLEVEL" = force -o "$need_wssize" = 1 ] || break
done done
} }
pktws_check_domain_http_bypass() pktws_check_domain_http_bypass()
@ -1338,15 +1368,28 @@ tpws_check_domain_http_bypass_()
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk # $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $3 - domain # $3 - domain
local s mss s2 s3 pos sec="$2" local s mss s2 s3 oobdis pos sec="$2"
local splits_tls='2 1 sniext+1 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld,endhost-1'
local splits_http='method+2 midsld method+2,midsld'
# simulteneous oob and disorder works properly only in linux. other systems retransmit oob byte without URG tcp flag and poison tcp stream.
[ "$UNAME" = Linux ] && oobdis='--oob --disorder'
if [ "$sec" = 0 ]; then if [ "$sec" = 0 ]; then
for s in '--hostcase' '--hostspell=hoSt' '--hostdot' '--hosttab' '--hostnospace' '--domcase' \ for s in '--hostcase' '--hostspell=hoSt' '--hostdot' '--hosttab' '--hostnospace' '--domcase' ; do
'--hostpad=1024' '--hostpad=2048' '--hostpad=4096' '--hostpad=8192' '--hostpad=16384' ; do
tpws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return tpws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
done done
for s2 in '' '--oob' '--disorder' '--oob --disorder'; do for s in 1024 2048 4096 8192 16384 ; do
for s in '--split-http-req=method' '--split-http-req=method --hostcase' '--split-http-req=host' '--split-http-req=host --hostcase' ; do tpws_curl_test_update $1 $3 --hostpad=$s && [ "$SCANLEVEL" != force ] && {
tpws_curl_test_update $1 $3 $s $s2 && [ "$SCANLEVEL" = quick ] && return [ "$SCANLEVEL" = quick ] && return
break
}
done
for s2 in '' '--hostcase' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
for s in $splits_http ; do
tpws_curl_test_update $1 $3 --split-pos=$s $s2 && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return
break
}
done done
done done
for s in '--methodspace' '--unixeol' '--methodeol'; do for s in '--methodspace' '--unixeol' '--methodeol'; do
@ -1355,30 +1398,21 @@ tpws_check_domain_http_bypass_()
else else
for mss in '' 88; do for mss in '' 88; do
s3=${mss:+--mss=$mss} s3=${mss:+--mss=$mss}
for s2 in '' '--oob' '--disorder' '--oob --disorder'; do for s2 in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
for pos in sni sniext; do for pos in $splits_tls; do
s="--split-tls=$pos" tpws_curl_test_update $1 $3 --split-pos=$pos $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
tpws_curl_test_update $1 $3 $s $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return
break
}
done
for pos in 1 2 3 4 5 10 50; do
s="--split-pos=$pos"
tpws_curl_test_update $1 $3 $s $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return [ "$SCANLEVEL" = quick ] && return
break break
} }
done done
done done
for s2 in '--tlsrec=sni' '--tlsrec=sni --split-tls=sni' '--tlsrec=sni --split-tls=sni --oob' \ for s in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
'--tlsrec=sni --split-tls=sni --disorder' '--tlsrec=sni --split-tls=sni --oob --disorder' \ for s2 in '--tlsrec=midsld' '--tlsrec=sniext+1 --split-pos=midsld' '--tlsrec=sniext+1 --split-pos=1,midsld' ; do
'--tlsrec=sni --split-pos=1' '--tlsrec=sni --split-pos=1 --oob' '--tlsrec=sni --split-pos=1 --disorder' \ tpws_curl_test_update $1 $3 $s2 $s $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
'--tlsrec=sni --split-pos=1 --oob --disorder'; do [ "$SCANLEVEL" = quick ] && return
tpws_curl_test_update $1 $3 $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && { break
[ "$SCANLEVEL" = quick ] && return }
break done
}
done done
# only linux supports mss # only linux supports mss
[ "$UNAME" = Linux -a "$sec" = 1 ] || break [ "$UNAME" = Linux -a "$sec" = 1 ] || break
@ -1682,17 +1716,6 @@ ask_params()
echo "installed curl version does not support http3 QUIC. tests disabled." echo "installed curl version does not support http3 QUIC. tests disabled."
fi fi
IGNORE_CA=0
CURL_OPT=
[ $ENABLE_HTTPS_TLS13 = 1 -o $ENABLE_HTTPS_TLS12 = 1 ] && {
echo
echo "on limited systems like openwrt CA certificates might not be installed to preserve space"
echo "in such a case curl cannot verify server certificate and you should either install ca-bundle or disable verification"
echo "however disabling verification will break https check if ISP does MitM attack and substitutes server certificate"
ask_yes_no_var IGNORE_CA "do not verify server certificate"
[ "$IGNORE_CA" = 1 ] && CURL_OPT=-k
}
echo echo
echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable." echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable."
printf "how many times to repeat each test (default: 1) : " printf "how many times to repeat each test (default: 1) : "

View File

@ -60,11 +60,22 @@ starts_with()
esac esac
return 1 return 1
} }
extract_arg()
{
# $1 - arg number
# $2,$3,... - args
local n=$1
while [ -n "$1" ]; do
shift
[ $n -eq 1 ] && { echo "$1"; return 0; }
n=$(($n-1))
done
return 1
}
find_str_in_list() find_str_in_list()
{ {
# $1 - string # $1 - string
# $2 - space separated values # $2 - space separated values
local v local v
[ -n "$1" ] && { [ -n "$1" ] && {
for v in $2; do for v in $2; do

View File

@ -221,7 +221,7 @@ check_system()
else else
echo system is not either systemd, openrc or openwrt based echo system is not either systemd, openrc or openwrt based
echo easy installer can set up config settings but can\'t configure auto start echo easy installer can set up config settings but can\'t configure auto start
echo you have to do it manually. check readme.txt for manual setup info. echo you have to do it manually. check readme.md for manual setup info.
if [ -n "$1" ] || ask_yes_no N "do you want to continue"; then if [ -n "$1" ] || ask_yes_no N "do you want to continue"; then
SYSTEM=linux SYSTEM=linux
else else
@ -232,7 +232,7 @@ check_system()
elif [ "$UNAME" = "Darwin" ]; then elif [ "$UNAME" = "Darwin" ]; then
SYSTEM=macos SYSTEM=macos
else else
echo easy installer only supports Linux and MacOS. check readme.txt for supported systems and manual setup info. echo easy installer only supports Linux and MacOS. check readme.md for supported systems and manual setup info.
exitp 5 exitp 5
fi fi
echo system is based on $SYSTEM echo system is based on $SYSTEM