異常系を考えてないので、想定外の時はいろいろまずいかも。
自動更新が失敗したら?!
多くのレンタルサーバーでは、無料SSLサーバー証明書 Let's Encryptは自動更新してくれて、失敗した時はメールで通知がくると思います。リトライとかも数回はやってくれるところが
多いので心配はいらないですが、自身でも検出出来たらよいかなぁと思ってました。PHPでSSL証明書の有効期限を取得できると知ったので、ちょっとやってみました。
参考にしたもの
・How to get SSL certificate info with CURL in PHP? - Stack Overflow
・PHP で外部サーバーの SSL サーバー証明書の有効期限を取得する - Qiita
1つ目を参考にしました。2つ目は情報源です。
方法その1:お勧め
<?php
function get_ssl_expire_date($domain){
$stream_context = stream_context_create(array(
'ssl' => array('capture_peer_cert' => true,
'verify_peer' => false,
'verify_peer_name' => false)
));
$resource = stream_socket_client(
'ssl://' . $domain . ':443',
$errno,
$errstr,
30,
STREAM_CLIENT_CONNECT,
$stream_context
);
$cont = stream_context_get_params($resource);
$parsed = openssl_x509_parse($cont['options']['ssl']['peer_certificate']);
$date = null;
if(strpos($parsed['subject']['CN'], $domain) !== false){
$date = date('Y/m/d', $parsed['validTo_time_t']);
}
return $date;
}
//----------
// MAIN
//----------
$domain = $_SERVER['HTTP_HOST'];
$date = get_ssl_expire_date($domain);
echo $date;
$domain = $_SERVER['HTTP_HOST'];で、このスクリプトが動作しているドメイン(ホスト名)のSSLの期限を調べます。日付は、GMT/グリニッジ標準時です。
バリューサーバー、スターサーバーで動作確認しました。
補足
・PHP: openssl_x509_parse - Manual
方法その2:curl版
<?php
function get_ssl_expire_date_curl($domain){
$fp = tmpfile();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://".$domain);
curl_setopt($ch, CURLOPT_STDERR, $fp);
curl_setopt($ch, CURLOPT_CERTINFO, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); //文字列に出力
$result = curl_exec($ch);
fseek($fp, 0);
$output = fread($fp, 8192);
//echo $output;
fclose($fp);
//----------
$pattern="/expire date:(.*?)\n/";
$subject=$output;
preg_match($pattern,$subject, $matches);
//print_r($matches);
$date = new DateTime($matches[1]);
//echo $date->format('U');
//echo $date->format('Y-m-d H:i:s');
return $date->format('Y-m-d');
}
//----------
// MAIN
//----------
$domain = $_SERVER['HTTP_HOST'];
$date = get_ssl_expire_date_curl($domain);
echo $date;
無料系のサーバーでは、stream_socket_clientあたりも制限されていて動作しないことが多いので、curlを使ったバージョンです。
スタードメイン付属の無料サーバーではうまく取得できています。バリューサーバーでも動作しました。
補足
CURLOPT_CERTINFO TRUE を設定すると、セキュアな転送時に SSL 証明書の情報を STDERR に出力します。
PHP: curl_setopt - Manual
これを利用して、SSLの有効期限を取得しています。
curl_setopt($ch, CURLOPT_STDERR, $fp);で、標準エラー出力を作業ファイル($fp)に出力しています。
出力内容を、pattern="/expire date:(.*?)\n/"; のパターンで正規表現で取得してますが、こんな決め打ちで良いのかは不明です。
コメントを残す