#!/usr/bin/perl -w
# $Id: check_certexp,v 1.1 2006/03/10 18:25:35 holger Exp $ # # check certificate expiry # # Copyright (c) 2006 Holger Weiss <Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра.
> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # #Changed by Kuleshov Sergey
use strict; #use Socket6; Socket6->import(qw(inet_pton getaddrinfo)); use IO::Socket::INET6; #use Socket; #use IO::Socket::INET;
use Getopt::Long; use Net::SSLeay; use Date::Manip;
use lib "/usr/local/libexec/nagios"; use utils qw(%ERRORS $TIMEOUT &print_revision &support); use vars qw($PROGNAME $PORT $CRIT $opt_H $opt_V $opt_c $opt_h $opt_p $opt_t $opt_v $opt_w);
sub days_until_expiry ($$); sub expiry_date ($$); sub die_crit ($); sub die_warn ($); sub die_unknown ($); sub print_usage (); sub print_help (); my ($ssl_port, $warning, $critical, $timeout, $days);
$PROGNAME = "check_certexp"; $PORT = 443; $CRIT = 28; $SIG{'ALRM'} = sub { die_unknown("Timeout"); }; $ENV{'PATH'} = ''; $ENV{'ENV'} = ''; $ENV{'TZ'} = 'CET';
Getopt::Long::Configure("bundling"); if (!GetOptions("V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, # actually, we won't produce any verbose output "v+" => \$opt_v, "verbose+" => \$opt_v, "H=s" => \$opt_H, "hostname=s" => \$opt_H, "c=i" => \$opt_c, "critical=i" => \$opt_c, "p=i" => \$opt_p, "port=i" => \$opt_p, "t=i" => \$opt_t, "timeout=i" => \$opt_t, "w=i" => \$opt_w, "warning=i" => \$opt_w)) { print "CERTEXP UNKNOWN - Error processing command line options\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; } if ($opt_V) { print_revision($PROGNAME,'$Revision: 1.1 $ '); exit $ERRORS{'OK'}; } if ($opt_h) { print_help(); exit $ERRORS{'OK'}; } unless ($opt_H) { print "CERTEXP UNKNOWN - No target host specified\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; }
if ( ($opt_H=~/((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)/) or ($opt_H=~/((^|:)([0-9a-fA-F]{0,4})){1,8}$/) ) { print "CERTEXP UNKNOWN - No target host specified\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; }
$critical = $opt_c ? $opt_c : $CRIT; $warning = $opt_w ? $opt_w : $critical; if ($warning < $critical) { print "CERTEXP UNKNOWN - Warning smaller than critical threshold\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; } $ssl_port = $opt_p ? $opt_p : $PORT; $timeout = $opt_t ? $opt_t : $TIMEOUT; alarm($timeout);
my @crit_ip;my @warn_ip;my $ret = 0; my @ip4 = `/usr/bin/host $opt_H | /usr/bin/grep -v IPv6 | /usr/bin/awk '{print \$4}'`; chomp @ip4; my @ip6 = `/usr/bin/host $opt_H | /usr/bin/grep IPv6 | /usr/bin/awk '{print \$5}'`; chomp @ip6;
my @ip = (@ip4, @ip6); my $ipv;
foreach (@ip) { $opt_H = $_; if ($opt_H =~ /((^|:)([0-9a-fA-F]{0,4})){1,8}$/) {$ipv = 6} else {$ipv = 4} $days = days_until_expiry($opt_H, $ssl_port); $days =~ s/^-// && die_crit("certificate expired $days days ago") if $days < 0; $ret = die_crit("certificate expires in $days days for $opt_H;") if $days < $critical; if ($ret == 2) {push @crit_ip, $opt_H;next} $ret = die_warn("certificate expires in $days days for $opt_H;") if $days < $warning; if ($ret == 1) {push @warn_ip, $opt_H;next} print "OK for $opt_H - cert expires in $days days;"; #exit $ERRORS{'OK'}; }
exit 1 if @warn_ip; exit 2 if @crit_ip;
sub days_until_expiry ($$) { my ($host, $port) = @_;
(my $exp = expiry_date($host, $port)) =~ s/ GMT//; int((&UnixDate(&ParseDate($exp),"%s") - time) / 86400); }
sub expiry_date ($$) { my ($host, $port) = @_; my ($buffer, $iaddr, $paddr, $ctx, $ssl, $crt, $end, $str);
# connect socket $iaddr = $ipv eq '4' ? inet_pton(AF_INET,$host) : inet_pton(AF_INET6,$host) || die_unknown("Invalid hostname/address: $host"); $paddr = $ipv == 4 ? sockaddr_in($port, $iaddr) : sockaddr_in6($port, $iaddr); if ($ipv == 4) {socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die_unknown("Socket error: $!")} else {socket(SOCK, PF_INET6, SOCK_STREAM, getprotobyname('tcp')) || die_unknown("Socket error: $!")} connect(SOCK, $paddr) || die_unknown("Error connecting to $host: $!");
# initialize SSL Net::SSLeay::load_error_strings(); Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::randomize();
$ctx = Net::SSLeay::CTX_new(); $ssl = Net::SSLeay::new($ctx);
Net::SSLeay::set_fd($ssl, fileno(SOCK)); Net::SSLeay::connect($ssl) || die_unknown(Net::SSLeay::print_errs());
# get certificate $crt = Net::SSLeay::get_peer_certificate($ssl) || die_unknown(Net::SSLeay::print_errs());
# get expiry date (string) $end = Net::SSLeay::X509_get_notAfter($crt); $str = Net::SSLeay::P_ASN1_UTCTIME_put2string($end);
# cleanup Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); close SOCK;
$str; }
sub die_unknown ($) { printf "CERTEXP UNKNOWN - %s\n", shift; exit $ERRORS{'UNKNOWN'}; }
sub die_warn ($) { printf "CERTEXP WARNING - %s", shift; # exit $ERRORS{'WARNING'}; return 1; }
sub die_crit ($) { printf "CERTEXP CRITICAL - %s", shift; # exit $ERRORS{'CRITICAL'}; return 2; }
sub print_usage () { print "Usage: $PROGNAME -H host [-p port] [-w warn] [-c crit]" . "[-t timeout] [-v]\n"; }
sub print_help () { print_revision($PROGNAME, '$Revision: 1.1 $'); print "Copyright (c) 2006 Holger Weiss\n\n"; print "Check certificate expiry date.\n\n"; print_usage(); print <<EOF;
-H, --hostname=HOSTNAME Host name (only) -p, --port=INTEGER Port number (default: $PORT) -w, --warning=INTEGER WARNING if less than specified number of days until expiry (default: $CRIT) -c, --critical=INTEGER CRITICAL if less than specified number of days until expiry (default: $CRIT) -t, --timeout=INTEGER Seconds before connection times out (default: $TIMEOUT) -v, --verbose Show details for command-line debugging (Nagios may truncate output)
EOF support(); }
|