nginx 不处理证书续签,需通过外部可观测性方案监控:用包装脚本将 certbot/acme.sh 续签结果写入 prometheus 格式文件(textfile_collector)或 json 状态文件,结合证书剩余天数指标与告警规则实现闭环监控,并确保 cron 稳定执行。

Nginx 本身不处理证书续签,也不感知 certbot、acme.sh 等工具的执行过程。要监控“证书自动续签模块的执行状态”,关键不是让 Nginx 做这件事,而是把续签动作变成可观测的外部事件,并通过 Prometheus 抓取其结果指标。
把续签脚本输出结构化指标(推荐 textfile_collector)
acme.sh 或 certbot 的 renew 命令执行后,应由一个包装脚本生成标准 Prometheus 格式的临时文件,供 Node Exporter 自动采集:
- 脚本在每次续签尝试后写入 /var/lib/node_exporter/textfile_collector/ssl_renew.prom(文件名必须以 .prom 结尾)
- 内容示例(成功时):
# HELP ssl_renew_last_run_timestamp Unix timestamp of last renew attempt
# TYPE ssl_renew_last_run_timestamp gauge
ssl_renew_last_run_timestamp 1725476220
# HELP ssl_renew_success_total Number of successful renewals
# TYPE ssl_renew_success_total counter
ssl_renew_success_total 42
# HELP ssl_renew_failed_total Number of failed renewals
# TYPE ssl_renew_failed_total counter
ssl_renew_failed_total 1 - 脚本需有执行权限,且确保 Node Exporter 已启用 textfile collector(默认开启,路径为
--collector.textfile.directory=/var/lib/node_exporter/textfile_collector)
用独立 HTTP 接口暴露续签结果(适配 nginx-vts-exporter 或自定义 exporter)
如果不想依赖 Node Exporter,可让续签脚本写一个 JSON 状态文件(如 /var/run/ssl-renew-status.json),再用 Nginx 暴露该路径:
- 在 Nginx 配置中添加内网仅限访问的 location:
location /health/renew {<br> alias /var/run/;<br> try_files ssl-renew-status.json =404;<br> allow 127.0.0.1;<br> allow 192.168.10.0/24;<br> deny all;<br>} - 续签脚本成功后写入:
{"timestamp":1725476220,"domain":"example.com","status":"success","expires_in_days":82} - 配合轻量 exporter(如
json_exporter)定时抓取该接口,转为 Prometheus 指标
关联证书剩余天数与续签状态(形成闭环判断)
仅看“续签是否运行过”不够,需结合证书真实有效期验证是否生效:
- 用另一个脚本定期提取 Nginx 配置中 ssl_certificate 文件的证书信息(如
openssl x509 -in /etc/nginx/ssl/example.com.crt -enddate -noout),计算剩余天数并写入指标:ssl_certificate_remaining_days{domain="example.com"} 82 - Prometheus 中设置告警规则,例如:
ssl_certificate_remaining_days <br>——表示证书即将过期,且最近 6 小时无续签记录,触发紧急告警 - 避免误报:续签成功但 Nginx 未 reload?可在脚本末尾加
nginx -t && nginx -s reload并记录 reload 时间戳作为辅助指标
检查 cron 是否真正触发了续签任务
底层稳定性常被忽略:cron 可能因环境变量缺失、路径错误或磁盘满而静默失败。
- 在 crontab 中明确指定 SHELL 和 PATH:
SHELL=/bin/bash<br>PATH=/usr/local/bin:/usr/bin:/bin<br>0 3 * * * /root/scripts/renew-ssl.sh >> /var/log/acme-renew.log 2>&1
- 用 Prometheus 抓取日志文件的 mtime(修改时间):
通过node_filesystem_mtime_seconds{mountpoint="/var/log",file=~".*acme-renew\.log"}判断是否按时更新 - 或直接采集 cron 日志(如 journalctl -u cron | grep acme),用 mtail 或 promtail 提取执行时间戳











