We just had an issue with an expired SSL certificate. Although the customer had a monitoring system in place, this system failed to inform the administrators of the upcoming certificate expiration which the leads to a system downtime this morning.
In order to be independent of the customer monitoring, I created a short Linux shell script which does the certificate checking by itself and sends out a notification mail if the certificate expiration date is less than x days away.
We are running this script every week via a cron job and let us warn 60 days in advance of the expiration date. So hopefully this will not happen again in future …
Here is the code of the script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
#!/bin/bash ########################################################################################## # check_connections.sh / V1.0 / mu # # V1.0: 2019-10-01 - Initial version # # Check the expiration date of a server SSL certificate # # Usage: # ./checkSSLExpiration.sh hostname:port warning_days # # hostname:port The hostname and the port which should be checked. If no port is specified then 443 will be used # warning_days If the certificate will expire in less or equal warning_days a warning will be sent via mail. If parameter not specified 30 days is used # # Prerequisites: # The server where the checks are running need access to the host via the specified port The server also needs to be able to send SMTP mails # via the SMTP relay configured below. # It uses OpenSSL to check the certificate and mailx to send notification mails # ########################################################################################## # Define some variables errorCode=0 # Sender Address # Specify here the sender address of the notification mails sender="SSL Certificate Notification <noreply@example.org>" # SMTP gateway # Define here the full qualified DNS name of the SMTP gateway which should be used to send notification mails. smtpmx="smtp.example.org" # Recipients address where to send notification mails recipients="user1@example.org user2@example.org" # Check if at least one parameter is given; if yes, use that as hostName:port if [ -z "$1" ] then echo "Usage: ./checkSSLExpiration.sh hostname:port [warning_days]" exit 1 else hostNameWithPort=$1 fi hostName=`echo $hostNameWithPort | cut -d: -f 1` port=`echo $hostNameWithPort | cut -d: -f 2 -s` # If there is no port number, use 443 as default if [ "$port" == "" ] then port="443" hostNameWithPort="$hostName:$port" fi # Check if a second parameter is given; if yes, use that as warning_days. If not, use 30 days as default if [ -z "$2" ] then warning_days="30" else warning_days=$2 fi # Check if certificate can be read; if there is an error, report it and end the script # Specify a timeout of 5 seconds in case the host does not answer checkCertificateOk=`timeout 5 openssl s_client -servername $hostName -connect $hostNameWithPort 2>/dev/null <<< "Q"` if [ $? -gt 0 ] then echo "ERROR - Cannot get certificate. Maybe wrong hostnam or port?" exit 1 fi # Get the expiration date and time for the certificate expirationdate=`date --date="$( echo | openssl s_client -servername $hostName -connect $hostNameWithPort 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f 2)"` # Get the expiration date and time for the certificate as number of seconds expirationdate_days=`date --date="$( echo | openssl s_client -servername $hostName -connect $hostNameWithPort 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f 2)" "+%s"` # Ge the current date / time as nnumber of seconds today_days=$(date -d "today" "+%s") # Calculcate the difference of the two times and convert it to days numberOfDays=$(( ($expirationdate_days - $today_days)/(60*60*24) )) # Report the result echo " " echo "The certificate of" echo " $hostName" echo "expires on" echo " $expirationdate" echo "which is in $numberOfDays days from now!" if [ $numberOfDays -gt $warning_days ] then # evertyhing ok, the certificate will expire later than the warning_days echo " " echo "OK - Expiration date is more than $warning_days days in future." echo " " errorCode=0 elif [ $numberOfDays -le 0 ] then # Report ERROR as the certificate has already expired echo " " echo "ERROR - Certificate has expired!" echo " " errorCode=99 subject="$hostName - SSL Certificate has expired" body="ATTENTION: The certificate of $hostName has expired on $expirationdate!" else # Report WARNING as the certificate will expire within warning_days. echo " " echo "WARNING - Expiration date is near!" echo " " errorCode=10 subject="$hostName - SSL Certificate expires in $numberOfDays days" body="ATTENTION: The certificate of $hostName expires on $expirationdate which is in $numberOfDays days from now!" fi if [ "$errorCode" -eq 0 ]; then # No errors found. Just end exit $errorCode else # Send notification mail echo -e $body | /bin/mailx -v -s "$subject" -S smtp=smtp://$smtpmx -r "$sender" $recipients >/dev/null 2>&1 echo "Mail notification sent" echo " " exit $errorCode fi |
SSL Certificate Expiration Checking