diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rwxr-xr-x | crypt-expiry-check.in | 124 |
3 files changed, 74 insertions, 55 deletions
@@ -5,3 +5,4 @@ man.commons *.1 crypt-expiry-check.service crypt-expiry-check.timer +.idea @@ -26,7 +26,7 @@ BINDIR = /usr/bin MANDIR = /usr/share/man SYSTEMDDIR = /usr/lib/systemd/system -VERSION = 4.3.5 +VERSION = 4.4.3 all: man.commons crypt-expiry-check crypt-expiry-check.cron crypt-expiry-check.1 crypt-expiry-check.service crypt-expiry-check.timer @@ -53,7 +53,7 @@ install: all clean: ls -A | \ grep "^\($(shell sed 's|\.|\\.|; s|\*|.*|; s|$$|\\|' .gitignore | tr '\n' '\|')\)\$$" | \ - xargs -r rm + xargs -r rm -rf --one-file-system dist: clean git status --porcelain 2> /dev/null | grep -q "\S" && (git add .; git commit -m"neue Version: $(VERSION)") || true diff --git a/crypt-expiry-check.in b/crypt-expiry-check.in index 2fe37ff..7ce5eae 100755 --- a/crypt-expiry-check.in +++ b/crypt-expiry-check.in @@ -6,13 +6,13 @@ # Author of ssl-cert-check: Matty < matty91 at gmail dot com > # Maintainer of crypt-expiry-check: Erich < crux at eckner dot net > # -# Purpose: +# Purpose: # crypt-expiry-check checks to see if a digital certificate in X.509 format -# or a GnuPG-key has expired. ssl-cert-check can be run in interactive -# and batch mode, and provides facilities to alarm if a certificate is +# or a GnuPG-key has expired. ssl-cert-check can be run in interactive +# and batch mode, and provides facilities to alarm if a certificate is # about to expire. # -# License: +# License: # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -25,12 +25,12 @@ # # Requirements: # Requires openssl gnupg -# -# Installation: +# +# Installation: # Copy the shell script to a suitable location # # Usage: -# Refer to the usage() sub-routine, or invoke crypt-expiry-check +# Refer to the usage() sub-routine, or invoke crypt-expiry-check # with the "-h" option. PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/ssl/bin:/usr/sfw/bin @@ -85,7 +85,7 @@ SORT=$(which sort) TAIL=$(which tail) MKTEMP=$(which mktemp) GPG=$(which gpg) -HOSTNAME=$(hostname) +HOSTNAME=$(uname -n) # Try to find a mail client MAIL="cantfindit" @@ -113,26 +113,36 @@ set_retcode() [ ${RETCODE} -lt $1 ] && RETCODE=$1 } +format_date() +{ + if echo "$*" | ${GREP} -qx '[0-9]\+'; then + ${DATE} '+%F' -d@"$*" + elif echo "$*" | ${GREP} -qx '[0-9]\+-[0-9]\+-[0-9]\+'; then + ${DATE} '+%F' -d"$*" + else + ${DATE} -d"$(echo "$*" | ${AWK} '{ print $1, $2, $4 }')" +%F + fi +} + ##################################################################### # Purpose: Print a line with the expiraton interval # Arguments: # $1 -> Hostname -# $2 -> TCP Port +# $2 -> TCP Port # $3 -> Status of certification (e.g., expired or valid) # $4 -> Date when certificate will expire -# $5 -> Days left until the certificate will expire +# $5 -> Days left until the certificate will expire # $6 -> Issuer of the certificate ##################################################################### -prints() +prints() { if ${ISSUER} && ! ${VALIDATION} then - MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }') if ${NAGIOS} then - ${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "${MIN_DATE}" \|days="$5" + ${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "$4" \|days="$5" else - ${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "${MIN_DATE}" "$5" + ${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "$4" "$5" fi elif ${ISSUER} && ${VALIDATION} then @@ -140,13 +150,12 @@ prints() elif ! ${VALIDATION} then - MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }') if ${NAGIOS} then - ${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "${MIN_DATE}" \|days="$5" + ${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "$4" \|days="$5" else - ${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "${MIN_DATE}" "$5" - fi + ${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "$4" "$5" + fi else ${PRINTF} "%-35s %-35s %-32s\n" "$1:$2" "$7" "$8" fi @@ -158,10 +167,10 @@ prints() # Arguments: # None #################################################### -print_heading() +print_heading() { if ! ${NOHEADER} - then + then if ${ISSUER} && ! ${NAGIOS} && ! ${VALIDATION} then ${PRINTF} "\n%-35s %-17s %-8s %-11s %-4s\n" "Host" "Issuer" "Status" "Expires" "Days" >> ${STDOUT_TMP} @@ -171,12 +180,12 @@ print_heading() then ${PRINTF} "\n%-35s %-35s %-32s %-17s\n" "Host" "Common Name" "Serial #" "Issuer" >> ${STDOUT_TMP} echo "----------------------------------- ----------------------------------- -------------------------------- -----------------" >> ${STDOUT_TMP} - + elif ! ${NAGIOS} && ! ${VALIDATION} then ${PRINTF} "\n%-47s %-12s %-12s %-4s\n" "Host" "Status" "Expires" "Days" >> ${STDOUT_TMP} echo "----------------------------------------------- ------------ ------------ ----" >> ${STDOUT_TMP} - + elif ! ${NAGIOS} && ${VALIDATION} then ${PRINTF} "\n%-35s %-35s %-32s\n" "Host" "Common Name" "Serial #" >> ${STDOUT_TMP} @@ -192,11 +201,11 @@ print_heading() # Arguments: # None ########################################## -usage() +usage() { >&2 echo "$(basename "$0") checks expiration of gpg keys and X.509 certificates and sends emails if keys are about to expire." >&2 echo "" - >&2 echo "Usage: $0 [ -e email address ] [ -x days ] [-q] [-a] [-b] [-h] [-i] [-n] [-v] { [ -s common_name:port] } || { [ -f cert_file ] } || { [ -c certificate file ] } || { [ -g email address ] }" + >&2 echo "Usage: $0 [ -e email address ] [ -x days ] [-q] [-a] [-b] [-h] [-i] [-n] [-v] { [ -s common_name:port] } || { [ -f cert_file ] } || { [ -c certificate file ] } || { [ -g email address ] }" >&2 echo "" >&2 echo " -a Send a warning message through E-mail" >&2 echo " -b Will not print header" @@ -211,7 +220,7 @@ usage() >&2 echo " -n Run as a Nagios plugin" >&2 echo " -N directory Check nginx certificates in directory's config files." >&2 echo " -q Don't print anything on the console" - >&2 echo " -r url Like -c, but download cert from url. + >&2 echo " -r url Like -c, but download cert from url." >&2 echo " -s commmon_name:port Server and Port to connect to (interactive mode)" >&2 echo " -t type Specify the certificate type" >&2 echo " -v Specify a specific protocol version to use (tls, ssl2, ssl3)" @@ -242,7 +251,7 @@ check_server_status() { elif [ "_${2}" = "_pop3" -o "_${2}" = "_110" ] then TLSFLAG="-starttls pop3" - + elif [ "_${2}" = "_imap" -o "_${2}" = "_143" ] then TLSFLAG="-starttls imap" @@ -285,12 +294,12 @@ check_server_status() { then prints ${1} ${2} "Cannot resolve domain" "Unknown" | ${TEE} -a ${MAILOUT_TMP} >> ${STDOUT_TMP} set_retcode 3 - + elif ${GREP} -iq "Operation timed out" ${ERROR_TMP} then prints ${1} ${2} "Operation timed out" "Unknown" | ${TEE} -a ${MAILOUT_TMP} >> ${STDOUT_TMP} set_retcode 3 - + elif ${GREP} -iq "ssl handshake failure" ${ERROR_TMP} then prints ${1} ${2} "SSL handshake failed" "Unknown" | ${TEE} -a ${MAILOUT_TMP} >> ${STDOUT_TMP} @@ -300,7 +309,7 @@ check_server_status() { then prints ${1} ${2} "Connection timed out" "Unknown" | ${TEE} -a ${MAILOUT_TMP} >> ${STDOUT_TMP} set_retcode 3 - + else check_file_status ${CERT_TMP} $1 $2 $3 fi @@ -406,10 +415,11 @@ check_file_status() { # send the informational message to /dev/null ${OPENSSL} pkcs12 -nokeys -in ${CERTFILE} \ -out ${CERT_TMP} -clcerts -password pass:${PKCSDBPASSWD} 2> /dev/null - + # Extract the expiration date from the certificate CERTDATE=$(${OPENSSL} x509 -in ${CERT_TMP} -enddate -noout | \ ${SED} 's/notAfter\=//') + CERTDATE=$(${DATE} +%s -d "${CERTDATE}") # Extract the issuer from the certificate CERTISSUER=$(${OPENSSL} x509 -in ${CERT_TMP} -issuer -noout | \ @@ -420,14 +430,15 @@ check_file_status() { COMMONNAME=$(${OPENSSL} x509 -in ${CERT_TMP} -subject -noout | \ ${SED} -e 's/.*CN=//' | \ ${SED} -e 's/\/.*//') - + ### Grab the serial number from the X.509 certificate SERIAL=$(${OPENSSL} x509 -in ${CERT_TMP} -serial -noout | \ ${SED} -e 's/serial=//') else # Extract the expiration date from the ceriticate - CERTDATE=$(${OPENSSL} x509 -in ${CERTFILE} -enddate -noout -inform ${CERTTYPE} | \ - ${SED} 's/notAfter\=//') + CERTDATE=$(while ${OPENSSL} x509 -enddate -noout -inform ${CERTTYPE} 2>/dev/null; do :; done <${CERTFILE} | \ + ${SED} 's/notAfter\=//' | \ + xargs -rI __ ${DATE} +%s -d "__") # Extract the issuer from the certificate CERTISSUER=$(${OPENSSL} x509 -in ${CERTFILE} -issuer -noout -inform ${CERTTYPE} | \ @@ -443,7 +454,8 @@ check_file_status() { fi # Convert the date to seconds, and get the diff between NOW and the expiration date - CERTDIFF=$[$(date +%s -d "${CERTDATE}") - $(date +%s)] + CERTDIFF=$[${CERTDATE} - $(${DATE} +%s)] + CERTDATE=$(format_date "${CERTDATE}") if [ ${CERTDIFF} -lt 0 ] then CERTDIFF=$[$[${CERTDIFF}+1]/3600/24-1] @@ -488,25 +500,31 @@ check_gpg_key_status() { exit 1 fi - KEY_INFO=$(${GPG_COMMAND} --list-secret-keys "${GPG_ADDRESS}" 2> /dev/null) - [ -z "${KEY_INFO}" ] && KEY_INFO=$(${GPG_COMMAND} --list-keys "${GPG_ADDRESS}") - - KEY_DATE_STR=$( - echo "${KEY_INFO}" | \ - ${GREP} "\[\(expire[ds]\|verfallen\|verf..\?llt\):[^]]*]" | \ - ${SED} "s#^.*\[\(expire[ds]\|verfallen\|verf..\?llt\):\s*\(\S[^]]*\)].*\$#\2#" | \ - ${SORT} -r | \ - ${TAIL} -n1 - ) - if [ -z "${KEY_DATE_STR}" ] + KEYS=$(${GPG_COMMAND} --list-secret-keys --with-colons "${GPG_ADDRESS}" 2>/dev/null) + [ -z "${KEYS}" ] && KEYS=$(${GPG_COMMAND} --list-keys --with-colons "${GPG_ADDRESS}" 2>/dev/null) + + KEY_DATE=$( + echo "${KEYS}" \ + | ${AWK} -F: '$1 == "fpr" {print $10}' \ + | ${SORT} -u \ + | while read -r KEY; do + ${GPG_COMMAND} --list-keys --with-colons "${KEY}" \ + | awk -F: '$1 == "sub" || $1 == "pub" {print $7}' \ + | ${SORT} -r \ + | tail -n1 + done \ + | ${SORT} \ + | tail -n1 + ) + if [ -z "${KEY_DATE}" ] then echo "No valid gpg-key found for ${GPG_ADDRESS}." | ${TEE} -a ${MAILOUT_TMP} >> ${STDOUT_TMP} set_retcode 2 - else - KEY_DATE=$(date +%s -ud "${KEY_DATE_STR}") + return fi - KEY_DIFF=$[${KEY_DATE} - $(date +%s)] + KEY_DIFF=$[${KEY_DATE} - $(${DATE} +%s)] + KEY_DATE=$(format_date "${KEY_DATE}") if [ ${KEY_DIFF} -lt 0 ] then KEY_DIFF=$[$[${KEY_DIFF}+1]/3600/24-1] @@ -517,17 +535,17 @@ check_gpg_key_status() { if [ ${KEY_DIFF} -lt 0 ] then echo "The GPG key for ${GPG_ADDRESS} has expired!" >> ${MAILOUT_TMP} - prints "GPG" " ${GPG_ADDRESS}" "Expired" "${KEY_DATE_STR}" "${KEY_DIFF}" "" "" "" >> ${STDOUT_TMP} + prints "GPG" " ${GPG_ADDRESS}" "Expired" "${KEY_DATE}" "${KEY_DIFF}" "" "" "" >> ${STDOUT_TMP} set_retcode 2 elif [ ${KEY_DIFF} -lt ${FWARNDAYS} ] then - echo "The GPG key for ${GPG_ADDRESS} will expire on ${KEY_DATE_STR}" >> ${MAILOUT_TMP} - prints "GPG" " ${GPG_ADDRESS}" "Expiring" "${KEY_DATE_STR}" "${KEY_DIFF}" "" "" "" >> ${STDOUT_TMP} + echo "The GPG key for ${GPG_ADDRESS} will expire on ${KEY_DATE}" >> ${MAILOUT_TMP} + prints "GPG" " ${GPG_ADDRESS}" "Expiring" "${KEY_DATE}" "${KEY_DIFF}" "" "" "" >> ${STDOUT_TMP} set_retcode 1 else - prints "GPG" " ${GPG_ADDRESS}" "Valid" "${KEY_DATE_STR}" "${KEY_DIFF}" "" "" "" >> ${STDOUT_TMP} + prints "GPG" " ${GPG_ADDRESS}" "Valid" "${KEY_DATE}" "${KEY_DIFF}" "" "" "" >> ${STDOUT_TMP} fi } @@ -756,7 +774,7 @@ then ( echo "To: ${ADMIN}" echo "From: $(whoami)@$(hostname)" - echo "Subject: $(basename $0) at $(date)" + echo "Subject: $(basename $0) at $(${DATE})" echo "" cat ${MAILOUT_TMP} ) | ${MAIL} -t |