1
0
Fork 0
scripts-admin-quickndirty-p.../nagios/check_dane_tlsa.sh

118 lines
3.5 KiB
Bash
Executable file

#!/bin/sh
# Not needed in this version of the script
set -e
PROGPATH=$( echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,' )
REVISION="0.1"
. $PROGPATH/utils.sh
#
# Help function
#
usage() {
cat <<EOF
Usage :
$0 -h
$0 -H host -p port [-P protocol (tcp/udp)] [-S starttls-scheme (smtp)]
EOF
}
#
# Parameters management
#
CHECKED_PROTOCOL="tcp" # it's almost always TCP so we don't bother to ask
OPENSSL_OPTIONS=""
while getopts hH:p:P:S: f; do
case "$f" in
'h')
usage
exit
;;
'H')
CHECKED_HOSTNAME="$OPTARG"
;;
'p')
CHECKED_PORT="$( printf "%d" "$OPTARG" )"
;;
'P')
CHECKED_PROTOCOL="$OPTARG"
;;
'S')
OPENSSL_OPTIONS="$OPENSSL_OPTIONS -starttls $OPTARG"
;;
\?)
usage
exit 1
;;
esac
done
if [ -z "$CHECKED_HOSTNAME" ]; then echo "ERROR empty parameter 'hostname'"; exit $STATE_UNKNOWN; fi
if [ -z "$CHECKED_PORT" ]; then echo "ERROR empty parameter 'port'"; exit $STATE_UNKNOWN; fi
# We get all TLSA record for the host
# FIXME: make a loop
# return example : "1 1 1 4A2403E87DBC4354570C5FDE24348EAED50B7791E4E2C3FC1D79B487 DDB9CC2C"
REQUEST_RECORD="_$CHECKED_PORT._$CHECKED_PROTOCOL.$CHECKED_HOSTNAME"
TLSA_RECORD="$( dig "$REQUEST_RECORD" TLSA +short | sed -n 's/^\([0-3]\)[[:space:]]\([01]\)[[:space:]]\([01]\)[[:space:]]/\1;\2;\3;/p' | sed 's/[[:space:]]//g' )"
if [ -z "$TLSA_RECORD" ]; then echo "ERROR no TLSA record at $REQUEST_RECORD"; exit $STATE_CRITICAL; fi
if [ -z "$( echo "$TLSA_RECORD" | sed -n '/^.;/p' )" ]; then echo "ERROR record malformed or too modern for this plugin"; exit $STATE_CRITICAL; fi
CPT=0
OUTPUT_STATUS=$STATE_OK
OUTPUT_DETAILS=""
MATCH_NUMBER=0
for LINE in $TLSA_RECORD; do
CERTIFICATE_USAGE="$( echo "$LINE" | cut -d ';' -f 1 )"
SELECTOR="$( echo "$LINE" | cut -d ';' -f 2 )"
MATCHING_TYPE="$( echo "$LINE" | cut -d ';' -f 3 )"
DATA="$( echo "$LINE" | cut -d ';' -f 4 )"
# PKI verification (TODO: to implement)
if [ "$CERTIFICATE_USAGE" -eq "0" ] || [ "$CERTIFICATE_USAGE" -eq "1" ]; then
OUTPUT_DETAILS="$OUTPUT_DETAILS (PKI check not implemented)"
fi
# Pointer
if [ "$CERTIFICATE_USAGE" -eq "1" ] || [ "$CERTIFICATE_USAGE" -eq "3" ]; then
# Check the certificate directly
case "$MATCHING_TYPE" in
'0')
# Entire info in base64
# TODO
;;
'1')
# SHA-256
OPENSSL_RESULT="$( openssl s_client $OPENSSL_OPTIONS -connect $CHECKED_HOSTNAME:$CHECKED_PORT -servername $CHECKED_HOSTNAME </dev/null 2>/dev/null | openssl x509 -pubkey -noout | openssl rsa -pubin -outform DER 2>/dev/null | openssl dgst -sha256 | tr a-z A-Z | sed 's/.*[[:space:]]//' )"
;;
'2')
# SHA-512
OPENSSL_RESULT="$( openssl s_client $OPENSSL_OPTIONS -connect $CHECKED_HOSTNAME:$CHECKED_PORT -servername $CHECKED_HOSTNAME </dev/null 2>/dev/null | openssl x509 -pubkey -noout | openssl rsa -pubin -outform DER 2>/dev/null | openssl dgst -sha512 | tr a-z A-Z | sed 's/.*[[:space:]]//' )"
;;
esac
if [ "$( echo "$DATA" | tr a-z A-Z )" = "$OPENSSL_RESULT" ]; then
OUTPUT_DETAILS="$OUTPUT_DETAILS $( echo $LINE | sed 's/^\(.\{8\}\).*\(.\{3\}\)$/\1...\2/' )-ok"
MATCH_NUMBER=$(( $MATCH_NUMBER + 1 ))
else
OUTPUT_DETAILS="$OUTPUT_DETAILS $( echo $LINE | sed 's/^\(.\{8\}\).*\(.\{3\}\)$/\1...\2/' )-NO"
fi
else
# Check one of the trust anchor
# TODO: to implement
OUTPUT_DETAILS="$OUTPUT_DETAILS (trust anchor check not implemented)"
fi
done
if [ "$MATCH_NUMBER" -eq 0 ]; then
echo "ERROR no match $OUTPUT_DETAILS"
exit $STATE_CRITICAL
else
echo "OK $OUTPUT_DETAILS"
exit $STATE_OK
fi