From 2928b5fdbe64ce58b725308f2a443290ef4ecbce Mon Sep 17 00:00:00 2001 From: Daniel Berteaud Date: Wed, 19 Feb 2014 09:27:07 +0100 Subject: [PATCH] Add scripts to monitor PHPki certificates --- createlinks | 3 +- .../zabbix_agentd.conf.d/phpki_certs.conf/10All | 23 ++++++++++ root/var/lib/zabbix/bin/check_certs_sudo | 33 +++++++++++++++ root/var/lib/zabbix/bin/disco_certs_sudo | 49 ++++++++++++++++++++++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 root/etc/e-smith/templates/etc/zabbix/zabbix_agentd.conf.d/phpki_certs.conf/10All create mode 100644 root/var/lib/zabbix/bin/check_certs_sudo create mode 100644 root/var/lib/zabbix/bin/disco_certs_sudo diff --git a/createlinks b/createlinks index c91aeb1..573ab65 100644 --- a/createlinks +++ b/createlinks @@ -6,7 +6,8 @@ use esmith::Build::CreateLinks qw(:all); foreach my $conf (qw!zabbix_agent.conf zabbix_agentd.conf zabbix_agentd.conf.d/asterisk.conf zabbix_agentd.conf.d/deprecated_cpunum.conf zabbix_agentd.conf.d/deprecated_memory.conf zabbix_agentd.conf.d/deprecated_netstat.conf zabbix_agentd.conf.d/deprecated_swap.conf - zabbix_agentd.conf.d/extip.conf zabbix_agentd.conf.d/mail.conf zabbix_agentd.conf.d/mysql.conf!){ + zabbix_agentd.conf.d/extip.conf zabbix_agentd.conf.d/mail.conf zabbix_agentd.conf.d/mysql.conf + zabbix_agentd.conf.d/phpki_certs.conf!){ templates2events("/etc/zabbix/$conf", qw(zabbix-agent-update bootstrap-console-save)); } templates2events("/etc/sudoers", "zabbix-agent-update"); diff --git a/root/etc/e-smith/templates/etc/zabbix/zabbix_agentd.conf.d/phpki_certs.conf/10All b/root/etc/e-smith/templates/etc/zabbix/zabbix_agentd.conf.d/phpki_certs.conf/10All new file mode 100644 index 0000000..4e8954b --- /dev/null +++ b/root/etc/e-smith/templates/etc/zabbix/zabbix_agentd.conf.d/phpki_certs.conf/10All @@ -0,0 +1,23 @@ +{ + +if (-e '/opt/phpki/phpki-store/CA/index.txt'){ + $OUT .=<<'EOF'; + +# Discovery of certificates and their status +# Key: pki.certs.discovery +# Macro: +# - {#CRTCN} : contains the common name +# - {#CRTSERIAL} : the serial number +# - {#CRTSTATUS} : the status, as a string (valid, revoked, expired) +# Available arguments: +# --index : path to the index file +# --path : directory where certificatres are stored, certificates should be named $serial.pem (in PEM format) + +UserParameter=pki.certs.discovery,/usr/bin/sudo /var/lib/zabbix/bin/disco_certs_sudo --index=/opt/phpki/phpki-store/CA/index.txt --path=/opt/phpki/phpki-store/CA/newcerts/ +UserParameter=pki.certs[*],/usr/bin/sudo /var/lib/zabbix/bin/check_certs_sudo --what=$1 --cert=$2 + +EOF +} +$OUT .= ''; + +} diff --git a/root/var/lib/zabbix/bin/check_certs_sudo b/root/var/lib/zabbix/bin/check_certs_sudo new file mode 100644 index 0000000..5ae3641 --- /dev/null +++ b/root/var/lib/zabbix/bin/check_certs_sudo @@ -0,0 +1,33 @@ +#!/usr/bin/perl -w + +# Check a PEM certificate +# --what: what to monitor. Only expire is supported for now, and returns the number of day before expiration +# --cert: the path to the certificate you want to check + +use strict; +use warnings; +use Crypt::OpenSSL::X509; +use Date::Parse; +use Getopt::Long; + +my $what = 'expire'; +my $cert = ''; + +GetOptions( + "cert=s" => \$cert, + "what=s" => \$what +); + +die "Usage: $0 --what=status --cert=/path/to/pem/certificate\n" unless + (-f $cert); + +$cert = Crypt::OpenSSL::X509->new_from_file( "$cert" ); +my $expire_in = int ((str2time($cert->notAfter())-time())/(3600*24)); + +if ($what eq 'expire'){ + print $expire_in; +} +else{ + die "Only expire is supported for now"; +} + diff --git a/root/var/lib/zabbix/bin/disco_certs_sudo b/root/var/lib/zabbix/bin/disco_certs_sudo new file mode 100644 index 0000000..88c1ecf --- /dev/null +++ b/root/var/lib/zabbix/bin/disco_certs_sudo @@ -0,0 +1,49 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use Crypt::OpenSSL::X509; +use Date::Parse; +use Getopt::Long; +use JSON; + +my $index = '/opt/phpki/phpki-store/CA/index.txt'; +my $path = '/opt/phpki/phpki-store/CA/newcerts'; + +GetOptions( + "index=s" => \$index, + "path=s" => \$path +); + +open INDEX, "$index" or die "Couldn't open $index\n"; + +my $json; + +foreach my $l (){ + next unless $l =~ m/^([VR])\t\d+Z\t(\d+Z)?\t(\w+)\tunknown\t.*/; + my $status = $1; + my $serial = $3; + my $cert = Crypt::OpenSSL::X509->new_from_file( "$path/$serial.pem" ); + + my $expire_in = int ((str2time($cert->notAfter())-time())/(3600*24)); + if ($status eq 'V'){ + $status = 'valid'; + } + elsif ($expire_in lt 0){ + $status = 'expired'; + } + else{ + $status = 'revoked'; + } + my $subject = $cert->subject; + $subject =~ m/.*\sCN=(.*),/; + my $cn = $1; + + push @{$json->{data}}, { + "{#CRTCN}" => $cn, + "{#CRTSERIAL}" => $serial, + "{#CRTSTATUS}" => $status, + }; +} +close INDEX; +print to_json($json);