Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 85 additions & 28 deletions ssl-cert-check
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
PROGRAMVERSION=4.14
PROGRAMVERSION=4.15
#
# Program: SSL Certificate Check <ssl-cert-check>
#
Expand All @@ -9,10 +9,13 @@ PROGRAMVERSION=4.14
#
# Author: Matty < matty at prefetch dot net >
#
# Last Updated: 11-12-2020
# Last Updated: 10-30-2022
#
# Revision History:
#
# Version 4.15
# - Add "-C" option to check the lifetime of CRLs -- Marcel Pennewiss
#
# Version 4.14
# - Fixed HOST / PORT discovery @mhow2
#
Expand Down Expand Up @@ -311,6 +314,9 @@ PKCSDBPASSWD=""
# Type of certificate (PEM, DER, NET) (cmdline: -t)
CERTTYPE="pem"

# Type of file (crl, x509)
CERTFILETYPE="x509"

# Location of system binaries
AWK=$(command -v awk)
DATE=$(command -v date)
Expand Down Expand Up @@ -557,14 +563,19 @@ print_summary()
return
fi

CERTFILETYPETEXT="certificate"
if [ "${CERTFILETYPE}" == "crl" ]; then
CERTFILETYPETEXT="crl"
fi

if [ ${SUMMARY_WILL_EXPIRE} -eq 0 ] && [ ${SUMMARY_EXPIRED} -eq 0 ]; then
${PRINTF} "%s valid certificate(s)|days=%s\n" "${SUMMARY_VALID}" "${SUMMARY_MIN_DIFF}"
${PRINTF} "%s valid ${CERTFILETYPETEXT}(s)|days=%s\n" "${SUMMARY_VALID}" "${SUMMARY_MIN_DIFF}"

elif [ ${SUMMARY_EXPIRED} -ne 0 ]; then
${PRINTF} "%s certificate(s) expired (%s:%s on %s)|days=%s\n" "${SUMMARY_EXPIRED}" "${SUMMARY_MIN_HOST}" "${SUMMARY_MIN_PORT}" "${SUMMARY_MIN_DATE}" "${SUMMARY_MIN_DIFF}"
${PRINTF} "%s ${CERTFILETYPETEXT}(s) expired (%s:%s on %s)|days=%s\n" "${SUMMARY_EXPIRED}" "${SUMMARY_MIN_HOST}" "${SUMMARY_MIN_PORT}" "${SUMMARY_MIN_DATE}" "${SUMMARY_MIN_DIFF}"

elif [ ${SUMMARY_WILL_EXPIRE} -ne 0 ]; then
${PRINTF} "%s certificate(s) will expire (%s:%s on %s)|days=%s\n" "${SUMMARY_WILL_EXPIRE}" "${SUMMARY_MIN_HOST}" "${SUMMARY_MIN_PORT}" "${SUMMARY_MIN_DATE}" "${SUMMARY_MIN_DIFF}"
${PRINTF} "%s ${CERTFILETYPETEXT}(s) will expire (%s:%s on %s)|days=%s\n" "${SUMMARY_WILL_EXPIRE}" "${SUMMARY_MIN_HOST}" "${SUMMARY_MIN_PORT}" "${SUMMARY_MIN_DATE}" "${SUMMARY_MIN_DIFF}"

