指定したURLのSSL証明書と中間証明書の有効期限を監視するNagiosプラグインをPerlで自作してみました。
SSL証明書の有効期限を取得して監視、というのはいろいろ既にあったのですが、その中間証明書の有効期限をとなると見つけることができませんでしたので作ってみたというわけです。
有効期限までの残りの日数が指定した日数以内になるとアラートを返すようにしています。
使用しているPerlモジュールは HTTP::Date と POSIX です。
use HTTP::Date; use POSIX;
仕組みですが、監視サーバにインストールされているopensslコマンドを利用して証明書を取得し、それを利用して有効期限を取得するようにしています。
# opensslコマンドで証明書を取得 @certfile = `openssl s_client -connect $domain:443 -showcerts < /dev/null 2>/dev/null`;
プラグインに渡す引数は下記の通りです。
my $domain = $ARGV[0]; my $certkbn = $ARGV[1]; # チェック対象の証明書 ( 1->サーバ証明書 / 2->中間証明書 ) my $warning = $ARGV[2]; my $critical = $ARGV[3];
実際のソースは下記のようになってます。
#!/usr/bin/perl ######################################################################## # Nagios Plugin for SSL Cert Kigen. ## ### Argument Domain / CertKBN / Warning / Critical #### Create 2014.8.29 ##### ####################################################################### use HTTP::Date; use POSIX; # 引数 if( @ARGV != 4 ){ print "Argument is not enough.(".@ARGV.")"; exit(3); } my $domain = $ARGV[0]; my $certkbn = $ARGV[1]; # チェック対象の証明書 ( 1->サーバ証明書 / 2->中間証明書 ) my $warning = $ARGV[2]; my $critical = $ARGV[3]; # フラグなどなど $flgCert = "none"; $i = 0; # opensslコマンドで証明書を取得 @certfile = `openssl s_client -connect $domain:443 -showcerts < /dev/null 2>/dev/null`; # 取得した証明書からサーバ証明書と中間証明書を抽出 foreach my $certline (@certfile) { # 改行コードを除去 $certline =~ s/\n//; # 証明書コードの始まりと終わりを検出 if( $certline eq "-----BEGIN CERTIFICATE-----" ){ $flgCert = "in" }elsif( $certline eq "-----END CERTIFICATE-----" ){ $flgCert = "out" } # 証明書部分のみ配列に格納 (証明書と中間証明書の2種類あるのでそれぞれを格納) if( $flgCert eq "in" ){ $cert[$i] = $cert[$i].$certline."\n"; }elsif( $flgCert eq "out" ){ $cert[$i] = $cert[$i].$certline."\n"; $flgCert = "none"; $i++; } } # サーバ証明書の有効期限情報を取得して何日後かを算出 $certdetail = `echo "$cert[0]" | openssl x509 -text | sed -e "/Not After/{s/^.* : //;p};d"`; $certdetail =~ s/\s+/ /g; @temp = split( /\ /, $certdetail ); $time1 = str2time( "$temp[1] $temp[0] $temp[3] $temp[2] $temp[4]" ); $time2 = time(); $diffdate_cert = ceil( ($time1-$time2) / 86400 ); # 中間証明書の有効期限情報を取得して何日後かを算出 $chaindetail = `echo "$cert[1]" | openssl x509 -text | sed -e "/Not After/{s/^.* : //;p};d"`; $chaindetail =~ s/\s+/ /g; @temp = split( /\ /, $chaindetail ); $time1 = str2time( "$temp[1] $temp[0] $temp[3] $temp[2] $temp[4]" ); $time2 = time(); $diffdate_chain = ceil( ($time1-$time2) / 86400 ); # 閾値に応じて結果を出力 if( $certkbn == 1 ){ $diffdate = $diffdate_cert; }else{ $diffdate = $diffdate_chain; } print "The ".$diffdate."th remaining | Days=".$diffdate; if( $diffdate <= $critical ){ exit(2); }elsif( $diffdate <= $warning ){ exit(1); }else{ exit(0); }
以上です。