Forum Discussion

David_Dalgaard_'s avatar
David_Dalgaard_
Icon for Nimbostratus rankNimbostratus
Jul 25, 2013

Script to check for certificate expiration

Hi guys

 

Most of you have probably been in the situation where a certificate suddenly expired without anyone noticing (or at least no one took proper action). I was in that situation a couple of weeks ago. I asked Lord Google if someone had a good method of detecting certificate expiration automatically. I didn't really find anything relevant, except for a couple of SOLs from F5 regarding the checkcert utility. So I sat down and did some scripting myself. I'm pretty satisfied with the result, however, this is my first real bash script so you can probably find something that could be optimized or done in a better way.

 

So first of all the scripts checks if the device is the active box. If it is not, the script does nothing, but if is, the script creates a list of all expiring certificates and places them in expiringcerts.txt. This file is then checked and each line is reported separately to our servicedesk (which in return creates a case and escalates it directly to network operations). When a certificate has been reported it is put in the flaggedcerts.txt. This file ensures that a certificate is not reported multiple times, unless it is less than a week from expiring. In this case a new mail is send each time the script is ran (in our case, it is put in /etc/crontab and configured to run every day at 12 pm/noon).

 

If a certificate is deleted, expired or renewed it is no longer put in the expiringcerts.txt file and is therefore also removed from the flaggedcerts.txt file.

 

In the end a status mail is sent to me each day to ensure that the check ran as it should. This is just me that like to be absolutely sure that the script does its job.

 

___________________________

 

!/bin/bash

 

Author: dadalife

 

 

 

Check if unit is active and if it is the script should continue:

 

ACTIVE=$(tmsh show cm failover-status | grep ACTIVE | wc -l)

 

if (($ACTIVE == 1)); then

 

echo -e "Unit is active. Proceeding...\n"

 

 

 

SCRIPTPATH='/root/'

 

MAIL='servicedesk@atea.dk'

 

MAILCC='dada@atea.dk'

 

NUMREPORTED=0

 

NUMFLAGGED=0

 

NUMCRITICAL=0

 

 

 

Create a list of all expiring certificates:

 

tmsh run sys crypto check-cert | grep 'will expired' | awk -F 'in file' '{print $2}' | awk -F ' GMT' '{print $1}' > "$SCRIPTPATH"expiringcerts.txt

 

echo "A list of all expiring certificates has been created!"

 

 

 

Send an email for each certificate if it has not already been sent:

 

echo -e "\nChecking for expiring certificates..."

 

> "$SCRIPTPATH"tempflagged.txt

 

while read line; do

 

BODY="\n\nPlease create this case as an incident (Priority 3) under the customer CNM and escalate directly to OPNOM.\n\nThis is an auto-generated e-mail from the BIG-IP."

 

CERT=$(echo $line | awk -F ' ' '{print $1}')

 

CERTEXPIRE=$(echo $line | awk -F 'expired on ' '{print $2}')

 

FLAGGED=$(cat "$SCRIPTPATH"flaggedcerts.txt | grep $CERT | wc -l)

 

if (( $FLAGGED == 0)); then

 

echo $CERT >> "$SCRIPTPATH"tempflagged.txt

 

echo -e "$CERT expires on $CERTEXPIRE GMT.$BODY" | mail -s "$CERT expires on $CERTEXPIRE GMT" $MAIL -c $MAILCC

 

echo "--> $CERT reported to servicedesk."

 

NUMREPORTED=$[$NUMREPORTED +1]

 

else

 

echo $CERT >> "$SCRIPTPATH"tempflagged.txt

 

echo "--> $CERT has already been flagged"

 

NUMFLAGGED=$[$NUMFLAGGED +1]

 

fi

 

done < "$SCRIPTPATH"expiringcerts.txt

 

cp "$SCRIPTPATH"tempflagged.txt "$SCRIPTPATH"flaggedcerts.txt

 

echo -e "Check for expiring certificates done!"

 

 

 

Check if a certificate is less than a week from expiring:

 

CURRENTTIMEEPOCH=$(date +%s)

 

