nginx 不支持内置证书过期检测与告警,需通过外部 shell 脚本配合 cron 定时检查 openssl 解析的证书有效期,并在剩余天数≤阈值时写入日志;脚本可扩展支持多证书遍历及邮件、webhook 等告警通知。

Nginx 本身不内置证书过期检测与告警功能,无法直接在配置文件中实现“证书即将过期时写日志”。它只负责 TLS 握手和证书加载,不主动检查证书有效期。要实现证书过期告警并记录到日志文件,需借助外部脚本配合定时任务(如 cron),再通过日志系统(如 rsyslog 或直接追加)写入指定文件。
用 shell 脚本检查证书剩余天数
核心思路是:从 Nginx 配置中提取证书路径(如 /etc/nginx/ssl/example.com.crt),用 OpenSSL 解析其 Not After 时间,计算距当前的剩余天数。当低于阈值(如 15 天)时,追加一条告警日志到指定文件(如 /var/log/nginx/cert_alert.log)。
- 脚本示例(保存为 /usr/local/bin/check-cert-expiry.sh):
#!/bin/bash
CERT_PATH="/etc/nginx/ssl/example.com.crt"
LOG_FILE="/var/log/nginx/cert_alert.log"
DAYS_WARN=15
if [ ! -f "$CERT_PATH" ]; then
echo "$(date): ERROR - Certificate not found: $CERT_PATH" >> "$LOG_FILE"
exit 1
fi
EXPIRY_DATE=$(openssl x509 -in "$CERT_PATH" -enddate -noout | cut -d' ' -f4-)
EXPIRY_SECONDS=$(date -d "$EXPIRY_DATE" +%s 2>/dev/null)
NOW_SECONDS=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_SECONDS - NOW_SECONDS) / 86400 ))
if [ "$DAYS_LEFT" -le "$DAYS_WARN" ] && [ "$DAYS_LEFT" -ge 0 ]; then
echo "$(date): WARNING - SSL certificate expires in $DAYS_LEFT days" >> "$LOG_FILE"
elif [ "$DAYS_LEFT" -lt 0 ]; then
echo "$(date): CRITICAL - SSL certificate has expired!" >> "$LOG_FILE"
fi
设置定期执行的 cron 任务
让系统每天凌晨 2 点自动运行该脚本,及时发现临期证书。
- 运行 crontab -e,添加一行:
0 2 * * * /usr/local/bin/check-cert-expiry.sh
- 确保日志目录存在且 Nginx 或运行脚本的用户(如 root)有写入权限:
mkdir -p /var/log/nginx
touch /var/log/nginx/cert_alert.log
chmod 644 /var/log/nginx/cert_alert.log
支持多个证书的灵活处理
若 Nginx 使用多个域名、多个证书,可将脚本升级为遍历配置中所有 ssl_certificate 指令指向的文件:
- 用 grep -r "ssl_certificate" /etc/nginx/conf.d/ 提取所有证书路径
- 对每个路径去重、过滤注释行后逐个检查
- 日志中明确标注域名或证书路径,便于定位问题
配合 Nginx 重载与监控更进一步
脚本可在告警同时触发通知动作,提升实用性:
- 发邮件:echo "Cert expires soon" | mail -s "Nginx SSL Alert" admin@example.com
- 调用企业微信/钉钉机器人 Webhook(需额外 curl 命令)
- 检查后自动 reload Nginx(谨慎使用):nginx -t && nginx -s reload,适用于证书已更新但未重载场景











