★NGINX 原生支持 ACME 协议:ngx_http_acme_module
全面指南★
TL;DR
NGINX 推出基于 Rust 的预览模块 ngx_http_acme_module
,支持在 NGINX 配置中直接请求、安装与续期 ACME(如 Let’s Encrypt)证书。当前支持 HTTP-01 验证,减少对 Certbot 的依赖,便于自动化 HTTPS 部署与运维。
一、概述:为什么要把 ACME 放进 NGINX 配置层
随着网站 HTTPS 的普及,证书管理已成为运维的基础技能。ACME(Automated Certificate Management Environment, RFC 8555)将证书签发与续期自动化,Let’s Encrypt 借此大幅降低了证书成本与复杂度。NGINX 将 ACME 功能以 ngx_http_acme_module
的形式“原生”集成,意味着你可以直接在 NGINX 配置层完成证书生命周期管理,而非依赖系统级别的外部工具(如 Certbot、acme.sh 等)。
主要好处:
- 🍄
在 NGINX 配置层自动化证书签发与续期,减少脚本与 Cron 的复杂度。 - 🍄
降低对外部工具(Certbot、acme.sh)的依赖,缩小攻击面与运维边界。 - 🍄
原生实现提升平台可移植性——不同 Linux 发行版或容器环境中更加一致。 - 🍄
结合 NGINX 的运行时变量(如 $acme_certificate
),可以实现动态证书注入与缓存管理。
二、核心概念速览
ACME 是什么?
ACME 是一套标准协议,用于自动化证书的申请、验证、签发与续期。主要挑战类型包括 HTTP-01、DNS-01、TLS-ALPN(ACMEv2 扩展支持通配符与更多验证方式)。
NGINX 预览版支持:
当前 ngx_http_acme_module
预览实现仅支持 HTTP-01 挑战(即通过 HTTP 服务响应 CA 的验证请求),未来计划支持 TLS-ALPN 与 DNS-01。
关键 NGINX 变量与指令:
- 🍄
acme_issuer <name>
:声明证书颁发器(CA)的 directory URI 与状态路径。 - 🍄
acme_shared_zone
:可选的共享内存区域,用于存放证书、私钥与挑战状态。 - 🍄
acme_certificate <issuer>
:在 server 块中启用自动签发/续期。 - 🍄
运行时变量: $acme_certificate
,$acme_certificate_key
(用于ssl_certificate
/ssl_certificate_key
)。
三、配置详解与示例
下面给出从声明 issuer,到挑战配置,再到自动签发的完整示例与运维建议——可复制到 NGINX 配置中进行测试。
1. 声明 ACME 发行器
acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
# contact admin@example.test;
state_path /var/cache/nginx/acme-letsencrypt;
accept_terms_of_service;
}
建议: state_path
目录应设置严格权限(例如 chown root:nginx
、chmod 700
),并纳入备份与灾备策略。
2. 分配共享内存
acme_shared_zone zone=acme_shared:1M;
默认 256K,生产环境建议根据证书数量和并发挑战量适当放大(示例中用 1M)。
3. 配置 HTTP-01 挑战的监听
server {
listen 80;
server_name example.com www.example.com;
location / {
# 保持简单返回,模块会接管特定 challenge 路径
return 404;
}
}
注意: HTTP-01 必须在端口 80 上被访问到;如果使用负载均衡或 CDN,请确保挑战请求能直接到达 NGINX 实例或将挑战路径(.well-known/acme-challenge/
)正确路由至后端。
4. 在 HTTPS server 中启用自动证书(acme_certificate)
server {
listen 443 ssl;
server_name example.com www.example.com;
acme_certificate letsencrypt;
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
ssl_certificate_cache max=10;
}
兼容性说明: 预览版对 server_name
的形式有限制:通配符和正则表达式可能不受支持,请使用明确或子域名列表。
四、典型迁移场景与实践建议(从 Certbot 到 NGINX 原生 ACME)
许多团队已有 Certbot / acme.sh 的既有流水线。迁移到 NGINX 原生 ACME 的流程建议如下:
-
并行运行与验证:在测试环境或小流量域名上并行启用 ngx_http_acme_module
,观察签发与续期日志。 -
证书证明与回滚机制:保留现有 Certbot 的证书作为回滚方案,确保在模块异常时可快速切换。 -
日志与监控:为模块生命周期事件(签发成功/失败、挑战失败、过期提醒)配置告警。 -
备份 state_path
:定期备份 NGINX 的state_path
(加密存储),以避免密钥丢失。 -
CDN / 负载均衡注意事项:如果使用 CDN(如 Cloudflare)或全局负载均衡器,请确认挑战路径不会被缓存或拦截,或使用 DNS-01(未来支持)替代 HTTP-01。
(以上实践建议包含百度与 Google 常见长尾搜索意图词:如“Certbot 迁移 NGINX 原生 ACME”、“在 NGINX 中自动续期 TLS 证书 实践”等)
五、安全、权限与合规建议
- 🍄
最小权限与目录保护: state_path
与任何证书临时文件应仅对 NGINX 进程可读写,禁止对外开放。 - 🍄
密钥生命周期管理: 定期审计私钥访问记录,必要时采用硬件安全模块(HSM)或受管的密钥管理服务。 - 🍄
透明度与合规: 对于合规要求严格的行业(金融、医疗),评估是否需要额外的证书策略(例如更短生命周期或多重签发流程)。 - 🍄
运维知识共享: 在团队文档中记录自动签发失败的常见原因、恢复步骤与联系人,提升组织的经验共享(Experience / E)。
六、常见问题(FAQ
Q1:当前支持通配符证书吗?
A:预览版主要支持 HTTP-01 验证,通配符证书通常需要 DNS-01 验证,因此当前预览版不支持通配符。请关注后续版本更新与 GitHub Issue 跟踪。
Q2:如何保障挑战请求能到达 NGINX?
A:确保端口 80 对外可访问或在负载均衡器/CDN中为 .well-known/acme-challenge/
路径做直通规则;避免缓存与重写拦截挑战请求。
Q3:模块会在内存中存储私钥吗?是否安全?
A:模块使用 acme_shared_zone
存储证书与挑战数据;请通过文件权限、进程隔离与备份策略保证安全性。
Q4:如何迁移现有 Certbot 证书到 NGINX 模块?
A:先并行测试,验证模块签发流程;制定回滚计划与证书备份;迁移完成后移除旧脚本并持续监控。
Q5:若签发失败,如何排查?
A:检查 NGINX 日志(error.log)、挑战路径访问日志、ACME CA 返回的错误信息,确认端口 80 路由、DNS 解析与 server_name 配置正确。