<a id="http-acme"></a>

# ACME

提供使用 [ACME 协议](https://datatracker.ietf.org/doc/html/rfc8555) 自动获取证书的功能。

在 [从源代码构建](https://cn.angie.software//angie/docs/installation/sourcebuild.md#sourcebuild) 时,默认不会构建此模块;
需要使用 [构建选项](https://cn.angie.software//angie/docs/installation/sourcebuild.md#configure) `--with-http_acme_module` 启用它。
在来自 [我们的软件仓库](https://cn.angie.software//angie/docs/installation/index.md#install-packages) 的包和镜像中,
该模块已包含在构建中。

<a id="configuration-example-4"></a>

## 配置示例

有关配置示例和设置说明,请参阅 [ACME 配置](https://cn.angie.software//angie/docs/configuration/acme.md#acme-config) 部分。

<a id="directives-4"></a>

## 指令

<a id="index-0"></a>

<a id="id4"></a>

### acme

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `acme` 名称;   |
|--------------------------------------------------------------------------------------|--------------|
| 默认值                                                                                  | —            |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | server       |

对于所有引用名为 名称 的 [ACME 客户端](#acme-client) 的 [server](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#server) 块中的 [server_name](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#server-name) 指令指定的所有域名,
将获得单个证书;
如果 `server_name` 配置更改,
证书将更新以反映这些更改。

每次 Angie 启动时,都会为所有缺少有效证书的域名请求新证书。
可能的原因包括证书已过期、
文件丢失或不可读、
证书配置发生更改等。

#### NOTE
该指令仅控制证书请求中包含的域名,
并不影响证书可在何处使用。
任何 `server` 块都可以通过
[$acme_cert_<name>](#v-acme-cert-name) 变量
引用该证书,
无论该块是否包含 `acme` 指令。
从 `server` 块中移除 `acme`
仅会将该块的 [server_name](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#server-name) 值
排除在后续的证书请求之外,
但不会阻止该块使用证书。

#### NOTE
目前,不支持使用正则表达式指定的域名,
这些域名将被忽略。

通配符域名仅在 `acme_client` 中设置了 `challenge=dns` 时才受支持。

此指令可以多次指定以加载不同类型的证书,例如 RSA 和 ECDSA:

```nginx
server {

    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate $acme_cert_rsa;
    ssl_certificate_key $acme_cert_key_rsa;

    ssl_certificate $acme_cert_ecdsa;
    ssl_certificate_key $acme_cert_key_ecdsa;

    acme rsa;
    acme ecdsa;
}
```

<a id="index-1"></a>

<a id="acme-client"></a>

### acme_client

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `acme_client` 名称 uri [`enabled=``on` | `off`] [`key_type=`类型] [`key_bits=`数字] [`email=`email] [`max_cert_size=`数字] [`renew_before_expiry=`时间] [`renew_on_load`] [`retry_after_error=`off|时间] [`challenge=``dns` | `http` | `alpn`] [`account_key=`文件];   |
|--------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 默认值                                                                                  | —                                                                                                                                                                                                                                                        |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                                                                                                                                                                                                                                                     |

定义一个全局唯一的名为 名称 的 ACME 客户端。
该名称必须对目录有效,
是一个包含变量的字符串,
并且将被视为不区分大小写。

第二个必需参数是 ACME 目录的 uri。
例如,Let's Encrypt ACME 目录的 URI [列出](https://letsencrypt.org/getting-started/)
为
[https://acme-v02.api.letsencrypt.org/directory](https://acme-v02.api.letsencrypt.org/directory)。

#### NOTE
ACME 模块会在 [client](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#client) 上下文中添加一个名为 `location @acme` 的位置,
可用于配置对 ACME 目录的请求;
默认情况下,此 `location`
包含一个带有目录 uri 的 [proxy_pass](https://cn.angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-pass) 指令,
可以向其添加来自 [代理](https://cn.angie.software//angie/docs/configuration/modules/http/http_proxy.md#http-proxy) 模块的其他设置。

为了使此指令生效,
必须在相同上下文中配置 [resolver](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#resolver)。

#### NOTE
出于测试目的,
证书颁发机构通常提供单独的测试环境。
例如,\`Let's Encrypt 的测试环境 <[https://letsencrypt.org/docs/staging-environment/](https://letsencrypt.org/docs/staging-environment/)>\`_
为
[https://acme-staging-v02.api.letsencrypt.org/directory](https://acme-staging-v02.api.letsencrypt.org/directory)。

| `enabled`             | 启用或禁用客户端证书的更新;<br/>例如,在不从配置中删除客户端的情况下临时暂停时,这很有用。<br/><br/>默认值:`on`。                                                                                                                                                                                                                                                                                                                                                                                                                                     |
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `key_type`            | 证书的私钥算法类型。<br/>有效值:`rsa`,:samp:ecdsa。<br/><br/>默认值:`ecdsa`。                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `key_bits`            | 证书密钥的位数。<br/>默认值:`ecdsa` 为 256,:samp:rsa 为 2048。                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `email`               | 用于反馈的可选电子邮件地址;<br/>在 CA 服务器上创建账户时使用。                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `max_cert_size`       | 指定新证书文件的最大允许大小(以字节为单位),<br/>以在共享内存中为新证书保留空间;<br/>请求的域名越多,需要的空间越大。<br/>此参数不限制 ACME 服务器响应的大小;<br/>请使用 [acme_max_response_size](#acme-max-response-size) 来限制响应大小。<br/><br/>如果未设置该参数,Angie 会根据配置的域名列表计算大致大小,<br/>并将其用于共享内存分配。<br/><br/>如果启动时已存在证书但其大小超过 `max_cert_size` 值,<br/>则 `max_cert_size` 值会动态增加以匹配现有证书文件的大小。<br/><br/>如果更新过程中获得的证书大小超过 `max_cert_size`,<br/>则更新过程将失败并报错。<br/><br/>默认值:自动计算。                                                                                                         |
| `renew_before_expiry` | 证书到期前应开始更新的 [时间](https://cn.angie.software//angie/docs/configuration/configfile.md#syntax)。<br/><br/>默认值:`30d`。                                                                                                                                                                                                                                                                                                                                                                                         |
| `renew_on_load`       | 指定在每次加载配置时强制更新证书。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `retry_after_error`   | 在证书获取失败时重试前等待的 [时间](https://cn.angie.software//angie/docs/configuration/configfile.md#syntax)。<br/>如果设置为 `off`,<br/>客户端不会在失败后重试获取证书。<br/><br/>默认值:`2h`。                                                                                                                                                                                                                                                                                                                                                 |
| `challenge`           | 指定 ACME 客户端的验证类型。<br/>有效值:`dns`,:samp:http,:samp:alpn。<br/><br/>`alpn` 值启用 [TLS-ALPN-01](https://datatracker.ietf.org/doc/rfc8737/) 验证,需要<br/>Angie 使用支持 ALPN 的 OpenSSL 构建<br/>(不支持 BoringSSL 或 AWS-LC 构建)。<br/><br/>默认值:`http`。                                                                                                                                                                                                                                                                        |
| `account_key`         | 指定包含 PEM 格式密钥的文件的完整路径。<br/>如果您想使用现有账户密钥而不是自动生成一个,<br/>或者需要为多个 ACME 客户端使用同一个密钥,这很有用。<br/><br/>支持的密钥类型:<br/><br/>- RSA 密钥,长度为 8 的倍数,范围从 2048 到 8192 位。<br/>- ECDSA 密钥,长度为 256、384 或 521 位。<br/><br/>指定 `account_key` 参数时,<br/>应确保密钥文件确实存在。<br/>如果文件不存在,<br/>Angie 将尝试在指定路径创建它。<br/><br/>请注意,ACME 客户端的密钥是按照它们在配置中<br/>通过 [acme_client](#acme-client)、[acme](#id4) 或 [acme_hook](#acme-hook) 指令提及的顺序创建的。<br/>因此,如果一个客户端应该使用为另一个客户端创建的密钥,<br/>那么另一个客户端必须在配置中更早出现。<br/><br/>此外,密钥仅为设置了 `enabled=on` 参数的客户端创建。 |

<a id="index-2"></a>

<a id="acme-max-response-size"></a>

### acme_max_response_size

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `acme_max_response_size` 大小;   |
|--------------------------------------------------------------------------------------|--------------------------------|
| 默认值                                                                                  | `acme_max_response_size 32k;`  |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                           |

限制 ACME 服务器响应正文的最大大小。如果响应超过此限制,请求将失败并报错。
如果您看到类似 `too big subrequest response while sending to client` 的错误,请增加该值。

<a id="index-3"></a>

<a id="acme-client-path"></a>

### acme_client_path

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `acme_client_path` 路径;   |
|--------------------------------------------------------------------------------------|--------------------------|
| 默认值                                                                                  | —                        |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                     |

覆盖用于存储证书和密钥的目录的 路径,
该路径在构建时由 [构建参数](https://cn.angie.software//angie/docs/installation/sourcebuild.md#configure) `--http-acme-client-path` 设置。

<a id="index-4"></a>

<a id="acme-dns-port"></a>

### acme_dns_port

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `acme_dns_port` 端口 | ip[:端口] | [ip6][:端口];   |
|--------------------------------------------------------------------------------------|----------------------------------------------|
| 默认值                                                                                  | `acme_dns_port 53;`                          |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                                         |

指定模块通过 UDP 处理来自 ACME 服务器的 DNS 查询所使用的端口。
端口号必须在 1 到 65535 之间。

也支持同时指定 IP 地址和可选端口。
可以使用 `ip:端口` 格式的 IPv4 地址
和 `[ip6]:端口` 格式的 IPv6 地址:

```nginx
acme_dns_port 8053;
acme_dns_port 127.0.0.1;
acme_dns_port [::1];
```

要使用 1024 或更低的端口号,
Angie 必须以 [超级用户](https://cn.angie.software//angie/docs/configuration/modules/core.md#user) 权限运行。

<a id="index-5"></a>

<a id="acme-http-port"></a>

### acme_http_port

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `acme_http_port` 端口 | ip[:端口] | [ip6][:端口];   |
|--------------------------------------------------------------------------------------|-----------------------------------------------|
| 默认值                                                                                  | `acme_http_port 80;`                          |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                                          |

指定模块用于处理 HTTP ACME 验证请求的端口。
端口号必须在 1 到 65535 之间。

也支持同时指定 IP 地址和可选端口。
可以使用 `ip:端口` 格式的 IPv4 地址
和 `[ip6]:端口` 格式的 IPv6 地址:

```nginx
acme_http_port 8080;
acme_http_port 127.0.0.1;
acme_http_port [::1];
```

如果没有服务器配置为监听指定的地址和端口,
模块会为 HTTP 验证创建专用监听器。

要使用 1024 或更低的端口号,
Angie 必须以 [超级用户](https://cn.angie.software//angie/docs/configuration/modules/core.md#user) 权限运行。

<a id="index-6"></a>

<a id="acme-hook"></a>

### acme_hook

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `acme_hook` 名称 [uri];   |
|--------------------------------------------------------------------------------------|-------------------------|
| 默认值                                                                                  | —                       |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | location                |

为由 名称 指定的 [ACME 客户端](#acme-client)
启用基于钩子的域名验证。
当证书签发或续订需要进行域名验证时,
Angie 会向放置该指令的命名 `location`
生成一个内部请求。
请求的处理方式完全取决于同一 `location`
中配置的其他指令,
例如 [fastcgi_pass](https://cn.angie.software//angie/docs/configuration/modules/http/http_fastcgi.md#fastcgi-pass)、[proxy_pass](https://cn.angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-pass),
或任何其他请求处理程序。

| 名称   | 由该钩子处理域名验证的<br/>[ACME 客户端](#acme-client) 的名称。   |
|------|-------------------------------------------------|
| uri  | 包含变量的字符串;<br/>指定钩子调用的请求 URI。<br/><br/>默认值:`/`。  |

例如,以下配置将 [hook 变量](#http-acme-variables) 的值
通过请求 URI 传递给 FastCGI 应用程序:

```nginx
acme_hook example uri=/acme_hook/$acme_hook_name?domain=$acme_hook_domain&key=$acme_hook_keyauth;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_pass ...;
```

<a id="http-acme-variables"></a>

## 内置变量

<a id="v-acme-cert-name"></a>

### `$acme_cert_<名称>`

由此 名称 的客户端获得的最后一个证书文件(如果有)的内容。

<a id="v-acme-cert-key-name"></a>

### `$acme_cert_key_<名称>`

此 名称 的客户端使用的证书密钥文件的内容。

#### NOTE
证书文件仅在 ACME 客户端获得至少一个证书后可用,
而密钥文件在启动后立即可用。

<a id="v-acme-hook-challenge"></a>

### `$acme_hook_challenge`

验证类型。可能的值:`dns`,:samp:http,:samp:alpn。

<a id="v-acme-hook-client"></a>

### `$acme_hook_client`

发起请求的 ACME 客户端的名称。

<a id="v-acme-hook-domain"></a>

### `$acme_hook_domain`

被验证的域名。
如果是通配符域名,将不带 `*.` 前缀传递。

<a id="v-acme-hook-keyauth"></a>

### `$acme_hook_keyauth`

授权字符串:

- 在 DNS 验证中,用作 TXT 记录的值,
  记录名称格式为 `_acme-challenge. + $acme_hook_domain + .`。
- 在 HTTP 验证中,此字符串应用作
  ACME 服务器请求的响应内容。

<a id="v-acme-hook-name"></a>

### `$acme_hook_name`

钩子名称。对于不同类型的验证,它可能有不同的值和含义:

| 值               | DNS 验证中的含义               | HTTP 验证中的含义                             |
|-----------------|--------------------------|-----------------------------------------|
| `add` (添加钩子)    | 需要在 DNS 配置中添加相应的 TXT 记录。 | 需要准备对相应 HTTP 请求的响应。                     |
| `remove` (移除钩子) | 可以从 DNS 配置中删除 TXT 记录。    | 此 HTTP 请求不再相关;<br/>可以删除先前创建的包含授权字符串的文件。 |

<a id="v-acme-hook-token"></a>

### `$acme_hook_token`

验证令牌。
在 HTTP 验证中,用作请求的文件名:
`/.well-known/acme-challenge/` + `$acme_hook_token`。