fi
}
Expand Down Expand Up @@ -615,12 +626,13 @@ set_summary()
##########################################
usage()
{
echo "Usage: $0 [ -e email address ] [-E sender email address] [ -x days ] [-q] [-a] [-b] [-h] [-i] [-n] [-N] [-v]"
echo "Usage: $0 [ -e email address ] [-E sender email address] [ -x days ] [-q] [-a] [-b] [-C] [-h] [-i] [-n] [-N] [-v]"
echo " { [ -s common_name ] && [ -p port] } || { [ -f cert_file ] } || { [ -c cert file ] } || { [ -d cert dir ] }"
echo ""
echo " -a : Send a warning message through E-mail"
echo " -b : Will not print header"
echo " -c cert file : Print the expiration date for the PEM or PKCS12 formatted certificate in cert file"
echo " -C : File(s) are Certificate Revocation List"
echo " -d cert directory : Print the expiration date for the PEM or PKCS12 formatted certificates in cert directory"
echo " -e E-mail address : E-mail address to send expiration notices"
echo " -E E-mail sender : E-mail address of the sender"
Expand Down Expand Up @@ -723,7 +735,7 @@ check_file_status() {
return
fi

### Grab the expiration date from the X.509 certificate
### Grab the expiration date from the X.509 certificate or CRL
if [ "${PKCSDBPASSWD}" != "" ]; then
# Extract the certificate from the PKCS#12 database, and
# send the informational message to /dev/null
Expand All @@ -748,22 +760,38 @@ check_file_status() {
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\=//')
if [ "${CERTFILETYPE}" == "x509" ]; then
# Extract the expiration date from the certificate
CERTDATE=$("${OPENSSL}" x509 -in "${CERTFILE}" -enddate -noout -inform "${CERTTYPE}" | \
"${SED}" 's/notAfter\=//')

### Grab the common name (CN) from the X.509 certificate
COMMONNAME=$("${OPENSSL}" x509 -in "${CERTFILE}" -subject -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/.*CN = //' | \
"${SED}" -e 's/, .*//')

### Grab the serial number from the X.509 certificate
SERIAL=$("${OPENSSL}" x509 -in "${CERTFILE}" -serial -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/serial=//')

elif [ "${CERTFILETYPE}" == "crl" ]; then
# Extract the next update from the CRL
CERTDATE=$("${OPENSSL}" crl -in "${CERTFILE}" -nextupdate -noout -inform "${CERTTYPE}" | \
"${SED}" 's/nextUpdate\=//')

### Grab the last update from the CRL
LASTUPDATE=$("${OPENSSL}" crl -in "${CERTFILE}" -lastupdate -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/lastUpdate\=//')

### Grab the crl number from the CRL
SERIAL=$("${OPENSSL}" crl -in "${CERTFILE}" -crlnumber -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/crlNumber=//')
fi

# Extract the issuer from the certificate
CERTISSUER=$("${OPENSSL}" x509 -in "${CERTFILE}" -issuer -noout -inform "${CERTTYPE}" | \
# Extract the issuer from the certificate or CRL
CERTISSUER=$("${OPENSSL}" ${CERTFILETYPE} -in "${CERTFILE}" -issuer -noout -inform "${CERTTYPE}" | \
"${AWK}" 'BEGIN {RS=", " } $0 ~ /^O =/ { print substr($0,5,17)}')

### Grab the common name (CN) from the X.509 certificate
COMMONNAME=$("${OPENSSL}" x509 -in "${CERTFILE}" -subject -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/.*CN = //' | \
"${SED}" -e 's/, .*//')

### Grab the serial number from the X.509 certificate
SERIAL=$("${OPENSSL}" x509 -in "${CERTFILE}" -serial -noout -inform "${CERTTYPE}" | \
"${SED}" -e 's/serial=//')
fi

### Split the result into parameters, and pass the relevant pieces to date2julian
Expand All @@ -776,23 +804,51 @@ check_file_status() {

if [ "${CERTDIFF}" -lt 0 ]; then
if [ "${ALARM}" = "TRUE" ]; then
send_mail "${SENDER}" "${ADMIN}" "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" \
"The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!"
if [ "${CERTFILETYPE}" == "x509" ]; then
send_mail "${SENDER}" "${ADMIN}" "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" \
"The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!"

elif [ "${CERTFILETYPE}" == "crl" ]; then
send_mail "${SENDER}" "${ADMIN}" "CRL for ${HOST} \"(Last Update: ${LASTUPDATE})\" has expired!" \
"The CRL for ${HOST} \"(Last Update: ${LASTUPDATE})\" has expired!"
fi
fi

prints "${HOST}" "${PORT}" "Expired" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
if [ "${CERTFILETYPE}" == "x509" ]; then
prints "${HOST}" "${PORT}" "Expired" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"

elif [ "${CERTFILETYPE}" == "crl" ]; then
prints "${HOST}" "${PORT}" "Expired" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${LASTUPDATE}" "${SERIAL}"
fi
RETCODE_LOCAL=2

elif [ "${CERTDIFF}" -lt "${WARNDAYS}" ]; then
if [ "${ALARM}" = "TRUE" ]; then
send_mail "${SENDER}" "${ADMIN}" "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire in ${CERTDIFF} days or less" \
"The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire on ${CERTDATE}"
if [ "${CERTFILETYPE}" == "x509" ]; then
send_mail "${SENDER}" "${ADMIN}" "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire in ${CERTDIFF} days or less" \
"The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire on ${CERTDATE}"

elif [ "${CERTFILETYPE}" == "crl" ]; then
send_mail "${SENDER}" "${ADMIN}" "CRL for ${HOST} \"(Last Update: ${LASTUPDATE})\" will expire in ${CERTDIFF} days or less" \
"The CRL for ${HOST} \"(Last Update: ${LASTUPDATE})\" will expire on ${CERTDATE}"
fi
fi

if [ "${CERTFILETYPE}" == "x509" ]; then
prints "${HOST}" "${PORT}" "Expiring" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"

elif [ "${CERTFILETYPE}" == "crl" ]; then
prints "${HOST}" "${PORT}" "Expiring" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${LASTUPDATE}" "${SERIAL}"
fi
prints "${HOST}" "${PORT}" "Expiring" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
RETCODE_LOCAL=1

else
prints "${HOST}" "${PORT}" "Valid" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
if [ "${CERTFILETYPE}" == "x509" ]; then
prints "${HOST}" "${PORT}" "Valid" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"

elif [ "${CERTFILETYPE}" == "crl" ]; then
prints "${HOST}" "${PORT}" "Valid" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${LASTUPDATE}" "${SERIAL}"
fi
RETCODE_LOCAL=0
fi

Expand All @@ -804,12 +860,13 @@ check_file_status() {
#################################
### Start of main program
#################################
while getopts abc:d:e:E:f:hik:nNp:qs:St:Vx: option
while getopts abc:Cd:e:E:f:hik:nNp:qs:St:Vx: option
do
case "${option}" in
a) ALARM="TRUE";;
b) NOHEADER="TRUE";;
c) CERTFILE=${OPTARG};;
C) CERTFILETYPE="crl";;
d) CERTDIRECTORY=${OPTARG};;
e) ADMIN=${OPTARG};;
E) SENDER=${OPTARG};;
Expand Down