nginx 不支持主证书失效自动切换,但可通过 sni 多证书配置、acme.sh 自定义 hook 降级、定期监控证书有效期三步实现容灾。需预置主备证书、用软链接统一管理路径、reload 前校验语法并确保权限正确。

Nginx 本身不内置“主证书失效自动切换备用证书”的运行时容灾逻辑,但可通过组合配置 + 外部工具 + SNI 多证书能力,实现接近自动化的证书降级与故障应对。关键不是让 Nginx 主动“检测证书过期”,而是预先部署多证书、配合健康检查与 reload 机制,在证书异常前或异常发生后快速响应。
以下为实用、可落地的三步实现路径:
1. 利用 SNI 多证书支持,为同一域名预置主/备证书
Nginx 1.15.9+ 原生支持按 server_name 匹配不同证书(SNI),允许你在单个 server 块中为同一域名声明多个 ssl_certificate 和 ssl_certificate_key 对——但注意:Nginx 不会自动在它们之间“切换”,必须靠外部触发 reload 并更新配置指向备用路径。
更可行的做法是:
- 在
server块中保留两套独立的server配置,监听相同端口和域名,但用listen ... ssl+ssl_certificate分别指定主证与备证; - 通过
include或条件变量控制启用哪一套(例如用if不适用,改用map+include_if_exists模式,或直接靠脚本替换软链接); - 示例结构:
# /etc/nginx/conf.d/example.com.conf map $upstream_cert_status $cert_path { default "/etc/nginx/ssl/example.com/main.crt"; "backup" "/etc/nginx/ssl/example.com/backup.crt"; } server { listen 443 ssl; server_name example.com; ssl_certificate $cert_path; ssl_certificate_key /etc/nginx/ssl/example.com/main.key; # 注意:key 路径需同步管理 # … 其他配置 }⚠️ 实际中更推荐用符号链接统一管理(见下文),而非动态变量——更稳定、更易调试。
2. 用 acme.sh + 自定义 hook 实现证书续签失败时自动启用备用证书
acme.sh 支持 --reloadcmd 和 --hook,可在证书更新失败时执行降级操作:
- 将备用证书(如由私有 CA 签发或离线保存的 Let’s Encrypt 备份)放在固定路径,例如
/etc/nginx/ssl/example.com/backup/; - 编写 hook 脚本(如
/usr/local/bin/cert-fallback.sh),当acme.sh --renew返回非零码时:- 备份当前生效的证书软链接;
- 将
/etc/nginx/ssl/example.com/cert.pem→ 指向备用证书; - 执行
nginx -s reload;
- 在 acme.sh 命令中挂载该 hook:
acme.sh --renew -d example.com --hook "/usr/local/bin/cert-fallback.sh"
3. 监控证书有效期并主动触发切换(推荐生产环境)
依赖 cron 定期扫描证书剩余天数,提前干预比等失效更可靠:
- 编写检查脚本(如
/opt/monitor/check-cert.sh):#!/bin/bash CERT="/etc/nginx/ssl/example.com/cert.pem" DAYS_LEFT=$(openssl x509 -in "$CERT" -enddate -noout | cut -d' ' -f4-6 | xargs -I{} date -d {} +%s 2>/dev/null) TODAY=$(date +%s) if [ $((DAYS_LEFT - TODAY)) -lt 7 ]; then ln -sf /etc/nginx/ssl/example.com/backup.pem /etc/nginx/ssl/example.com/cert.pem ln -sf /etc/nginx/ssl/example.com/backup.key /etc/nginx/ssl/example.com/key.pem nginx -s reload fi - 加入 crontab 每日执行:
0 3 * * * /opt/monitor/check-cert.sh 2>/dev/null
不复杂但容易忽略:所有证书路径必须确保 Nginx worker 进程有读取权限;reload 前务必 nginx -t 校验语法;备用证书需提前测试兼容性(如 TLS 版本、密钥长度、签名算法)。











