不推荐解析 nginx -T 监控证书链,应从配置文件精准提取 ssl_certificate 路径,补全为绝对路径后,用 OpenSSL 验证 PEM 文件中证书链的完整性、顺序及有效期。
直接解析 nginx -T 输出来监控证书链合规性,不推荐——因为该命令输出的是合并后的全部配置(含注释、重复块、未生效的 server 块),结构混乱且无证书文件路径的可靠上下文。真正可行的自动化方案是:**跳过 nginx -T,转而从 Nginx 配置文件中精准提取 ssl_certificate 和 ssl_certificate_key 指令指向的 PEM 文件路径,再对这些证书文件做链验证**。
Nginx 配置中证书路径可能分散在多个 server 块中,还可能使用变量或相对路径。需用稳健方式解析:
nginx -t -q 确保配置语法正确,避免解析失败awk 或 grep -oP 提取所有非注释行中的 ssl_certificate 指令值,忽略被注释掉的行和空行nginx.conf 所在目录或 prefix 路径).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
单个 PEM 文件可能包含证书链(server cert + intermediate(s) + root),但顺序错误或缺失中间证书会导致浏览器信任失败。需检查:
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
生产环境建议用轻量 Exporter(如自研 Bash Exporter 或 nginx-cert-exporter),但快速落地可用:
cron)每 4 小时执行一次校验脚本nginx_cert_expires_in_seconds{path="/path/to/cert.pem"} 1234567)openssl x509 -in cert.pem -enddate -noout),提前 30 天预警实际部署中常见问题:
nginx -T 的输出解析证书路径:它会拼接所有 include 文件,路径丢失上下文,且无法区分生效/未生效的 server 块/etc/nginx)为基准,但 ssl_certificate 可能写成 certs/example.com.crt
readlink -f 解析真实路径后再校验nginx -c /app/conf/nginx.conf 需统一入口