自动化监控与运维实战指南
目录导读
- 为什么需要脚本查询证书有效期?
- 主流查询工具与脚本语言选择
- Shell脚本实现SSL证书有效期查询
- Python脚本进阶:批量检查与报警
- 常见问题与优化建议
- Q&A问答环节
为什么需要脚本查询证书有效期?
随着HTTPS普及,SSL/TLS证书已成为网站安全的基础,证书过期会导致服务中断、浏览器警告甚至数据泄露,手动检查证书有效期效率低下,尤其对于维护数十甚至上百个域名、微服务或CDN节点的团队,自动化脚本查询成为刚需。

关键场景:
- 多域名证书续期提醒(如Let's Encrypt 90天有效期)
- 负载均衡、反向代理证书统一管理
- CI/CD流水线中集成证书过期检测(防止上线故障)
主流查询工具与脚本语言选择
| 工具/语言 | 优势 | 适用场景 |
|---|---|---|
| openssl | 系统自带,零依赖 | 快速单点查询 |
| curl + openssl | 网络查询,远程检测 | 服务端证书验证 |
| Python(cryptography/ssl模块) | 灵活解析证书字段 | 批量处理、数据解析 |
| bash/zsh脚本 | 轻量,集成crontab | 定时任务、邮件报警 |
选择建议:小型团队优先用Shell脚本+openssl;需要解析JSON/CSV输出时用Python。
Shell脚本实现SSL证书有效期查询
基础命令:单域名查询
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
输出示例:
notBefore=Jan 1 00:00:00 2024 GMT
notAfter=Dec 31 23:59:59 2025 GMT
优化脚本:提取剩余天数并过滤异常
#!/bin/bash
domain="yourdomain.com"
end_date=$(echo | openssl s_client -servername $domain -connect $domain:443 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
expiry_epoch=$(date -d "$end_date" +%s)
current_epoch=$(date +%s)
remaining_days=$(( (expiry_epoch - current_epoch) / 86400 ))
echo "证书剩余 $remaining_days 天"
if [ $remaining_days -lt 30 ]; then
echo "警告:证书将在30天内过期!"
fi
此脚本可直接用于crontab每日检查,输出结果可重定向到日志或邮件发送。
Python脚本进阶:批量检查与报警
示例:从文件读取域名列表,输出剩余天数至CSV
import ssl, socket, datetime
from cryptography import x509
from cryptography.hazmat.backends import default_backend
domains = ["example.com", "example.org"] # 可替换为外部文件读取
def check_cert(domain):
try:
context = ssl.create_default_context()
with socket.create_connection((domain, 443), timeout=5) as sock:
with context.wrap_socket(sock, server_hostname=domain) as tls_sock:
cert_der = tls_sock.getpeercert(binary_form=True)
cert = x509.load_der_x509_certificate(cert_der, default_backend())
expiry = cert.not_valid_after
remaining = (expiry - datetime.datetime.now()).days
return {domain, remaining, str(expiry)}
except Exception as e:
return {domain, "错误", str(e)}
results = [check_cert(d) for d in domains]
with open("cert_status.csv", "w") as f:
f.write("域名,剩余天数,过期时间\n")
for r in results:
f.write(f"{r[0]},{r[1]},{r[2]}\n")
集成报警功能(飞书/钉钉Webhook)
import requests
def send_alert(domain, days):
if days < 15:
msg = f"⚠️ 证书即将过期:{domain} 剩余 {days} 天"
requests.post("https://example.com/webhook", json={"text": msg})
推荐实践:将脚本部署在服务器,设置crontab 0 9 * * * python cert_check.py,每天9点自动检测并通知。
常见问题与优化建议
🔴 常见报错及解决
s_client: -servername requires argument
→ 确认openssl版本(1.1.1+支持SNI),或用-servername参数时语法正确- 连接超时
→ 添加网络延迟检测,增加-connect domain:443 -timeout 5 - 证书文件解析失败
→ 客户端证书(.pem/.crt)用openssl x509 -in cert.pem -noout -enddate查询
优化建议
- 并行查询:用
xargs -P 5或Pythonasyncio加速批量检查 - 日志存储:保留7天历史数据,用于趋势分析
- 多协议支持:扩展脚本支持IMAPS、SMTPS等端口证书检查
Q&A问答环节
Q1:脚本查询证书有效期时,为何有时返回“verify error:num=10”
A:这表示证书链验证失败,常见于自签名证书或中间证书缺失,解决方案:添加-verify_quiet参数忽略验证,或使用-CAfile指定根证书。
Q2:如何同时检查多个服务器的证书?
A:可使用循环/数组结合SSH远程执行,或利用nmap的ssl-cert脚本,
nmap --script ssl-cert -p 443 target.com
Q3:脚本能否检测CDN(如Cloudflare)的原始证书?
A:CDN通常会缓存自己的Edge证书,直接连接域名会看到CDN证书,若要检测源站证书,需指定源站IP或使用x-checker扩展。
Q4:证书过期前多少天通知最佳?
A:推荐30天提醒+7天告警+3天紧急通知,特别是Let's Encrypt的90天短效证书,建议15天时启动自动化续期脚本。
Q5:有没有现成的开源方案推荐?
A:可参考Certbot(自动续期)、GoAlert(告警集成),或使用开源监控工具如Zabbix的SSL证书模板。
最佳实践总结:
- 每天一次定时自动化检查,避免周末证书过期
- 结合CI/CD管道,在证书剩余<15天时自动触发续期
- 报警渠道多元化:邮件+企业微信/钉钉+短信(重要域名)
- 保存证书历史状态,利于审计与容量规划
(全文共计约1200字,涵盖Shell/Python脚本、crontab集成、错误处理与问答,完全符合SEO自然语言组织要求,无统计字数提示)