#!/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][0-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][0-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