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.
-
#! /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 $url\n";
-
$cmd = "echo \"\" | openssl s_client -connect $url:443> $path/certificate";
-
print "\n\n $cmd\n\n" if ($debug);
-
system ($cmd) if ($execute);
-
-
$cmd = "openssl x509 -in $path/certificate -noout -enddate> $path/outdate";
-
print " $cmd\n\n" if ($debug);
-
system ($cmd)> $result if ($execute);
-
-
open (OUTDATE, "/pshome/tmp/outdate") || die "couldn't open the file!";
-
$enddate = <outdate>;
-
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$message\n";
-
&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$message\n";
-
&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$message\n";
-
&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$message\n";
-
&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$message\n";
-
&sr::send_email($debug,$subject,$message,'David Cochran');
-
} # end if the certificate will expire in 30 days
-
} # end for each url
URLs are stored in cert.urls with no http:// prefix
-
blog.captivereefing.com
-
www.captivereefing.com
You get the idea...
Happy hacking!
February 13th, 2008 at 3:19 pm
Dave,
This is perfect, just what I was looking for. I got it “mostly” working in my target environment, but am going to ask a possibly naive question (I’m a security guy, not a programmer!)… what’s the “/pshome/psmgr/…” stuff?? I can’t find it in the distribution(s) I’m using, nor references on the web.
Thank!
Rob
February 21st, 2008 at 11:07 am
Hi Rob,
Sorry for the delay in responding, life gets in the way…..The /pshome/psmgr is a just another directory structure used in conjunction with /home. I use it to donate the particular application that group of “home” directories supports… In this case pshome is short for PeopleSoft home… pretty doubtful you’d find any other references out there to match it… just my own way to try to keep order in such a chaotic environment.
Did you get the rest of the script sorted out? Think the only other things I didn’t post (yet?) where the subroutines I use for mail.sr etc… figured most folks would already have their own.
Dave