可通过shell脚本结合openssl与nginx -t提取nginx https站点证书路径,再计算剩余有效期并定时检查;需解析配置获取ssl_certificate路径、处理相对路径、用openssl读取enddate、转换为天数,小于30天告警,最后通过cron每日执行并记录日志。

可以在服务器上用 Shell 脚本结合 openssl 和 nginx -T(或配置文件路径)提取 HTTPS 站点的证书信息,再通过定时任务(cron)定期检查所有 Nginx 服务所用 SSL 证书的剩余有效期。
提取 Nginx 配置中所有监听 443 的 server 块及证书路径
Nginx 本身不直接暴露证书有效期,需从配置中找出 ssl_certificate 指令指向的 PEM 文件路径。脚本可递归扫描 /etc/nginx/conf.d/、/etc/nginx/sites-enabled/ 及主配置中的 include 文件:
- 用
grep -r "listen.*443" /etc/nginx/ | grep -v "#" | awk '{print $1}'初步定位含 HTTPS 的 server 块 - 更可靠方式是解析配置:用
nginx -T 2>/dev/null | awk '/^[\t ]*server {/,/^[\t ]*}/ {if (/ssl_certificate[[:space:]]+[^;]+;/) print $2}' | tr -d ';' | sort -u提取全部唯一证书路径 - 注意处理相对路径:Nginx 中
ssl_certificate cert.pem;默认相对于conf目录,脚本中需补全为/etc/nginx/cert.pem
用 openssl 获取证书剩余天数并告警
对每个证书路径,执行:
openssl x509 -in "$cert_path" -enddate -noout 2>/dev/null | \
cut -d' ' -f4- | \
xargs -I{} date -d "{}" +%s 2>/dev/null | \
awk -v now=$(date +%s) '{print int(($1 - now) / 86400)}'
若返回负数表示已过期;小于 30 天可触发邮件或写入日志。建议封装成函数:
check_cert_days() { local cert="$1"; [ -f "$cert" ] || { echo "$cert: not found"; return; }; ... }- 支持通配符证书:同一证书可能被多个
server_name共享,去重后检查即可 - 跳过软链接目标未就绪的情况(如 Certbot 自动续期中),加
[ -L "$cert" ] && cert=$(readlink -f "$cert")
集成到 cron 并生成可读报告
将脚本保存为 /usr/local/bin/check-nginx-certs.sh,添加执行权限,再设置定时任务:
- 每天凌晨 3 点运行:
0 3 * * * root /usr/local/bin/check-nginx-certs.sh >> /var/log/nginx-cert-check.log 2>&1 - 脚本末尾可用
echo "$(date): $(wc -l > /var/log/nginx-cert-check-summary.log记录摘要 - 关键告警建议用
logger -t nginx-cert "EXPIRING: example.com expires in 7 days"推送至系统日志,便于集中监控(如 journalctl 或 ELK)
处理常见异常场景
实际运行中需兼顾健壮性:
- 证书链文件(如
fullchain.pem)也能被openssl x509正确解析首张证书,无需额外拆分 - 遇到权限拒绝(如证书在
/root/下):确保脚本以 root 运行,或改用sudo -n openssl ...显式提权 - 部分站点用 TLS 终止在 CDN 或 LB 后端,Nginx 配置中无
ssl_certificate—— 这类无需检查,脚本自动跳过即可 - 输出格式统一为
域名 | 证书路径 | 剩余天数 | 状态,方便后续用awk '$4 ~ /CRITICAL/ {print $1}'快速提取高危域名











