必须用外部shell脚本+crontab检查nginx证书有效期:先精准提取所有ssl_certificate路径(处理相对路径和多配置),转绝对路径后用openssl解析剩余天数,低于阈值(如15天)触发邮件或webhook告警,并支持反向代理上游证书校验。

不能在 Nginx 配置文件里写脚本,也不能靠 Nginx 自己检查证书到期时间。必须用外部 Shell 脚本 + 系统定时任务(如 cron)来完成,核心是:精准找到 Nginx 正在用的证书文件,再用 OpenSSL 解析其有效期。
准确提取 Nginx 使用的证书路径
Nginx 的 ssl_certificate 指令可能出现在主配置、include 的子配置或多个 server 块中,路径还可能是相对的。不能只靠 grep -r 简单搜索。
- 先获取主配置路径:
CONF=$(nginx -V 2>&1 | grep "configure arguments:" | sed -n 's/.*--conf-path=\([^[:space:]]*\).*/\1/p') - 再从所有生效配置中提取非注释行的证书路径:
awk '/^[[:space:]]*ssl_certificate[[:space:]]+[^;#]/{gsub(/["'"'"'];?$/, "", $2); gsub(/^[[:space:]"]+|[[:space:]"]+$/, "", $2); if($2) print $2}' "$CONF" $(dirname "$CONF")/sites-enabled/* 2>/dev/null | sort -u - 把相对路径转为绝对路径(以
$CONF所在目录为基准),并过滤掉非 PEM/CRT 文件
用 OpenSSL 计算剩余天数
拿到证书文件后,一行命令就能算出还剩多少天:
- 提取过期时间并转为时间戳:
openssl x509 -in /path/to/cert.pem -enddate -noout | awk '{print $4,$5,$6,$7,$8}' | xargs -I{} date -d "{}" +%s 2>/dev/null - 计算剩余天数(整数):
expr ($(date -d "$(openssl x509 -in /path/to/cert.pem -enddate -noout | awk '{print $4,$5,$6,$7,$8}')" +%s 2>/dev/null) - $(date +%s)) / 86400 2>/dev/null - 结果为负数表示已过期,0 表示当天到期,正数即剩余天数
设置定时检查与阈值告警
把上面逻辑封装成脚本,每天执行一次,低于设定天数就通知。
- 脚本中定义告警阈值(例如 15 天),用
if [ $days -le 15 ]; then ... fi判断 - 告警方式可选邮件:
echo "SSL expires in ${days} days" | mail -s "Nginx SSL Alert" admin@example.com - 也可调用企业微信/钉钉 Webhook,发送 Markdown 格式消息,含域名、剩余天数、过期时间
- 加入日志记录(如
>>/var/log/ssl-check.log)和错误捕获,避免单个证书异常导致整个脚本退出
兼顾反向代理场景的远程证书校验
如果 Nginx 是反向代理,还要确认上游 HTTPS 服务(如 proxy_pass https://api.example.com)的证书是否有效。
- 用 OpenSSL 直连上游端口获取实时证书:
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -noout -enddate - 同样解析该输出,计算剩余天数,纳入统一告警逻辑
- 这样能发现 CDN、LB 或后端服务自身证书过期的问题,不局限于 Nginx 本地配置的证书











