概要
PHPで、ウェブサイトのSSL証明書の有効期限をチェックして、有効期限が近いサイトがあれば、Slackに通知したい。
「ツール入れればいいじゃん」という話は、無しでお願いします・・・。お手軽重視!!
しらべた
自分が使うだけのものなので、あんまり時間をかけずにサクッと作りたかった。ので、とりあえずググりました。
参考にさせていただいたのは、以下の2記事。というか、ほとんどそのまま・・・。
実装
サクッと組み合わせたものを、そのまま 恥ずかしげもなく 公開。定数の定義位置が微妙なのは、非エンジニアでもドメイン追加しやすいように、という余計な配慮です。
ssl-watch.php
<?php
/**
* SSL証明書期限切れ通知用プログラム
*/
// ここに、監視対象のドメインを追加(FQDN)
$domain_names = array(
'example.com',
);
// テストしたい場合は1にして手動実行すると、全て通知される。
define('IS_TEST', 0);
// 通知先のチャンネル名。@始まりでDM。
define('SLACK_CHANNEL_NAME', '#ssl_watch');
// Slack Incoming WebHooksのURL
define('SLACK_WEBHOOK_URL', 'https://hooks.slack.com/services/hogehogehogehogehogehoge');
$warning_messages = array();
foreach($domain_names as $domain_name){
$stream_context = stream_context_create(array(
'ssl' => array('capture_peer_cert' => true)
));
$resource = stream_socket_client(
'ssl://' . $domain_name . ':443',
$errno,
$errstr,
30,
STREAM_CLIENT_CONNECT,
$stream_context
);
$cont = stream_context_get_params($resource);
$parsed = openssl_x509_parse($cont['options']['ssl']['peer_certificate']);
if(strpos($parsed['subject']['CN'], $domain_name) !== false){
// 1ヶ月以内の場合は、通知
$_ssl_limit = date('Y/m/d', $parsed['validTo_time_t']);
if(IS_TEST || strtotime($_ssl_limit) < mktime(0, 0, 0, date('m') + 1, date('d'), date('Y'))){
$_warning_message = "【SSL証明書期限】{$domain_name} ({$_ssl_limit})";
}
}else{
// 取得できなかったドメインも通知
$_warning_message = "【SSL証明書期限】{$domain_name} (取得失敗)";
}
if(!empty($_warning_message)){
if(IS_TEST) $_warning_message = 'TEST '.$_warning_message;
$warning_messages[] = $_warning_message;
echo $_warning_message."\n";
}
}
if(!empty($warning_messages)) SendSlack::send(implode("\n", $warning_messages));
return;
class SendSlack
{
public static function send($text){
$webhook_url = SLACK_WEBHOOK_URL;
$message = array(
'username' => 'Bot',
"channel" => SLACK_CHANNEL_NAME,
'text' => $text,
"icon_emoji" => ":ghost:",
);
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode($message),
),
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
),
);
$response = file_get_contents($webhook_url, false, stream_context_create($options));
$ret = $response === 'ok';
}
}
実行
日次バッチなどでphpを実行すると、期限が1ヶ月以内に迫った場合は、以下のような感じでSlackに通知される。
【SSL証明書期限】example.com (2018/12/31)