in reply to Getting an SSL Certificate Expiration Date
That was incredibly helpful. Thank you. This is not my cleanest work and needs better error checking. It does, however, work as expected.
#!/usr/bin/env perl #------------------------------------------------ use strict; use warnings; #------------------------------------------------ # extras my $DEBUG = 1; use LWP::UserAgent; use Time::HiRes qw(gettimeofday tv_interval); use Date::Parse; my $XYMON_SVR = "127.0.0.1"; my $XYMON_PORT = 1984; my $WARN_DAYS = 30; my @MONTH = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); #------------------------------------------------ # output formats # month day, year hh:mm:ss zone my $TIME_FMT = "%s %s, %s %s:%s:%s %s"; # output for http my $HTTPFMT="status %s.%s %s %s %s %s %s %s seconds\n"; # output fro sslcert my $SSLCERTFMT="status %s.%s %s %s Certificate for %s expires in %d days Expiration Date: %s\n"; #------------------------------------------------ # globals ## certificate info my %g_certinfo = (); #------------------------------------------------ # main #------------------------------------------------ sub main { # get the site name my $site = $ARGV[0]; return 1 unless $site; my $resp_line = ""; my $resp_headers = ""; # always start as green my $status_color = "green"; # start the timer my $t0 = [gettimeofday]; #---------------------------------------------- # get site headers if it is reachable # create the agent my $ua = LWP::UserAgent->new ( ssl_opts => {SSL_verify_callback => \&xtract_cert } ); # define teh url my $url = "https://" . $site; # try to connect my $resp = $ua->get($url); # we don't care if the response code is a 200, 300, or 400 but 500 i +s still a # bad thing if ($resp->code >= 500) { $resp_line = $resp->status_line ? $resp->status_line : "Unable to +connect to " . $site; $resp_headers = ""; $status_color = "red"; } else { $resp_line = $resp->protocol . " " . $resp->status_line; $resp_headers = $resp->headers_as_string; chomp($resp_headers); } # calculate Elapsed Time my $et = tv_interval ($t0); # time for status line my $time = localtime(); # send https status to xymon my $httpout = sprintf $HTTPFMT, $site, "http", $status_color, $time, + $url, $resp_line, $resp_headers, $et; send_2_xymon($XYMON_SVR, $XYMON_PORT, $httpout); # convert time from LWP to seconds since epoch my $epoch_xpire = str2time( $g_certinfo{EndDate} ); # if no epoch_xpire then there is a problem. return 1 unless ($epoch_xpire); # convert expiration time to human readable format my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = +localtime($epoch_xpire); $year += 1900; my $tz = $isdst > 0 ? "PDT" : "PST"; my $expire_date = sprintf $TIME_FMT, $MONTH[$mon], $mday, $year, $ho +ur, $min, $sec, $tz; # current time since epoch my $epoch_now = time(); # how much time is left on cert my $remain_sec = $epoch_xpire - $epoch_now; my $remain_day = int($remain_sec / 86400 + 0.5); if ($remain_sec > $WARN_DAYS * 86400) { $status_color = "green"; } elsif ($remain_sec < 0) { $status_color = "red"; } else { $status_color = "yellow"; } my $sslcertout = sprintf $SSLCERTFMT, $site, "sslcert", $status_colo +r, $time, $url, $remain_day, $expire_date; send_2_xymon($XYMON_SVR, $XYMON_PORT, $sslcertout); return 0; } #------------------------------------------------ # extract some certificate information #------------------------------------------------ sub xtract_cert { my ($ok, $ctx_store) = @_; my $cert = Net::SSLeay::X509_STORE_CTX_get_current_cert($ctx_store); $g_certinfo{EndDate} = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSL +eay::X509_get_notAfter($cert)); return $ok; } #------------------------------------------------ # send the data to xymon #------------------------------------------------ sub send_2_xymon { use IO::Socket; my ($server,$port,$output) = @_; if ($DEBUG) { print $output, "\n"; return ""; } # open a socket my $socket = new IO::Socket::INET ( PeerAddr => $server, PeerPort => $port, Proto => 'tcp', ); return "Could not create socket: $!n" unless $socket; # send data over socket print $socket $output; # close socket close($socket); # return empty string on success return ""; } exit main();
|
|---|