Nginx 证书监控:如何编写自动化监控脚本实时解析 nginx -T 输出中的证书链合规性

作者:袖梨 2026-06-22
不推荐解析 nginx -T 监控证书链,应从配置文件精准提取 ssl_certificate 路径,补全为绝对路径后,用 OpenSSL 验证 PEM 文件中证书链的完整性、顺序及有效期。

直接解析 nginx -T 输出来监控证书链合规性,不推荐——因为该命令输出的是合并后的全部配置(含注释、重复块、未生效的 server 块),结构混乱且无证书文件路径的可靠上下文。真正可行的自动化方案是:**跳过 nginx -T,转而从 Nginx 配置文件中精准提取 ssl_certificatessl_certificate_key 指令指向的 PEM 文件路径,再对这些证书文件做链验证**。

1. 从配置中准确提取证书路径

Nginx 配置中证书路径可能分散在多个 server 块中,还可能使用变量或相对路径。需用稳健方式解析:

  • 使用 nginx -t -q 确保配置语法正确,避免解析失败
  • awkgrep -oP 提取所有非注释行中的 ssl_certificate 指令值,忽略被注释掉的行和空行
  • 将相对路径补全为绝对路径(基于 nginx.conf 所在目录或 prefix 路径)
  • 去重并过滤空值、非 PEM 后缀路径(如 .crt, .pem, .cer

示例(Bash):

# 获取主配置路径(通常 /etc/nginx/nginx.conf)CONF=$(nginx -V 2>&1 | grep "configure arguments:" | sed -n 's/.*--conf-path=([^[:space:]]*).*/1/p')CONF=${CONF:-/etc/nginx/nginx.conf}<h1>提取所有 ssl_certificate 路径(跳过注释、支持引号包裹、处理空格)</h1><p>awk '/^[[:space:]]<em>ssl_certificate[[:space:]]+[^;#]/{gsub(/["'"'"'];?$/, "", $2); gsub(/^[[:space:]"]+|[[:space:]"]+$/, "", $2); if($2) print $2}' $(dirname "$CONF")/sites-enabled/</em> "$CONF" 2>/dev/null | xargs -I{} sh -c 'cd $(dirname "$CONF"); echo "$(pwd)/{}"' | sort -u

2. 解析证书链并验证完整性与顺序

单个 PEM 文件可能包含证书链(server cert + intermediate(s) + root),但顺序错误或缺失中间证书会导致浏览器信任失败。需检查:

  • 是否至少含 1 张证书(server cert)
  • 是否按“server → intermediate(s) → root(可选)”顺序排列(OpenSSL 默认验证要求)
  • 每张证书是否有效(未过期、签名可验、用途匹配)
  • 链能否向上追溯至系统信任库中的根证书(可用 openssl verify -untrusted

验证脚本片段(Bash + OpenSSL):

for cert in $CERT_FILES; do  # 提取所有证书并编号  n=$(openssl crl2pkcs7 -nocrl -certfile "$cert" 2>/dev/null |      openssl pkcs7 -print_certs -noout 2>/dev/null |      grep "^subject|^issuer" | wc -l)<p>if [ "$n" -eq 0 ]; thenecho "[WARN] $cert: no valid certificate found"continuefi</p><h1>验证链(自动识别中间证书)</h1><p>if ! openssl verify -untrusted <(openssl crl2pkcs7 -nocrl -certfile "$cert" 2>/dev/null | openssl pkcs7 -print_certs -noout 2>/dev/null | sed '1,/^$/d') "$cert" >/dev/null 2>&1; thenecho "[FAIL] $cert: chain verification failed"elseecho "[OK] $cert: chain valid"fidone

3. 集成到监控流程(Prometheus + Exporter 或 Shell 告警)

生产环境建议用轻量 Exporter(如自研 Bash Exporter 或 nginx-cert-exporter),但快速落地可用:

  • 定时任务(cron)每 4 小时执行一次校验脚本
  • 失败时写入日志并触发告警(邮件 / Webhook / Slack)
  • 导出指标供 Prometheus 抓取(例如:nginx_cert_expires_in_seconds{path="/path/to/cert.pem"} 1234567
  • 额外检查证书剩余有效期(openssl x509 -in cert.pem -enddate -noout),提前 30 天预警

4. 注意事项与避坑点

实际部署中常见问题:

  • 不要依赖 nginx -T 的输出解析证书路径:它会拼接所有 include 文件,路径丢失上下文,且无法区分生效/未生效的 server 块
  • 相对路径必须补全:Nginx 默认以 prefix(如 /etc/nginx)为基准,但 ssl_certificate 可能写成 certs/example.com.crt
  • 忽略软链接目标变更风险:若证书是符号链接,需用 readlink -f 解析真实路径后再校验
  • 多实例场景要指定 nginx 二进制路径:如容器化部署中,nginx -c /app/conf/nginx.conf 需统一入口

相关文章

精彩推荐