python3监控https证书过期时间

上周日,我们的一个https证书到期了,结果运维没有事前检查到,导致服务中断,于是赶紧亡羊补牢一个python3的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# !/usr/bin/env python 
# -*- coding:utf-8 -*-
# 作者:ChrisChan
# 用途:获取https证书的过期时间,需要先执行pip3 install pyopenssl
from urllib3.contrib import pyopenssl as reqs
from datetime import datetime

# 公网验证
cert = reqs.OpenSSL.crypto.load_certificate(reqs.OpenSSL.crypto.FILETYPE_PEM, reqs.ssl.get_server_certificate(('cn.imoulife.com', 443)))

notafter = datetime.strptime(cert.get_notAfter().decode()[0:-1], '%Y%m%d%H%M%S') #获取到的时间戳格式是ans.1的,需要转换
remain_days = notafter - datetime.now() # 用证书到期时间减去当前时间
print(remain_days.days)

# 离线验证
from OpenSSL import crypto

cert_file = 'F:\\crt文件的路径\\mycert.crt'
cert2 = crypto.load_certificate(crypto.FILETYPE_PEM, open(cert_file).read())
cert2.get_version()
subject = cert2.get_subject()
subject.get_components()
print("域名是:",subject.CN)
print("终止的时间戳是:",cert2.get_notAfter())

pyopenssl可以给与我们的https信息非常的丰富,除了到期时间之外,还有如下几个常用项:

  1. get_subject():返回证书域名
  2. get_version():返回证书版本
  3. get_issuer():证书颁发机构

更多信息可以去看 https://www.pyopenssl.org/en/stable/index.html 官网介绍。

进一步加工后的脚本是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# !/usr/bin/env python 
# -*- coding:utf-8 -*-
import argparse
from urllib3.contrib import pyopenssl as reqs
from datetime import datetime

# 命令行参数
parser = argparse.ArgumentParser(description='本脚本获取https证书到期时间')
parser.add_argument('-w', '--www', metavar='https网站,如cn.imoulife.com', required=True, dest='sites', nargs='+', help='请一定要输入监控的https网站') # required表示此字段一定需要,nargs=’+’ 表>示至少一个参数
args = parser.parse_args()


# 公网验证
def get_notafter(www):
cert = reqs.OpenSSL.crypto.load_certificate(reqs.OpenSSL.crypto.FILETYPE_PEM, reqs.ssl.get_server_certificate((www, 443)))

notafter = datetime.strptime(cert.get_notAfter().decode()[0:-1], '%Y%m%d%H%M%S')
remain_days = notafter - datetime.now() # 用证书到期时间减去当前时间
print(www,"证书到期天数是:",remain_days.days)


# 输出结果
try:
for site in args.sites:
get_notafter(site)
except Exception as e:
print("出现错误,请检查域名是否正确或者可达性!")

执行效果如下:
抱光妹

shell脚本

http://noops.me/?p=945 这个小米的运维网站分享一个非常不错的shell脚本来监控证书,脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#! /bin/sh

host=$1
port=$2
end_date=`openssl s_client -host $host -port $port -showcerts </dev/null 2>/dev/null |
sed -n '/BEGIN CERTIFICATE/,/END CERT/p' |
openssl x509 -text 2>/dev/null |
sed -n 's/ *Not After : *//p'`
# openssl 检验和验证SSL证书。
# </dev/null 定向标准输入,防止交互式程序Hang。从/dev/null 读时,直接读出0 。
# sed -n 和p 一起使用,仅显示匹配到的部分。 //,// 区间匹配。
# openssl x509 -text 解码证书信息,包含证书的有效期。

if [ -n "$end_date" ]
then
end_date_seconds=`date '+%s' --date "$end_date"`
# date指令format字符串时间。
now_seconds=`date '+%s'`
echo "($end_date_seconds-$now_seconds)/24/3600" | bc
fi

上面那个有两个小地方可以改进下:echo “HOST: test.com /r/n GET / HTTP/1.1″|openssl s_client -connect test.com:443 这样可以增加速度,因为openssl s_client只负责链接,后面是请求内容如果不输入的话就是等待超时,时间会很长。而且增加一个参数-servername可一直开启TLS SNI support,可以检测一个ip多个证书的情况。

其他监控证书的网站

如果不想用脚本监控可以用第三方网站监控,下面这三个网站方法都一样:就是填入自己的邮箱注册账户,然后在页面输入自己要监控的域名,然后会给你一个剩余时间,如果快到期了就会给你发邮件通知,这三个网站分别是:

  1. letsmonitor.org 每小时检测一次,但是发送告警邮件只有一次
  2. certificatemonitor.org 非常简单,只能443端口,一共会发9次邮件通知
  3. https://keychest.net/ 它支持api,邮件每周一次发送,比较好

详情可见https://www.sooele.com/2784.html

参考资料

https://flyhigher.top/develop/755.html
https://blog.skk.moe/post/checkssl-status/
https://blog.csdn.net/tzdjzs/article/details/28124609
https://www.conum.cn/program/python/241.html (pyopenssl的介绍)
https://python3-cookbook.readthedocs.io/zh_CN/latest/c13/p03_parsing_command_line_options.html (python命令行参数)

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------