]> git.etc.gen.nz Git - spong.git/commitdiff
Module to check expiration date of SSL certificate for $HOST origin
authorAlan Premselaar <alien@12inch.com>
Thu, 2 Mar 2006 05:38:09 +0000 (05:38 +0000)
committerAlan Premselaar <alien@12inch.com>
Thu, 2 Mar 2006 05:38:09 +0000 (05:38 +0000)
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.

src/lib/Spong/Network/plugins/check_ssl [new file with mode: 0755]

diff --git a/src/lib/Spong/Network/plugins/check_ssl b/src/lib/Spong/Network/plugins/check_ssl
new file mode 100755 (executable)
index 0000000..5cf5a4c
--- /dev/null
@@ -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 <alien@12inch.com>
+#
+# $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 <TIMEOUT> and <HOSTNAME>
+#                                      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 <TIMEOUT>  https://<HOSTNAME> 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/<HOSTNAME>/$host/g;
+               $curl =~ s/<TIMEOUT>/$host_timeout/g;
+
+               if (! open(CURL, " $curl |")) {
+                       error("Cannot pipe to $curl");
+                       return(0);
+               }
+
+               while ($line = <CURL>) {
+                       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;