nginx 本身无法主动监控 ssl 证书剩余有效期,因其不内置证书检查功能;需通过外部脚本(如 openssl 解析 pem 文件)定期计算剩余天数,并结合 cron、告警工具或状态接口实现监控与预警。

直接用 Nginx 本身无法主动监控 SSL 证书剩余有效期,因为它不内置证书检查功能,也不定期读取或验证证书文件的过期时间。但可以通过外部脚本配合 Nginx 的运行环境(如 cron、systemd timer)定期检查证书文件,并结合日志、告警或状态接口实现“监控效果”。关键在于把证书文件路径暴露给可执行工具(如 openssl),再把结果用于通知或健康检查。
获取证书剩余天数(命令行基础)
SSL 证书(PEM 格式)可通过 openssl 提取到期时间:
openssl x509 -in /path/to/fullchain.pem -enddate -noout | cut -d' ' -f4-
- 更实用的是直接算出剩余天数:
openssl x509 -in /path/to/fullchain.pem -enddate -noout -dates 2>/dev/null | awk '/notAfter/ {print $4,$5,$6,$7,$8}' | xargs -I{} date -d "{}" +%s 2>/dev/null | xargs -I{} echo $(($(date +%s) - {})) | xargs -I{} echo "剩余 $(( {}/86400 )) 天" - 推荐简化版(一行可靠):
expr $(($(date -d "$(openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -enddate -noout | awk '{print $4,$5,$6,$7,$8}')" +%s 2>/dev/null) - $(date +%s))) / 86400 2>/dev/null
集成到自动化检查流程
把上述逻辑封装为脚本,由系统定时触发:
- 写一个检查脚本(如
/usr/local/bin/check-ssl-expiry.sh),输出剩余天数或状态(OK/ALERT) - 用
cron每天执行一次:0 3 * * * /usr/local/bin/check-ssl-expiry.sh >> /var/log/ssl-check.log 2>&1 - 脚本内可加入阈值判断(如
if [ $days -le 15 ]; then echo "ALERT: SSL expires in $days days" | mail -s "SSL Warning" admin@example.com; fi) - 也可将结果写入 Nginx 可访问的临时文件(如
/var/www/html/ssl-status.txt),供运维页面或 Prometheus 抓取
与 Nginx 服务联动(轻量级健康检查)
虽然 Nginx 不解析证书,但可以借助其静态文件能力暴露状态:
- 在 Nginx 配置中添加一个内部 location:
location /health/ssl { alias /var/run/; try_files ssl-status.txt =404; } - 让检查脚本每次成功后生成
/var/run/ssl-status.txt,内容如:{"domain":"example.com","expires_in":24,"status":"ok"} - 这样可通过
curl http://localhost/health/ssl获取实时状态,接入 Prometheus、Zabbix 或自建看板
使用现成工具降低维护成本
避免重复造轮子,推荐几个成熟方案:
-
sslexpire:轻量 CLI 工具,支持批量检查本地证书和远程 HTTPS 站点
sslexpire -f /etc/letsencrypt/live/example.com/fullchain.pem -
cert-exporter(Prometheus Exporter):专为证书设计,支持文件路径和域名探测,输出指标如
ssl_cert_not_after_seconds - acme.sh + hook:若用 acme.sh 管理证书,可在 renew-hook 中自动触发检查或推送告警
不复杂但容易忽略:证书路径要确保 Nginx worker 进程有读取权限;Let’s Encrypt 的证书通常放在 /etc/letsencrypt/live/ 下,但实际链接指向 archive/,建议用 readlink -f 获取真实路径再检查。