echo -e "\nChecking for almost expired certificates..."

 

while read line; do

 

CERTEXPIRE=$(echo $line | awk -F 'expired on ' '{print $2}')

 

CERTEXPIREEPOCH=$(date --date="$CERTEXPIRE" +%s)

 

CERTEXPIREDIFF=$(expr $CERTEXPIREEPOCH - $CURRENTTIMEEPOCH)

 

if (($CERTEXPIREDIFF < 604800)); then

 

BODY="\n\nPlease create this case as an incident (Priority 1) under the customer CNM and escalate directly to OPNOM.\n\nThis is an auto-generated e-mail from the BIG-IP."

 

CERT=$(echo $line | awk -F ' ' '{print $1}')

 

echo -e "$CERT expires on $CERTEXPIRE GMT.$BODY" | mail -s "WARNING: $CERT EXPIRES IN LESS THAN A WEEK!!" $MAIL -c $MAILCC

 

echo "--> WARNING: $CERT EXPIRES IN LESS THAN A WEEK!!"

 

NUMCRITICAL=$[$NUMCRITICAL +1]

 

fi

 

done < "$SCRIPTPATH"expiringcerts.txt

 

echo "Check for almost expired certificates done!"

 

 

 

echo -e "\nCertification check done!"

 

 

 

Send a status email:

 

echo -e "Hi David\n\nYour script did its job!!\n\nNumber of newly reported certificates: '$NUMREPORTED'\nNumber of already flagged certificates: '$NUMFLAGGED'\nNumber of critical certificates: '$NUMCRITICAL'\n\nYours Sincerely\nThe BIG-IP" | mail -s "Everthing went well!" $MAILCC

 

 

 

else

 

echo "Unit is standby. No action taken!"

 

fi

 

___________________

 

Feel free to comment on anything! :)

 

 

Thanks,

 

David

 

  • REastman_249266's avatar
    REastman_249266
    Historic F5 Account

    Your syntax is incorrect compared to the posted code. You don't have a space between the single quotes before print. Posted code: CERTEXPIRE=$(echo $line | awk -F 'expired on ' '{print $2}') Your code: CERTEXPIRE=$(echo $line | awk -F 'expired on ''{print $2}')

     

  • I dont think that was it. I made the change and still same result, this is the full email I get:

     

    /Common/appnet-test.crt expires on  GMT.
    If it was not previously done, please create a Service Now Ticket for Systems team in order to renew the certificate.
    
    Ignore this alarm if the certificate is /Common/ca-bundle.crt
    
    
    This is an auto-generated e-mail from the BIG-IP.
    

     

    These are my files created by the script:

    expiringcerts.txt /Common/appnet-test.crt will expire on Jan 20 23:59:59 2018 /Common/appnet-test.crt will expire on Jan 20 23:59:59 2018 /Common/appnet-test.crt will expire on Jan 20 23:59:59 2018 /Common/appnet-test.crt will expire on Jan 20 23:59:59 2018 /Common/appnet-test.crt will expire on Jan 20 23:59:59 2018

    flaggedcerts.txt /Common/appnet-test.crt /Common/appnet-test.crt /Common/appnet-test.crt /Common/appnet-test.crt /Common/appnet-test.crt

    tempflagged.txt /Common/appnet-test.crt /Common/appnet-test.crt /Common/appnet-test.crt /Common/appnet-test.crt /Common/appnet-test.crt

     

  • Hi,

    my script also started to fail after upgrading to 12.1, seems that they changed some parts of the output text of "run sys crypto check-cert" and the regex fails.

    Change

     

    CERTEXPIRE=$(echo $line | awk -F 'expired on ''{print $2}')
    

     

    to

     

    CERTEXPIRE=$(echo $line | awk -F 'expire on ' '{print $2}')
    

     

    (note the missing d) and it should work fine.

    also check the following line at the beginning ot the script:

     

    tmsh -c "cd /; run sys crypto check-cert" | grep 'will expire' | awk -F 'in file' '{print $2}' >> "$SCRIPTPATH"expiringcerts.txt
    

     

    Kind regards.