nginx 无法直接监控 ssl 证书剩余天数,需借助外部 shell 脚本配合 cron 定时执行,通过 openssl 解析 pem 证书有效期并按阈值告警。

在 Nginx 中直接执行脚本监控 SSL 证书剩余天数是不可行的——Nginx 本身不提供运行 Shell 脚本或主动检查证书有效期的能力。它只是一个反向代理和 Web 服务器,不具备内置的证书生命周期监控功能。真正的监控必须由外部脚本配合系统定时任务(如 cron)来完成,然后通过日志、邮件、Webhook 等方式触发告警。
获取证书有效期的常用方法
大多数 SSL 证书以 PEM 格式存放(如 /etc/nginx/ssl/example.com.crt),可用 OpenSSL 命令提取到期时间:
openssl x509 -in /etc/nginx/ssl/example.com.crt -enddate -noout | cut -d' ' -f4-- 更可靠的方式是计算剩余天数:
openssl x509 -in /etc/nginx/ssl/example.com.crt -enddate -noout | awk '{print $4,$5,$6}' | xargs -I {} date -d "{}" +%s 2>/dev/null | xargs -I {} echo $(($(date +%s) - {})) | xargs -I {} echo "剩余 $(( {}/86400 )) 天" - 推荐使用一行简洁命令:
expr $(( ($(date -d "$(/dev/null) - $(date +%s) )) / 86400
编写可复用的监控脚本
新建脚本 /usr/local/bin/check_ssl_expiry.sh,支持多个证书路径,并设置告警阈值(如 30 天):
- 脚本开头加
#!/bin/bash,并确保有执行权限:chmod +x /usr/local/bin/check_ssl_expiry.sh - 遍历指定证书文件,逐个解析剩余天数,记录低于阈值的域名和天数
- 发现临期证书时,可调用
mail发送邮件、curl推送企业微信/钉钉 Webhook,或写入日志供 Prometheus 抓取 - 示例关键逻辑:
days_left=$(openssl x509 -in "$cert" -enddate -noout | awk '{print $4,$5,$6}' | xargs -I {} date -d "{}" +%s 2>/dev/null | xargs -I {} echo $(($(date +%s) - {})) | xargs -I {} echo $(( {}/86400 ))
通过 cron 定期执行并静默运行
将脚本加入系统定时任务,建议每天凌晨执行一次:
- 编辑 root 的 crontab:
sudo crontab -e - 添加行:
0 3 * * * /usr/local/bin/check_ssl_expiry.sh >> /var/log/ssl_expiry.log 2>&1 - 避免日志爆炸:可在脚本内判断只有告警时才输出,或用
logger写入 syslog - 测试脚本是否正常工作:
sudo -u root /usr/local/bin/check_ssl_expiry.sh
与 Nginx 配合的实用补充建议
虽然 Nginx 不参与监控,但可辅助提升可观测性:
- 在 Nginx 日志中记录证书信息(需编译时启用
ngx_http_ssl_module并配置log_format含$ssl_protocol、$ssl_cipher,但不包含有效期) - 利用
nginx -t和nginx -s reload在更新证书后自动重载,确保新证书生效 - 配合 Certbot 自动续期时,在
--deploy-hook中调用监控脚本,实现“更新即验证” - 把证书路径统一存放在变量或配置文件中,方便脚本读取,避免硬编码











