343 lines
10 KiB
Bash
Executable File
343 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
# -*- mode: sh; fill-column: 75; tab-width: 8; coding: utf-8-unix -*-
|
|
|
|
prog=`basename $0 .bash`
|
|
PREFIX=/usr/local
|
|
ROLE=toxcore
|
|
export PATH=/sbin:$PATH
|
|
|
|
[ -f /usr/local/etc/testforge/testforge.bash ] && \
|
|
. /usr/local/etc/testforge/testforge.bash
|
|
#[ -n "$TESTF_VAR_LOCAL" ] && PREFIX=$TESTF_VAR_LOCAL
|
|
. $PREFIX/bin/usr_local_tput.bash || exit 2
|
|
. /usr/local/bin/proxy_ping_lib.bash >/dev/null || \
|
|
{ ERROR loading /usr/local/bin/proxy_ping_lib.bash ; exit 3; }
|
|
|
|
|
|
#? . $PREFIX/src/usr_local_src.bash || exit 2
|
|
|
|
DNS_TRIES=3
|
|
LOGP=TestSSL_`date -u +%y-%m-%d_%H_$$`
|
|
rm -f $TMPDIR/${LOGP}*
|
|
|
|
# analyze-ssl passed files.pythonhosted.org
|
|
# INFO: 226s analyze-ssl no error = /tmp/_files.pythonhosted.org_analyze-ssl.out
|
|
[ -z "$SSLTEST_TESTS" ] && SSLTEST_TESTS="curl openssl testssl nmap" # sslscan
|
|
[ -z "$SSLTEST_CERTS" ] && SSLTEST_CERTS="/etc/ssl/certs/ca-certificates.crt /usr/local/etc/ssl/cacert-testforge.pem"
|
|
[ -z "$SSLTEST_TIMEOUT" ] && SSLTEST_TIMEOUT=30
|
|
|
|
[ -z "$SSLTEST_SOCKS_PROXY" -a -n "$socks_proxy" ] && SSLTEST_SOCKS_PROXY=$socks_proxy \
|
|
&& DBUG SSLTEST_SOCKS_PROXY=$socks_proxy
|
|
if [ -z "$SSLTEST_HTTPS_PROXY" -a -n "$https_proxy" ] ; then
|
|
SSLTEST_HTTPS_PROXY=$https_proxy
|
|
DBUG SSLTEST_HTTPS_PROXY=$SSLTEST_HTTPS_PROXY
|
|
fi
|
|
[ -z "$SSLTEST_HTTP_PROXY" -a -n "$http_proxy" ] && SSLTEST_HTTP_PROXY=$http_proxy \
|
|
&& DBUG SSLTEST_HTTP_PROXY=$http_proxy
|
|
[ -z "$BOX_BYPASS_PROXY_GROUP" ] && BOX_BYPASS_PROXY_GROUP=bin
|
|
|
|
SSL_LIB=openssl
|
|
|
|
# [ "$MODE" ] && proxy_ping_test.bash $MODE
|
|
|
|
declare -a BADSSL_SITES
|
|
BADSSL_SITES=(
|
|
self-signed.badssl.com
|
|
expired.badssl.com
|
|
mixed.badssl.com
|
|
rc4.badssl.com
|
|
hsts.badssl.com
|
|
)
|
|
declare -a GOODSSL_SITES
|
|
GOODSSL_SITES=(
|
|
files.pythonhosted.org
|
|
mirrors.dotsrc.org
|
|
deb.devuan.org
|
|
# dfw.source.kernel.org
|
|
# cdn.kernel.org
|
|
)
|
|
|
|
badssl=0
|
|
goodssl=0
|
|
[ "$#" -eq 0 ] && goodssl=1
|
|
tests="$SSLTEST_TESTS"
|
|
verbosity=2
|
|
outdir=/tmp
|
|
timeout=$SSLTEST_TIMEOUT
|
|
onion=0
|
|
TMPDIR=/tmp
|
|
SSL_PORT=443
|
|
SSL_VER=3
|
|
|
|
usage() {
|
|
echo "Usage: $0 [OPTIONS] dirs-or-files"
|
|
echo
|
|
echo " -B | --badssl - test badssl.org sites"
|
|
echo " -G | --goodssl - test good sites"
|
|
echo " -S | --ssl - tls version v1.x - 2 or 3"
|
|
echo " -O | --onion - onion"
|
|
echo " -o | --outdir=$TMPDIR - output directory"
|
|
echo " -v | --verbosity=$verbosity - verbosity 0 least 5 most"
|
|
echo " -T | --timeout=$timeout - timeout in sec."
|
|
echo " -E | --tests=`sed -e 's/ /,/g' <<< $tests` - tests, comma separated"
|
|
echo " -C | --certs=`sed -e 's/ /,/g' <<< $SSLTEST_CERTS` - tests, comma separated"
|
|
echo " -Y | --ciphers - comma sep list of ciphers"
|
|
echo " -P | --port - port default $SSL_PORT"
|
|
echo " -N | --connect - connect"
|
|
echo
|
|
echo " -V | --version - print version of this script"
|
|
echo " -h | --help - print this help"
|
|
}
|
|
|
|
SHORTOPTS="hVGBv:T:C:P:S:E:Y:ON:"
|
|
LONGOPTS="help,version:,goodssl,badssl,verbosity:,timeout,certs:,port:,ssl:,tests:,ciphers:,onion,connect:"
|
|
declare -a SITES
|
|
SITES=()
|
|
|
|
ARGS=$(getopt --options $SHORTOPTS --longoptions $LONGOPTS -- "$@")
|
|
[ $? != 0 ] && { ERROR "error parsing getopt" ; exit 4 ; }
|
|
|
|
eval set -- "$ARGS"
|
|
|
|
while true; do
|
|
case "$1" in
|
|
-o|--outdir)
|
|
shift
|
|
TMPDIR="$1"
|
|
;;
|
|
-v|--verbosity)
|
|
shift
|
|
verbosity="$1"
|
|
;;
|
|
-T|--timeout)
|
|
shift
|
|
timeout="$1"
|
|
;;
|
|
-S|--ssl)
|
|
shift
|
|
SSL_VER="$1"
|
|
;;
|
|
-P|--port)
|
|
shift
|
|
SSL_PORT="$1"
|
|
;;
|
|
-N|--connect)
|
|
shift
|
|
SSL_CONNECT="$1"
|
|
;;
|
|
-C|--certs)
|
|
shift
|
|
SSLTEST_CERTS="`sed -e 's/,/ /g' <<< $1`"
|
|
;;
|
|
-Y|--ciphers)
|
|
shift
|
|
SSLTEST_CIPHERS="`sed -e 's/,/ /g' <<< $1`"
|
|
;;
|
|
-t|--tests)
|
|
shift
|
|
tests="`sed -e 's/,/ /g' <<< $1`"
|
|
;;
|
|
-O|--onion)
|
|
onion=1
|
|
;;
|
|
-G|--goodssl)
|
|
goodssl=1
|
|
badssl=0
|
|
;;
|
|
-B|--badssl)
|
|
badssl=1
|
|
goodssl=0
|
|
;;
|
|
-V|--version)
|
|
usage
|
|
exit 0
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
'--')
|
|
shift
|
|
SITES=("$@")
|
|
break
|
|
;;
|
|
*)
|
|
{ ERROR "unrecognized arguments $*" ; exit 5 ; }
|
|
break
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
[ "${#SITES[*]}" -eq 0 -a $badssl -gt 0 ] && SITES=("${BADSSL_SITES[@]}")
|
|
[ "${#SITES[*]}" -eq 0 -a $goodssl -gt 0 ] && SITES=("${GOODSSL_SITES[@]}")
|
|
[ "${#SITES[@]}" -eq 0 ] && { ERROR "no arguments $*" ; exit 7 ; }
|
|
|
|
[ "$SSL_VER" -ge 2 -a "$SSL_VER" -le 3 ] || { ERROR "SSL_VER $SSL_VER" ; exit 6 ; }
|
|
[ -d "$TMPDIR" ] || mkdir -p "$TMPDIR" || { ERROR "mkdir $TMPDIR" ; exit 8 ; }
|
|
|
|
[ $onion -eq 0 ] && TIMEOUT=$timeout || TIMEOUT=`expr $timeout \* 2`
|
|
SSLTEST_TESTS="$tests"
|
|
declare -a tests_ran
|
|
tests_ran=()
|
|
|
|
grep -q "^wlan[1-9][ ]00000000" /proc/net/route || { WARN "not connected" ; exit 0 ; }
|
|
|
|
IF=`route | grep ^def |sed -e 's/.* //'`
|
|
[ -n "$IF" ] || { ERROR "no IF" ; exit 10 ; }
|
|
|
|
IP=`ifconfig $IF|grep -A 2 ^wlan |grep inet | sed -e 's/.*inet //' -e 's/ .*//'`
|
|
[ -n "$IP" ] || { ERROR "no IP" ; exit 11 ; }
|
|
|
|
[ -z "$socks_proxy" ] || . /usr/local/bin/proxy_export.bash
|
|
|
|
netstat -nle4 | grep -v grep | grep -q 0.1:53 || \
|
|
{ WARN "DNS not running - netstat " ; }
|
|
|
|
# iptables-legacy-save | grep "OUTPUT -o wlan4 -m owner --gid-owner 2 -j ACCEPT"
|
|
|
|
# uses TIMEOUT=30
|
|
. $PREFIX/bin/toxcore_ssl_lib.bash
|
|
|
|
if [ "$USER" = bin ] ; then
|
|
[ -z "$SOCKS_HOST" ] && SOCKS_HOST=
|
|
[ -z "$SOCKS_PORT" ] && SOCKS_PORT=
|
|
[ -z "$SOCKS_DNS" ] && SOCKS_DNS=9053
|
|
else
|
|
DEBUG=0 proxy_ping_get_socks >/dev/null
|
|
[ -z "$SOCKS_HOST" ] && SOCKS_HOST=127.0.0.1
|
|
[ -z "$SOCKS_PORT" ] && SOCKS_PORT=9050
|
|
[ -z "$SOCKS_DNS" ] && SOCKS_DNS=9053
|
|
fi
|
|
|
|
if [ "$USER" = bin ] ; then
|
|
TORSOCKS=""
|
|
elif [ $SOCKS_HOST != 127.0.0.1 ] ; then
|
|
TORSOCKS="torsocks --address $SOCKS_HOST --port $SOCKS_PORT "
|
|
elif [ $SOCKS_PORT != 9050 ] ; then
|
|
TORSOCKS="torsocks --port $SOCKS_PORT "
|
|
else
|
|
TORSOCKS="torsocks "
|
|
fi
|
|
|
|
if [ -n "$SSLTEST_HTTPS_PROXY" ] ; then
|
|
grep -q "SocksPolicy *accept *$IP" /etc/tor/torrc || \
|
|
{ WARN "need SocksPolicy accept $IP in /etc/tor/torrc" ; }
|
|
fi
|
|
|
|
# This works off the $https_proxy environment variable in the form http://127.0.0.1:9128
|
|
# so you can test trans routing by call this with that unset.
|
|
ssltest_proxies $onion
|
|
|
|
rm -f $TMPDIR/${LOGP}.*.*
|
|
OUTF=$TMPDIR/${LOGP}.out
|
|
for CAFILE in $SSLTEST_CERTS ; do
|
|
grep -q "^wlan[1-9][ ]00000000" /proc/net/route || {
|
|
WARN $prog we are not connected >&2
|
|
exit `expr 256 - 1`
|
|
}
|
|
|
|
[ -f $CAFILE ] || { ERROR "CAfile not found $CAFILE" ; continue ; }
|
|
DATE DBUG CAFILE=$CAFILE --address $SOCKS_HOST --port $SOCKS_PORT
|
|
|
|
cacert=`basename $CAFILE`
|
|
for site in "${SITES[@]##*/}" ; do
|
|
warns=0
|
|
IF=`route | grep ^def |sed -e 's/.* //'`
|
|
[ -n "$IF" ] || { WARN "$site no route" ; continue ; }
|
|
|
|
SITE_OUTF=$TMPDIR/${LOGP}_${site}.out
|
|
DEBUG=1 DATE DBUG $site CAFILE=$CAFILE $SITE_OUTF | tee -a $SITE_OUTF
|
|
|
|
# ERROR: Could not resolve hostname www.devuan.org.
|
|
i=0
|
|
while [ $i -le $DNS_TRIES ] ; do
|
|
if [ $onion -eq 0 ] ; then
|
|
site_ip=`dig $site +retry=5 +tries=2 +noall +answer +short | awk '{ print $1 }'` && break
|
|
else
|
|
site_ip=`tor-resolve -4 $site` && break
|
|
fi
|
|
i=`expr $i + 1`
|
|
sleep 5
|
|
done
|
|
[ $i -ge $DNS_TRIES ] && ERROR failed resolve $site | tee -a $SITE_OUTF
|
|
[ $i -ge $DNS_TRIES ] && site_ip=$site
|
|
|
|
elt=sslscan
|
|
SSLSCAN_ELTS="$SSLSCAN_ARGS --certs $CAFILE --sni-name $site"
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_sslscan $elt $site $SITE_OUTF $site_ip
|
|
|
|
elt=openssl
|
|
OPENSSL_ELTS="$OPENSSL_ARGS -CAfile $CAFILE -servername $site"
|
|
[ -n "$SSL_CONNECT" ] && OPENSSL_ELTS="$OPENSSL_ARGS -connect ${SSL_CONNECT}:$SSL_PORT"
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
[ $onion -eq 0 ] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_openssl $elt $site $SITE_OUTF $site_ip
|
|
|
|
elt=testssl
|
|
rm -f $TMPDIR/${LOGP}.$site.$elt.json # --jsonfile-pretty $TMPDIR/${LOGP}.$site.$elt.json
|
|
TESTSSL_ELTS="$TESTSSL_ARGS --add-ca $CAFILE --append --ip $site_ip"
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
[ $onion -eq 0 ] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_testssl $elt $site $SITE_OUTF $site_ip
|
|
|
|
elt=analyze-ssl
|
|
ANALYZE_ELTS="$ANALYZE_ARGS --CApath $CAFILE --name $site"
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
[ $SSL_PORT = 443 ] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_analyze_ssl $elt $site $SITE_OUTF $site_ip
|
|
|
|
elt=curl
|
|
CURL_ELTS="$CURL_ARGS --cacert $CAFILE --output /dev/null"
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_curl $elt $site $SITE_OUTF $site_ip
|
|
|
|
elt=nmap
|
|
NMAP_ELTS="$NMAP_ARGS --host-timeout $TIMEOUT -p $SSL_PORT"
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_nmap $elt $site $SITE_OUTF $site_ip
|
|
|
|
elt=ssllabs
|
|
[ $SSL_PORT = 443 ] && \
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_ssllabs $elt $site $SITE_OUTF $site_ip
|
|
done
|
|
done
|
|
|
|
# bonus
|
|
elt=alt_svc
|
|
[ $SSL_PORT = 443 ] && \
|
|
[[ $SSLTEST_TESTS =~ .*${elt}.* ]] && \
|
|
tests_ran+=($elt) && \
|
|
ssltest_http2_alt_svc $elt - $SITE_OUTF -
|
|
|
|
cat $TMPDIR/${LOGP}_*.out > $OUTF
|
|
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
|
|
a=`openssl ciphers -v 'ECDH+AESGCM:ECDH+CHACHA20:ECDH+AES256:ECDH+AES128:!aNULL:!SHA1:!AESCCM' | wc -l | sed -e 's/ .*//'`
|
|
[ $? -eq 0 ] && [ "$a" -eq 0 ] && \
|
|
WARN "no openssl ciphers" | tee -a $OUTF
|
|
|
|
DEBUG=1 DBUG "${#tests_ran[@]}" TESTS="${tests_ran[@]}"
|
|
warns=`grep -c WARN: $OUTF`
|
|
[ $? -eq 0 ] && [ "$warns" -gt 0 ] && DATE WARN "$warns warns for $site in $OUTF"
|
|
errs=`grep -c 'ERROR:\|EROR:' $OUTF`
|
|
[ $? -eq 0 ] && [ "$errs" -gt 0 ] && DATE ERROR "$errs errs for $site in $OUTF"
|
|
[ $? -eq 0 ] && [ "$warns" -eq 0 -a "$errs" -eq 0 ] && \
|
|
DATE INFO "NO warns/errs for $site in $OUTF"
|
|
|
|
exit $errs
|
|
|
|
# pysslscan scan --scan=protocol.http --scan=vuln.heartbleed --scan=server.renegotiation \
|
|
# --scan=server.preferred_ciphers --scan=server.ciphers \
|
|
# --report=term:rating=ssllabs.2009e --ssl2 --ssl3 --tls10 --tls11 --tls12
|
|
# /usr/local/bin/ssl-cipher-check.pl
|
|
|