定时检测SSL证书过期情况并发送通知

PHP 2018/09/10

Let’s Encrypt免费证书只有3个月有效期,到期需要续签。

虽然像宝塔一样的面板在申请证书后会自动添加crontab任务,自动续签。但是有时候需要手动去检测证书过期情况,以免过期了还不知道。

于是就想着通过PHP来检测证书的过期时间,然后发送方糖通知。

核心

通过PHP里的Streams扩展功能(stream_context_create、stream_socket_client等)函数创建并返回一个资源流,然后通过openssl_x509_parse函数解析证书信息

stream_context_create函数详解:http://www.php.net/manual/zh/book.stream.php

代码

下载:https://file.bugxia.com/s/KN6t7y7drYH92Tr

<?php

//需要检查的域名数组
$domains = array(
	"bugxia.com",
	"baidu.com"
);

foreach($domains as $domain){
	$result = check($domain);
	echo $domain." ---- ".$result."<br>";
}


//检测证书信息
function check($domain){
	$stream_option = array(
		"ssl" => array(
			"capture_peer_cert_chain" => true
		)
	);
	$stream = stream_context_create($stream_option); 
	$stream_client = stream_socket_client("ssl://".$domain.":443", $errno, $errstr, 20, STREAM_CLIENT_CONNECT, $stream);
	if(!$stream_client){
		return "发生错误,错误代码:".$errno;
	}
	$stream_info = stream_context_get_params($stream_client);
	stream_socket_shutdown($stream_client, STREAM_SHUT_WR);
	
	foreach ($stream_info["options"]["ssl"]["peer_certificate_chain"] as $cert) {
		$cerInfo = openssl_x509_parse($cert);
		if(strstr($cerInfo["extensions"]["subjectAltName"],"DNS:".$domain) != false){
			return expireLeft($cerInfo['validTo_time_t']);
			if($cerInfo['validTo_time_t'] - time() < 86400){
				sendFTQQ($domain);
			}
		}else{
			return "未发现该证书对应的域名:".$cerInfo["extensions"]["subjectAltName"];
		}
	}
}

//证书到期时间格式化
function expireLeft($exp_time){
	$sec = $exp_time - time();
	switch ($sec)
	{
		case $sec<0:
			return "已过期";
			break;  
		case $sec > 0 and $sec < 61:
			return $c."秒";
			break; 
		case $sec < 3600 and $sec > 60:
			return round($c/60,0)."分钟";
			break; 
		case $sec < 86401 and $sec > 3600:
			return round($c/3600,0)."小时";
			break; 
		case $sec > 86400:
			return floor($sec/86400)."天";
			break; 
	}
}
//方糖通知
//申请地址:http://sc.ftqq.com/3.version
function sendFTQQ($domain){
	$SCKEY = "方糖KEY";
	$url = 'https://sc.ftqq.com/'.$SCKEY.'.send?desp='.urlencode($domain).'&text='.urlencode("域名证书到期通知");
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
	curl_setopt($ch, CURLOPT_SSLVERSION , CURL_SSLVERSION_DEFAULT);
	curl_setopt($ch, CURLOPT_POST, TRUE);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $data);        
	curl_setopt($ch, CURLOPT_TIMEOUT, 10);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$result = curl_exec($ch);
	curl_close($ch);
	return;
}
?>

 

本文标签:


评论(*号为必填项)