Perl (というか openssl コマンド) でリモートのサーバに接続し、SSL 証明書の有効期限を取得する方法。
openssl コマンドでリモートのサーバの SSL を証明書を取得するには、s_client を使う。
$ openssl s_client -connect ${host}:${port} -showcerts
取得した証明書から有効期限を取得するには、証明書を openssl x509 にパイプで渡せば良い。
$ ... | openssl x509 -dates -noout
例えば www.google.co.jp:443 のものを取得すると、次のように表示される。
notBefore=Apr 24 12:36:07 2013 GMT
notAfter=Dec 30 00:00:00 2013 GMT
notAfter の値が有効期限なので、これをパースして求める日時フォーマットに変換してやる。今回は Perl の DateTime::Format::Strptime モジュールを使用する。
#!/usr/bin/env perl
use strict;
use warnings;
use DateTime::Format::Strptime;
print &get_ssl_expire($ARGV[0]) . "\n";
sub get_ssl_expire {
my $host = shift || "";
my $port = shift || 443;
return "" if ($host !~ /^[a-z0-9\.\-]+$/i);
return "" if ($port !~ /^[0-9]+$/);
my $date;
my $timeout = 10;
my $cmd = "echo | openssl s_client -connect $host:$port -showcerts 2> /dev/null";
$cmd .= " | openssl x509 -dates -noout 2> /dev/null";
$cmd .= " | grep notAfter | awk -F= '{print \$2}'";
eval {
local $SIG{ALRM} = sub {die};
alarm($timeout);
$date = qx/$cmd/;
chomp $date;
alarm(0);
};
return "" if ($@);
return "" if ($date !~ /^([A-Z][a-z]{2})\s+([0-9]{1,2})\s+[0-9:]{8}\s+([0-9]{4})\s+[A-Z]{3}$/);
my $strp = DateTime::Format::Strptime->new(pattern => "%b %d %T %Y %Z");
return $strp->parse_datetime($date)->ymd;
}
実行すると次のようになる。
$ ./get_ssl_expire.pl www.google.co.jp
2013-12-30
別の日時フォーマットで取り出したい場合は、ymd メソッドを適当なものに変更すれば良い。
openssl コマンドを使わずに、証明書の取得も Perl で実現したいなら、Net::SSLeay モジュールを使用するという手もある。
コメント