目录

NGINX ACME 模块使用指南

ngx_http_acme_module 是一个由 NGINX 官方(F5, Inc.)开发的基于 Rust 的动态模块,用于实现 ACMEv2 协议(RFC 8555)的自动化证书管理。它支持 HTTP-01 和 TLS-ALPN-01 验证方式。

1. 模块加载

由于该模块是作为动态模块编译的,必须在 nginx.conf 的最顶部(全局块)加载:

load_module modules/ngx_http_acme_module.so;

2. 基础配置示例

以下是一个使用 Let’s Encrypt 获取证书并在 443 端口使用的完整示例:

# 加载模块
load_module modules/ngx_http_acme_module.so;

events {
    worker_connections 1024;
}

http {
    # 必须配置解析器以解析 ACME 服务器域名
    # 使用 Google 或 Cloudflare 的公共 DNS,或者使用 Docker 内部 DNS (127.0.0.11)
    resolver 8.8.8.8 1.1.1.1 valid=300s;
    resolver_timeout 5s;

    # 【重要】如果是在 Docker 内部,也可以尝试使用 Docker 的内置解析器
    # resolver 127.0.0.11 ipv6=off;

    # 定义共享内存区域,用于存储证书和状态(建议 1M 或更多)
    acme_shared_zone zone=ngx_acme_shared:1M;

    # 定义 ACME 发行者
    acme_issuer letsencrypt {
        uri https://acme-v02.api.letsencrypt.org/directory;
        state_path /var/cache/nginx/acme_letsencrypt;
        accept_terms_of_service;
        contact mailto:admin@example.com;
    }

    server {
        listen 80;
        server_name example.com;

        # HTTP-01 验证需要监听 80 端口,模块会自动处理 /.well-known/acme-challenge/
        location / {
            return 301 https://$host$request_uri;
        }
    }

    server {
        listen 443 ssl;
        server_name example.com;

        # 关联发行者并请求证书
        acme_certificate letsencrypt;

        # 使用模块提供的嵌入式变量加载证书和密钥
        ssl_certificate     $acme_certificate;
        ssl_certificate_key $acme_certificate_key;

        # 推荐:启用证书缓存以提高性能
        ssl_certificate_cache max=10;

        location / {
            root /usr/share/nginx/html;
        }
    }
}

3. 指令详解

acme_issuer

  • 上下文: http
  • 作用: 定义一个证书发行者配置块。
  • 子指令:
    • uri: ACME 服务器的目录 URL(必须)。
    • account_key: 指定账户私钥。格式为算法(ecdsa:256/rsa:2048)或现有密钥路径。默认为 ecdsa:256
    • challenge: 验证方式。可选 http-01 (默认) 或 tls-alpn-01
    • state_path: 证书和账户数据在磁盘上的持久化路径。
    • contact: 联系方式,通常为 mailto:email@address
    • accept_terms_of_service: 自动同意服务条款。
    • external_account_key: 配置外部账户绑定 (EAB),用于 ZeroSSL 或 Google Trust Services 等。

acme_certificate

  • 上下文: server
  • 用法: acme_certificate issuer_name [identifiers...];
  • 作用: 为当前虚拟主机请求证书。如果不指定标识符,将自动使用 server_name 指令中的域名。

acme_shared_zone

  • 上下文: http
  • 用法: acme_shared_zone zone=name:size;
  • 作用: 分配共享内存以在所有工作进程间同步证书数据。

4. 高级用法

TLS-ALPN-01 验证

如果您无法开启 80 端口,可以使用 TLS-ALPN-01 方式(必须在 443 端口进行):

acme_issuer cloud_issuer {
    uri https://...;
    challenge tls-alpn-01;
    state_path /etc/nginx/acme;
}

server {
    listen 443 ssl;
    server_name example.com;
    acme_certificate cloud_issuer;
    ...
}

嵌入式变量

模块提供了两个只读变量,直接用于 ssl_certificate 系列指令:

  • $acme_certificate: 获取当前 server 块签发的证书内容(PEM 格式)。
  • $acme_certificate_key: 获取对应的私钥内容。

5. 注意事项

  1. 权限: 确保 NGINX 工作进程对 state_path 目录具有读写权限。
  2. 限速: 第一次启动时,模块会发起注册和签发请求。如果域名过多,请注意 ACME 服务器的速率限制。
  3. 域名解析: 必须配置 resolver 指令,否则模块无法连接到 ACME 发行者。
  4. IP 证书: 该模块支持申请 IP 证书(RFC 8738),只需将 IP 放入 server_nameacme_certificate 参数中。

模块仓库:https://github.com/nginx/nginx-acme
官方文档:http://nginx.org/en/docs/http/ngx_http_acme_module.html
详细教程:https://forum.idev.top/d/1335