Press "Enter" to skip to content

Checking SSL Certificate expiration dates

Managing a lot of SSL certificates? Hate being surprised when they expire on you and break your web site? How about a simple process to notify you in advance?

All of the above sound about right? It does to me, I literally manage close to 100 web sites that require SSL encryption for sensitive data transfers, it seems almost impossible to get and keep them all lined up for expiration dates. Even when they were something new would come along and mess up the rotation, in short order it looks like a shotgun blast to a calendar was the deciding factor.

Here is an easy perl script I wrote to check the dates of existing SSL certs, it gets the URL list to check from certs.urls, compares the certificate expiration date to the current date and send emails at the specified intervals. Pretty simple, but like most, it’s very effective when run daily via cron.

I’ve edited some of the partially confidential stuff out, but not enough to render the script unusable by any means, just set the email.sr to your local email faciltiy.

[code]
#! /usr/local/bin/perl
#
# check_ssl_expire.pl, v 0.01
#
# Inital version – Dave Cochran 9/13/07
###########################################################
use Switch;
use Time::Local;

unshift(@INC, “/pshome/psmgr/bin”);
unshift(@INC, “/pshome/psmgr/bin.test”) if (“/pshome/psmgr/bin.test” eq “$ENV{‘PWD’}”);
unshift(@INC, “/pshome/psmgr/stat/bin”) if (“/pshome/psmgr/stat/bin” eq “$ENV{‘PWD’}”);
require sr;

$debug = 0;
$debug = 1 if (“/pshome/psmgr/bin.test” eq “$ENV{‘PWD’}”);
$debug = 1 if (“/pshome/psmgr/stat/bin” eq “$ENV{‘PWD’}”);
$execute = 1;

$path = “/pshome/tmp”;
@urls = `cat /pshome/psmgr/files/cert.urls`;

foreach $url (@urls) { # start for each url
chomp $url;
print “nChecking $urln”;
$cmd = “echo “” | openssl s_client -connect $url:443 > $path/certificate”;
print “nn $cmdnn” if ($debug);
system ($cmd) if ($execute);

$cmd = “openssl x509 -in $path/certificate -noout -enddate > $path/outdate”;
print ” $cmdnn” if ($debug);
system ($cmd) > $result if ($execute);

open (OUTDATE, “/pshome/tmp/outdate”) || die “couldn’t open the file!”;
$enddate = ;
chomp $enddate;
close(OUTDATE);
print “SSL enddate is: < $enddate>n” if ($debug);
$expire = substr($enddate, 9, 20);
print “Expire date : < $expire>n” if ($debug);
$month = substr($expire, 0, 3);
$day = substr($expire, 4, 2);
$year = substr($expire, 16, 4);

switch (“$month”)
{
case “Jan” { $month = 0 }
case “Feb” { $month = 1 }
case “Mar” { $month = 2 }
case “Apr” { $month = 3 }
case “May” { $month = 4 }
case “Jun” { $month = 5 }
case “Jul” { $month = 6 }
case “Aug” { $month = 7 }
case “Sep” { $month = 8 }
case “Oct” { $month = 9 }
case “Nov” { $month = 10 }
case “Dec” { $month = 11 }
else { print “$month is not a valid month. You have problems!n” }
} # end switch on month
$day =~ s/ /0/;
$expire_date = timegm(1,0,0,$day,$month,$year – 1900);
$today = `date +%Y%m%d`;
chomp $today;
$today = timegm(1,0,0,`date +%d`,`date +%m` -1,`date +%Y` – 1900);
$thirty_days = $today + (86400 * 30);
$fifteen_days = $today + (86400 * 15);
$seven_days = $today + (86400 * 7);
$one_day = ($today + 86400);

print “Today is < $today> and the cert expires on < $expire_date>n” if ($debug);
print “1 day is < $one_day>n” if ($debug);
print “7 days is < $seven_days>n” if ($debug);
print “15 days is < $fifteen_days>n” if ($debug);
print “30 days is < $thirty_days>n” if ($debug);

$subject = “$url certificate expiration”;
if ($today > $expire_date) { # start if the certificate is expired
&sr::send_page($debug,”$url cert expired”,’Paul Hofmann’,’David Cochran’);
$message = “The $url certificate is expired”;
print “t$messagen”;
&sr::send_email($debug,$subject,$message,’David Cochran’);
} # end if the certificate is expired
elsif ($one_day == $expire_date) { # start else if the certificate will expire in 1 day
&sr::send_page($debug,”$url cert expires in 1 day”,’David Cochran’);
$message = “The $url certificate will expire in 1 day”;
print “t$messagen”;
&sr::send_email($debug,$subject,$message,’David Cochran’);
} # end if the certificate will expire in 1 day
elsif ($seven_days == $expire_date) { # start else if the certificate will expire in 7 days
$message = “The $url certificate will expire in 7 days”;
print “t$messagen”;
&sr::send_email($debug,$subject,$message,’David Cochran’);
} # end if the certificate will expire in 7 days
elsif ($fifteen_days == $expire_date) { # start else if the certificate will expire in 15 days
$message = “The $url certificate will expire in 15 days”;
print “t$messagen”;
&sr::send_email($debug,$subject,$message,’David Cochran’);
} # end if the certificate will expire in 15 days
elsif ($thirty_days == $expire_date) { # start else if the certificate will expire in 30 days
$message = “The $url certificate will expire in 30 days”;
print “t$messagen”;
&sr::send_email($debug,$subject,$message,’David Cochran’);
} # end if the certificate will expire in 30 days
} # end for each url

[/code]

URLs are stored in cert.urls with no http:// prefix

[code]
blog.captivereefing.com
www.captivereefing.com
[/code]

You get the idea…

Happy hacking!