PHP 辅助监控 SSL 证书过期问题《顺手的 PHP》

Let's Encrypt 的简介

Let's Encrypt ,它拥有较短的有效期(三个月);通过 acme 协议,API 自动颁发证书;让一切 web 流量加密的理念;知名机构的支持; http/2.0 的摧枯拉朽,使得短时间内大行其道。

SSL 证书监控的缺失

传统手工申请安装证书有效期较长,使得证书过期问题被忽略。阿里云栖社区、新浪SAE、七牛等公司都有过生产环境证书过期的事故,可参见 v2ex 搜索的搜索记录。SSL 证书的监控不应该是缺失的一部分,除了公民,一切都应该被监控。

如何使用 PHP 辅助监控 SSL 证书过期问题?

通过 stream_context_create、stream_context_get_params、openssl_x509_parse 三个函数,我们可以得到 SSL 证书资源很多信息,包括证书的过期时间。这里有个 gist 获取了百度的证书信息。

我们可以编写一个检测页面,只要即将过期,就抛出异常。 然后使用阿里云监控这类成熟监控服务添加这个页面,设置一旦状态码 >= 400 立即报错,能够推送短信、邮件、钉钉。

<?php
$g = stream_context_create ([
    "ssl" => ["capture_peer_cert" => true],
    'http' => [
          'method' => 'GET',
        'user_agent' => 'shouwang.io ssl detector',
        'timeout'=>10
    ]
]);
$r = fopen("https://example.com/", "rb", false, $g);
$cont = stream_context_get_params($r);
$cert = openssl_x509_parse($cont["options"]["ssl"]["peer_certificate"]);

if(empty($cert['validTo_time_t'])) {
    throw new \Exception("Can't get cert expire time");
}

$fortyEightHours = strtotime("+48 hours");
if($cert['validTo_time_t'] <= $fortyEightHours) {
    throw new \Exception("Cert will expire in 48 hours");
} else {
    echo "Cert would expired at ", date("Y-m-d H:i:s", $cert['validTo_time_t']);
}

除此之外,如果你用的是 Let’s encrypt 的服务,还应当配置证书的自动更新。

第三方的服务

除此之外还有一些第三方 SSL 监控服务,然而在成熟度上略逊于云服务商的监控功能。此代码本来是想用于业余项目:守望者监控 shouwang.io,由于忙于主业,所以将此段代码拿出来分享。 希望各大云服务商早日推出自己的证书监控服务。

文章评论:做一头严肃的大叫驴

根据过去的经验得出,大多数评论是毫无意义的灌水,还有一小部分内容是针对文章的补充和纠错。如果你有建议请邮件联系。