From: Alan Premselaar Date: Thu, 2 Mar 2006 05:38:09 +0000 (+0000) Subject: Module to check expiration date of SSL certificate for $HOST X-Git-Url: http://git.etc.gen.nz/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Forigin;p=spong.git Module to check expiration date of SSL certificate for $HOST currently dependant on 'curl' being installed. at some point I'd like to re-write it to do connections directly, but haven't figured out yet how to get more than just the certificate issuer and name. --- diff --git a/src/lib/Spong/Network/plugins/check_ssl b/src/lib/Spong/Network/plugins/check_ssl new file mode 100755 index 0000000..5cf5a4c --- /dev/null +++ b/src/lib/Spong/Network/plugins/check_ssl @@ -0,0 +1,150 @@ +# SPONG Network plugin module +# +# This plugin will use curl in verbose mode to connect to an SSL server and extract the +# SSL certificate expiry date and send a warning notification based on the approprate grace +# period settings. +# +# Author: Alan Premselaar +# +# $Id: check_ssl,v 1.1 2006/03/02 05:38:09 apremselaar Exp $ +# +# Synopsis: +# +# The following variables can be set in the spong.conf file: +# +# $SSLTIMEOUT - set the timeout in seconds for curl to connect to the URL +# this can also be set per host with ssl_timeout => seconds directive +# $SSLRETRY - set the number of retries, in case of timeout +# $SSLGRACE - set the number of seconds before expiry to start warning +# ($expire - time()) <= $SSLGRACE > $SSLGRACE /2 = yellow +# ($expire - time()) <= $SSLGRACE /2 = red +# $SSLCURLCMD - the command to use to call curl (installation dependant) +# this command should have the tags and +# in it as appropriate. Please see the code for an example. +# some newer versions of curl require the -k option to connect +# to SSL servers w/o requiring a cert. +# +# Register function with the plugin registry +$PLUGINS{'ssl'} = \&check_ssl; + +sub check_ssl { + + use constant SECOND => 1; + use constant MINUTE => SECOND * 60; + use constant HOUR => MINUTE * 60; + use constant DAY => HOUR * 24; + use constant WEEK => DAY * 7; + use constant MONTH => WEEK * 4; + + use constant TRUE => 1; + use constant FALSE => 0; + + use POSIX; + use Time::Local; + + our $_TIMEOUT = $SSLTIMEOUT || 5; + our $_TO_RETRY = $SSLRETRY || 5; + + our $_CURL_CMD = "/usr/bin/curl -v -m https:// 2>&1"; + our $_EXPIRE_MATCH = '^\*\s+expire date: (\d{4})-(\d{1,2})-(\d{1,2})\s(\d{1,2}):(\d{1,2}):(\d{1,2})\s+([A-Z]{3})'; + our $_GRACE = $SSLGRACE || MONTH * 2; # 2 month grace period: start warning $_GRACE time before date of expiry + + our $retry = 0; + + sub open_https { + my $host = shift; + + my $curl = $SSLCURLCMD || $_CURL_CMD; + my $host_timeout = $HOSTS{$host}->{ssl_timeout} || $_TIMEOUT; + + + info(">> [$host] retry = $retry, max = $_TO_RETRY , host_timeout = $host_timeout"); + my ($year,$month,$day,$hour,$min,$sec,$tz,$timeout); + + $curl =~ s//$host/g; + $curl =~ s//$host_timeout/g; + + if (! open(CURL, " $curl |")) { + error("Cannot pipe to $curl"); + return(0); + } + + while ($line = ) { + if ($line =~ /timeout/i || $line =~ /timed out/i) { + if ($retry >= $_TO_RETRY) { + info(" [$host] retry = $retry, max = $_TO_RETRY , host_timeout = $host_timeout"); + return(0,0,0,1,0,1970,"GMT","timeout"); + } + $retry++; + debug(" [$host] TIMEOUT: recursing ($retry)"); +# info(" [$host] TIMEOUT: recursing ($retry)"); + ($sec,$min,$hour,$day,$month,$year,$tz,$timeout) = open_https($host); + return($sec,$min,$hour,$day,$month,$year,$tz,$timeout); + } + next unless ($line =~ /$_EXPIRE_MATCH/); + ($year,$month,$day,$hour,$min,$sec,$tz) = ($1,$2,$3,$4,$5,$6,$7); + last; + } + + close(CURL); +# info("[$host] $hour:$min:$sec $month/$day/$year"); + $month -= 1 if ($month > 0); + return($sec,$min,$hour,$day,$month,$year,$tz,$timeout); + } + + sub will_expire_soon { + my $expire = shift; + my $currtime = shift; + my $grace = shift; + + my $diff = ($expire - $currtime); + + if ( $diff <= $grace ) { + return(TRUE); + } else { + return(FALSE); + } + } + + my ($host) = @_; + my ($color,$summary) = ("green","OK"); + + my @retval = open_https($host); + + if ($retval[7] eq "timeout") { + $color = "yellow"; + $summary = "Connection timeout: no more retries"; + + debug("ssl - $host - $color, $summary"); + return($color,$summary); + } + + my $timeg = timegm(@retval); + my $timel = time(); + + my $stimeg = strftime("%m-%d-%Y %H:%M:%S %Z", localtime($timeg)); + my $stimel = strftime("%m-%d-%Y %H:%M:%S %Z", localtime($timel)); + + my $yellow = will_expire_soon($timeg,$timel,$_GRACE); + my $red = will_expire_soon($timeg,$timel,$_GRACE/2); + + if ($yellow) { + $color = "yellow"; + $summary = "SSL certificate will expire on $stimeg"; + + } + + if ($red) { + $color = "red"; + $summary = "WARNING: SSL certificate will expire on $stimeg!"; + } + + if ($color eq "green") { + $summary = "OK - SSL certificate valid until $stimeg"; + } + + debug( "ssl - $host - $color, $summary" ); + return( $color, $summary ); +} + +1;