当前位置:首页>python>Python检测SSL证书到期:证书过期这种事真的会发生

Python检测SSL证书到期:证书过期这种事真的会发生

  • 2026-10-11 07:17:29
Python检测SSL证书到期:证书过期这种事真的会发生

证书过期是网络运维里最让人窝火的事故之一。明明网站能打开,但浏览器弹个安全警告,用户第一个电话就打到你这里来。实际上证书过期这种事完全可以提前发现,写个Python脚本监控一下,到期前30天就报警,不用等到出事才救火。

Python的标准库里就有处理SSL证书的能力,不需要装第三方库:

importssl
importsocket
fromdatetimeimportdatetime, timedelta
importcsv
importsmtplib
fromemail.mime.textimportMIMEText
fromemail.mime.multipartimportMIMEMultipart

defget_cert_info(host, port=443, timeout=5):
"""获取目标站点的SSL证书信息"""
context=ssl.create_default_context()
context.check_hostname=False
context.verify_mode=ssl.CERT_NONE# 忽略证书链验证错误,照样读取证书信息

try:
withsocket.create_connection((host, port), timeout=timeout) assock:
withcontext.wrap_socket(sock, server_hostname=host) asssock:
cert=ssock.getpeercert(binary_form=True)
# 解析证书
fromcryptographyimportx509
fromcryptography.hazmat.backendsimportdefault_backend
cert_obj=x509.load_der_x509_certificate(cert, default_backend())

not_before=cert_obj.not_valid_before_utc
not_after=cert_obj.not_valid_after_utc
issuer=cert_obj.issuer.rfc4514_string()
subject=cert_obj.subject.rfc4514_string()

return {
'host': host,
'port': port,
'subject': subject,
'issuer': issuer,
'not_before': not_before,
'not_after': not_after,
'days_left': (not_after-datetime.utcnow()).days
                }
exceptExceptionase:
return {'host': host, 'port': port, 'error': str(e)}

defcheck_certificate(host, warning_days=30):
"""检查证书状态,返回(是否正常, 描述信息)"""
info=get_cert_info(host)

if'error'ininfo:
returnFalse, f"连接失败:{info['error']}"

days_left=info['days_left']

ifdays_left<0:
returnFalse, f"证书已过期 {abs(days_left)} 天!"
elifdays_left<=warning_days:
returnFalse, f"证书即将过期,剩余 {days_left} 天"
else:
returnTrue, f"证书正常,剩余 {days_left} 天"

# 安装依赖:pip install cryptography
# 批量检查域名列表
SITES= [
    ("www.example.com", 443),
    ("api.example.com", 443),
    ("mail.example.com", 443),
    ("vpn.example.com", 443),
]

if__name__=="__main__":
print(f"检查时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("="*60)

warning_count=0
forhost, portinSITES:
status, msg=check_certificate(host, warning_days=30)
symbol="[OK]"ifstatuselse"[警告]"
print(f"{symbol}{host:30s}{msg}")
ifnotstatus:
warning_count+=1

print("="*60)
ifwarning_count>0:
print(f"共发现 {warning_count} 个站点的证书需要关注")
else:
print("所有站点证书状态正常")

这里用的是Python标准库里的ssl和socket,配合cryptography库来解析X.509证书。cryptography需要单独装一下:

pip install cryptography

核心逻辑就是建立SSL连接之后用getpeercert()拿到证书信息,然后计算剩余天数,和告警阈值做比较。

实际用这个脚本排查过一个遗留问题:某台VPN网关的证书还有17天到期,VPN设备本身又没法装自动续期脚本,靠人工又容易忘。用这个脚本加了定时任务,每周扫一遍内网所有HTTPS资产,提前把到期时间摸清楚,在过期前两周就安排好续期。

进阶一点的做法是把结果写到CSV文件里,再配合钉钉或者企业微信的Webhook做自动告警。脚本本身逻辑很简单,加上一个requests.post()调用把告警信息推出去就行:

defsend_dingtalk_alert(title, content):
"""发送钉钉告警"""
webhook_url="https://oapi.dingtalk.com/robot/send?access_token=你的token"
payload= {
"msgtype": "markdown",
"markdown": {"title": title, "text": f"### {title}\n{content}"}
    }
requests.post(webhook_url, json=payload)

放到cron里每周跑一次,比什么监控系统都省事。

最新文章

随机文章