可通过脚本+告警工具实现Nginx SSL证书到期自动告警,核心是从本地证书文件或远程443端口提取有效期,计算剩余天数并按阈值触发邮件/企业微信等通知,支持多域名及防重复告警。

可以通过定期检查 SSL 证书有效期并结合脚本+告警工具(如 Prometheus + Alertmanager、Zabbix 或简单邮件/企业微信通知)实现 Nginx 的 SSL 证书到期自动告警。核心不依赖 Nginx 原生功能,而是从证书文件或线上服务端口提取信息进行监控。
获取证书剩余天数(本地文件或远程端口)
SSL 证书有效期需从 PEM 文件或通过 OpenSSL 连接线上 443 端口实时获取。推荐两种方式:
-
监控本地证书文件:适用于证书由运维统一管理、路径固定(如
/etc/nginx/ssl/example.com.pem),用以下命令提取剩余天数:
openssl x509 -in /etc/nginx/ssl/example.com.pem -enddate -noout | awk -F' = ' '{print $2}' | xargs -I{} date -d "{}" +%s 2>/dev/null | xargs -I{} echo $(( ({} - $(date +%s)) / 86400 ))-
监控线上 HTTPS 端口:更真实反映生产环境实际证书(尤其使用 CDN、LB 或自动续签时),例如检查
example.com:443:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -enddate -noout | awk -F' = ' '{print $2}' | xargs -I{} date -d "{}" +%s 2>/dev/null | xargs -I{} echo $(( ({} - $(date +%s)) / 86400 ))返回负数表示已过期,0 表示当天到期,正数为剩余天数。
定时执行检查并触发告警
将上述命令封装为可执行脚本(如 /opt/scripts/check-ssl-expiry.sh),加入 cron 定期运行(建议每天一次):
- 设置阈值(如 15 天、7 天、3 天),低于则触发通知;
- 避免重复告警:记录上次告警时间或使用状态文件(如
/tmp/ssl_alerted_example.com); - 支持多域名:循环读取域名列表,逐个检测并汇总结果。
示例关键逻辑片段:
DOMAIN="example.com"
DAYS=$(echo | openssl s_client -connect $DOMAIN:443 -servername $DOMAIN 2>/dev/null | openssl x509 -enddate -noout 2>/dev/null | awk -F' = ' '{print $2}' | xargs -I{} date -d "{}" +%s 2>/dev/null | xargs -I{} echo $(( ({} - $(date +%s)) / 86400 )) 2>/dev/null)
if [ "$DAYS" -le 7 ] && [ "$DAYS" -ge 0 ]; then
[ ! -f "/tmp/ssl_alerted_$DOMAIN" ] && echo "$(date): SSL cert for $DOMAIN expires in $DAYS days" | mail -s "⚠️ SSL Certificate Alert" admin@example.com
touch "/tmp/ssl_alerted_$DOMAIN"
fi接入 Prometheus + Alertmanager(适合中大型环境)
若已有 Prometheus 生态,可用 ssl-cert-exporter 直接暴露证书剩余天数为指标 ssl_cert_not_after_seconds:
- Docker 启动 exporter,配置监控目标(支持文件路径、域名+端口、自定义标签);
- Prometheus 抓取指标后,配置告警规则:
groups:
- name: ssl-alerts
rules:
- alert: SSLCertificateExpiringSoon
expr: ssl_cert_not_after_seconds{job="ssl_certs"} - time() < 604800 # 7天
for: 1h
labels:
severity: warning
annotations:
summary: "SSL certificate for {{ $labels.instance }} expires soon"
description: "Expires in {{ $value | humanizeDuration }}"Alertmanager 可对接邮件、钉钉、企业微信、飞书等渠道完成自动通知。
补充建议与注意事项
- 确保执行脚本的用户有权限读取证书文件或发起 outbound HTTPS 请求(防火墙、SELinux 可能拦截);
- 对使用 Let’s Encrypt + Certbot 的环境,建议在
certbot renew --deploy-hook中加入验证和通知逻辑,双重保障; - 避免仅依赖 Nginx reload 时间判断——证书文件可能已更新但未重载,务必以实际端口响应为准;
- 测试阶段先用
echo替代真实告警,确认天数计算准确、超时处理合理。
不复杂但容易忽略的是证书链完整性 —— 若中间证书缺失,openssl s_client 可能无法正确解析有效期,建议加 -showcerts 调试或使用完整链文件验证。


















