check_cert.pl
changeset 0 66c2f2375514
child 1 8c08150c2371
equal deleted inserted replaced
-1:000000000000 0:66c2f2375514
       
     1 #!/usr/bin/perl -w
       
     2 
       
     3 use strict;
       
     4 use warnings;
       
     5 use File::Basename;
       
     6 use Getopt::Long;
       
     7 use Date::Manip;
       
     8 use IPC::Open2;
       
     9 use lib "/usr/lib/nagios/plugins";
       
    10 use utils qw (%ERRORS &print_revision &support);
       
    11 
       
    12 sub print_help();
       
    13 sub print_usage();
       
    14 
       
    15 my $ME = basename $0;
       
    16 my ($opt_w, $opt_c, $opt_V, $opt_h, $opt_b, @opt_certfiles);
       
    17 my ($w_time, $c_time, $result, $message, %certs);
       
    18 my (@critical, @warning);
       
    19 
       
    20 $opt_w = "1month";
       
    21 $opt_c = "1week";
       
    22 $opt_b = "/usr/bin/openssl";
       
    23 
       
    24 Getopt::Long::Configure('bundling');
       
    25 GetOptions(
       
    26     "V"   => \$opt_V, "version"    => \$opt_V,
       
    27     "h"   => \$opt_h, "help"       => \$opt_h,
       
    28     "b=s" => \$opt_b, "binary"     => \$opt_b,
       
    29     "w=s" => \$opt_w, "warning=s"  => \$opt_w,
       
    30     "c=s" => \$opt_c, "critical=s" => \$opt_c,
       
    31     "f=s" => \@opt_certfiles, "certfile=s" => \@opt_certfiles);
       
    32 
       
    33 if ($opt_V) {
       
    34     print_revision($ME, "0.1");
       
    35     exit $ERRORS{"OK"};
       
    36 }
       
    37 
       
    38 if ($opt_h) {
       
    39     print_help();
       
    40     exit $ERRORS{"OK"};
       
    41 }
       
    42 
       
    43 # check openssl binary
       
    44 unless (-x $opt_b) {
       
    45     print "CERT CRITICAL: OpenSSL not found or not executable - $opt_b\n";
       
    46     exit $ERRORS{"CRITICAL"};
       
    47 }
       
    48 
       
    49 unless(@opt_certfiles) {
       
    50     print "CERT WARNING: Not defined any certificate files\n";
       
    51     exit $ERRORS{"WARNING"};
       
    52 }
       
    53 
       
    54 @opt_certfiles = split(/,/, join(',', @opt_certfiles));
       
    55 
       
    56 # extract certificate data
       
    57 foreach my $file (@opt_certfiles) {
       
    58     unless (-r $file) {
       
    59 	print "CERT CRITICAL: $file - not exists or not read permission is granted\n";
       
    60 	exit $ERRORS{"CRITICAL"};
       
    61     }
       
    62     my @cmd_x509 = ($opt_b, "x509", "-in", $file, "-noout", "-subject", "-enddate");
       
    63     my @cmd_pkcs12 = ($opt_b, "pkcs12", "-in", $file, "-clcerts", "-nokeys", "-nomacver", "-passin", "pass:");
       
    64     my @cmd_pipe = ($opt_b, "x509", "-noout", "-subject", "-enddate");
       
    65     my ($temp, $cn, $enddate, $rc);
       
    66     open(CERT, "-|") or do {
       
    67 	open(STDERR, ">&STDOUT");
       
    68 	exec(@cmd_x509);
       
    69     };
       
    70 
       
    71     # check x509 certificates
       
    72     while(<CERT>) {
       
    73 	/unable to load certificate/ and $rc = 1 and last;
       
    74 	/^subject=\s.*CN=(.*)\s+$/ and $cn = $1;
       
    75 	/^notAfter=(.*)\s+$/ and $enddate = $1;
       
    76     }
       
    77     close(CERT);
       
    78 
       
    79     # check pkcs12 certificates
       
    80     if ($rc) {
       
    81 	open(PKCS12, "@cmd_pkcs12 |");
       
    82 
       
    83 	while(<PKCS12>) {
       
    84 	    $temp .= $_;
       
    85 	}
       
    86 	close(PKCS12);
       
    87 
       
    88 	local (*READ, *WRITE);
       
    89 	open2(\*READ, \*WRITE,  @cmd_pipe) or die "Can't fork: $!\n";
       
    90 	print WRITE $temp;
       
    91 	close(WRITE);
       
    92 
       
    93 	while(<READ>) {
       
    94 	    /unable to load certificate/ and print "CERT CRITICAL: unable to load certificate\n" and exit $ERRORS{"CRITICAL"};
       
    95 	    /^subject=\s.*CN=(.*)\s+$/ and $cn = $1;
       
    96 	    /^notAfter=(.*)\s+$/ and $enddate = $1;
       
    97 	}
       
    98 	close(READ);
       
    99     }
       
   100     # fill the hash
       
   101     push ( @{$certs{$file}}, ($cn, $enddate) );
       
   102 }
       
   103 
       
   104 # calculate the time
       
   105 $w_time = DateCalc("today", "+ $opt_w");
       
   106 $c_time = DateCalc("today", "+ $opt_c");
       
   107 
       
   108 # check expire date
       
   109 foreach (sort keys %certs) {
       
   110     my $enddate;
       
   111     if (@{$certs{$_}}[1] =~ /(\w+\s+\d+\s+\d+:\d+:\d+\s+\d+)/) { $enddate = $1; }
       
   112     $enddate = ParseDate($enddate);
       
   113     unless ($enddate) {
       
   114 	print "CERT CRITICAL: Can't parse enddate\n";
       
   115 	exit $ERRORS{"CRITICAL"};
       
   116     }
       
   117 
       
   118     &Date_Cmp($enddate, $w_time) > 0 and push (@{$certs{$_}}, "OK"), next;
       
   119     &Date_Cmp($enddate, $c_time) > 0 and push (@{$certs{$_}}, "WARNING"), next;
       
   120     push (@{$certs{$_}}, "CRITICAL");
       
   121 }
       
   122 
       
   123 # looking for stats
       
   124 foreach (sort keys %certs) {
       
   125     if (@{$certs{$_}}[2] eq "WARNING") {
       
   126 	push (@warning, "file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1]");
       
   127     } elsif (@{$certs{$_}}[2] eq "CRITICAL") {
       
   128 	push (@critical, "file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1]");
       
   129     }
       
   130 }
       
   131 
       
   132 # return the state
       
   133 if (@critical) {
       
   134     print "CERT CRITICAL: @critical\n";
       
   135     exit $ERRORS{"CRITICAL"};
       
   136 } elsif (@warning) {
       
   137     print "CERT WARNING: @warning\n";
       
   138     exit $ERRORS{"WARNING"};
       
   139 } else {
       
   140     print "CERT OK: all certificates in limit\n";
       
   141     exit $ERRORS{"OK"};
       
   142 }
       
   143 
       
   144 sub print_usage() {
       
   145     print "Usage:\n";
       
   146     print "  $ME [-b <binary>] [-w <time>] [-c <time>] [-f <file,file,file,...>]\n";
       
   147     print "  $ME [-h | --help]\n";
       
   148     print "  $ME [-V | --version]\n";
       
   149 }
       
   150 
       
   151 sub print_help() {
       
   152     print_revision($ME, "0.1");
       
   153     print "Copyright (c) 2008 Christian Arnold\n\n";
       
   154     print "This plugin checks the expire date for openssl certificates.\n\n";
       
   155     print_usage();
       
   156     print "\n";
       
   157     print "  -b, --binary <binary>\n";
       
   158     print "     Path of openssl binary (default: /usr/bin/openssl)\n";
       
   159     print "  -w, --warning <time>\n";
       
   160     print "     Certificat should not be more than this time older (default: 1month)\n";
       
   161     print "     For time can be used year, month, day, hour, minute, second and weeks.\n";
       
   162     print "  -c, --critical <time>\n";
       
   163     print "     Certificat should not be more than this time older (default: 1week)\n";
       
   164     print "     For time can be used year, month, day, hour, minute, second and weeks.\n";
       
   165     print "  -f, --certfile <file,file,file, ...>\n";
       
   166     print "     Absolute path of x509 or pkcs12 openssl certificate files, use comma-separated lists for multiple files.\n";
       
   167     print "  -h, --help\n";
       
   168     print "     Print detailed help screen\n";
       
   169     print "  -V, --version\n";
       
   170     print "     Print version information\n";
       
   171     print "\n";
       
   172     support();
       
   173 }
       
   174 
       
   175 
       
   176 exit;
       
   177 
       
   178 # vim:sts=4 sw=4 aw ai sm: