<!-- review: finished -->

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

# ACME 配置

Angie 中的 [ACME](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#http-acme) 模块使用 [ACME 协议](https://datatracker.ietf.org/doc/html/rfc8555) 实现自动证书获取。ACME 协议支持
多种域名验证方法(也称为"验证");本模块实现了 [HTTP 验证](#acme-config-http)、
[DNS 验证](#acme-config-dns)、[ALPN 验证](#acme-config-alpn) 以及通过自定义外部服务进行的 [基于钩子的验证](#acme-config-hooks)。

<a id="configuration-steps"></a>

## 配置步骤

在配置中启用证书请求的常规步骤:

- **配置 ACME 客户端**:在 `http` 块中使用 [acme_client](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-client) 指令,
  指定唯一的客户端名称和其他参数。可以配置多个 ACME 客户端。
- **指定请求证书的域名**:将为所有 `server` 块中 [server_name](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#server-name)
  指令列出的所有域名颁发单个证书,这些块使用指向同一 ACME 客户端的 [acme](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#id4) 指令。
- **设置请求处理和 ACME 回调**:这是验证域名所有权所必需的。设置取决于所选的域名验证方法:

  | 方法                           | 用户要求                                                                                                                                                                                                                  | 多域名   | 通配符域名   |
  |------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|---------|
  | [HTTP 验证](#acme-config-http) | 在 Angie 服务器上开放端口 80(或 [acme_http_port](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-http-port) 中指定的端口)<br/>以接受传入连接。                                                             | ✔     |         |
  | [DNS 验证](#acme-config-dns)   | 在 Angie 服务器上开放端口 53(或 [acme_dns_port](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-dns-port) 中指定的端口)<br/>以接受传入连接。<br/><br/>为 `_acme-challenge.` 子域设置 NS 记录,<br/>指向您的 Angie 服务器。 | ✔     | ✔       |
  | [ALPN 验证](#acme-config-alpn) | 在 Angie 服务器上开放端口 443(或您的服务器使用的 TLS 端口)<br/>以接受传入连接。                                                                                                                                                                   | ✔     |         |
  | [钩子验证](#acme-config-hooks)   | 创建一个外部服务(脚本或应用程序),<br/>可以根据 Angie 的请求更新 DNS 记录<br/>或通过 Web 服务器提供特殊响应。                                                                                                                                                 | ✔     | ✔       |
- **使用获取的证书和密钥配置 SSL**:该模块将证书和密钥作为 [嵌入式变量](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#http-acme-variables)
  提供,可在 [配置](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile) 中使用以填充 [ssl_certificate](https://cn.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-certificate) 和 [ssl_certificate_key](https://cn.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-certificate-key)。

  有关 SSL 设置说明,请参阅 [SSL配置](https://cn.angie.software//angie/docs/configuration/ssl.md#ssl-config)。

<a id="acme-config-details"></a>

## 实现细节

客户端密钥和证书以 [PEM 编码](https://datatracker.ietf.org/doc/html/rfc7468) 存储在由 `--http-acme-client-path`
[构建选项](https://cn.angie.software//angie/docs/installation/sourcebuild.md#configure) 指定的目录的子目录中:

```console
$ ls /var/lib/angie/acme/example/

  account.key  certificate.pem  private.key
```

ACME 客户端需要在 CA 服务器上拥有一个账户。为了创建和管理此账户,
客户端使用私钥(`account.key`)。如果不存在密钥,则在启动时生成。
然后客户端使用此密钥向服务器注册账户。

#### NOTE
如果您已经拥有账户密钥,请在启动前将其放置在客户端的子目录中以重用该账户。
或者,使用 [acme_client](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-client) 中的 `account_key` 参数指定密钥文件。

ACME 客户端还使用单独的密钥(`private.key`)用于证书签名请求(CSR)。
如果需要,此证书密钥会在启动时自动创建。

启动时,如果证书不存在,客户端会请求证书,签名并向 CA 服务器发送包含其管理的所有域名的 CSR。
服务器使用 [HTTP](#acme-config-http) 或 [DNS 验证](#acme-config-dns) 验证域名所有权,
并颁发证书,客户端将其保存在本地(`certificate.pem`)。

如前所述,单个证书涵盖同一 ACME 客户端管理的所有域名,可能产生多域名证书。
证书涵盖的所有名称列表可以在获取的证书的 Subject Alternative Name (SAN)部分中找到。
要从命令行检查:

```console
$ openssl x509 -in certificate.pem -noout -text | grep -A5 "Subject Alternative Name"
```

当证书即将过期或域名列表发生变化时,客户端会签名并向 CA 服务器发送另一个 CSR。
服务器重新验证所有权并颁发新证书,客户端将其安装在本地,替换之前的证书。

在 [配置](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile) 中,获取的证书及其对应的密钥可通过前缀变量
[$acme_cert_<名称>](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#v-acme-cert-name) 和 [$acme_cert_key_<名称>](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#v-acme-cert-key-name) 获得。它们的值是相应文件的内容,
应与 [ssl_certificate](https://cn.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-certificate) 和 [ssl_certificate_key](https://cn.angie.software//angie/docs/configuration/modules/http/http_ssl.md#ssl-certificate-key) 指令一起使用:

```nginx
server {

    listen 443 ssl;

    server_name example.com www.example.com;
    acme example;

    ssl_certificate $acme_cert_example;
    ssl_certificate_key $acme_cert_key_example;
}
```

<a id="acme-config-domain-collection"></a>

## 域名收集与证书使用

[acme](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#id4) 指令仅用于收集证书请求的域名,
并不控制证书可在何处使用:
任何 `server` 块都可以通过
[$acme_cert_<name>](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#v-acme-cert-name) 变量
引用获取的证书,
无论该块是否包含 `acme` 指令。

例如,如果您有一个已涵盖所有子域名的通配符 `server` 块,
那么针对特定子域名的额外 `server` 块
不需要 `acme` 指令:

```nginx
http {

    resolver 127.0.0.53;

    acme_client example https://acme-v02.api.letsencrypt.org/directory
        challenge=dns;

    # This block lists the domains for the certificate request
    server {

        listen 443 ssl;

        server_name example.com *.example.com;
        acme example;

        ssl_certificate $acme_cert_example;
        ssl_certificate_key $acme_cert_key_example;
    }

    # This block uses the same certificate but does not
    # add its server_name to the certificate request
    server {

        listen 443 ssl;

        server_name app.example.com;

        ssl_certificate $acme_cert_example;
        ssl_certificate_key $acme_cert_key_example;
    }
}
```

<a id="acme-config-explicit-domains"></a>

### 显式域名列表

为了精确控制证书中的域名集合,
而不依赖于从所有 `server` 块自动收集,
可以创建一个专用的 `server` 块,
其中仅包含 [server_name](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#server-name) 和 [acme](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#id4) 指令。
为防止此块处理实际流量,
可以将其绑定到 Unix 域套接字:

```nginx
# Dedicated block that defines the certificate's domain list
server {

    listen unix:/tmp/acme_example.sock;

    server_name example.com www.example.com;
    acme example;
}
```

其他 `server` 块随后可通过
[$acme_cert_<name>](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#v-acme-cert-name) 变量
使用该证书,而不会影响请求的域名。

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

## HTTP 验证

验证是自动处理的。该过程涉及 ACME 服务器在收到请求后,\`通过 HTTP 检索特殊令牌文件
<[https://datatracker.ietf.org/doc/html/rfc8555#section-8.3](https://datatracker.ietf.org/doc/html/rfc8555#section-8.3)>\`_,
从客户端地址 `/.well-known/acme-challenge/<TOKEN>` 获取。我们的 ACME 模块
会自动跟踪和处理此类请求。当收到包含正确内容的预期响应时,ACME 服务器确认该域名属于客户端。

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

### 配置示例

在此示例中,名为 `example` 的 ACME 客户端管理 `example.com` 和
`www.example.com` 的证书(注意 HTTP 验证不支持通配符证书):

```nginx
http {

    resolver 127.0.0.53; # 'acme_client' 指令所需

    acme_client example https://acme-v02.api.letsencrypt.org/directory;

    server {

        listen 80; # 如果没有服务器监听 HTTP 挑战端口,则可选
                   # (参见 'acme_http_port' 指令)

        listen 443 ssl;

        server_name example.com www.example.com;
        acme example;

        ssl_certificate $acme_cert_example;
        ssl_certificate_key $acme_cert_key_example;
    }
}
```

如前所述,必须开放端口 80 以处理 HTTP ACME 调用。
如果没有配置服务器监听 HTTP 挑战端口,
该模块会在端口 80(或 [acme_http_port](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-http-port) 中设置的端口)上创建专用监听器。不需要单独的 [server](https://cn.angie.software//angie/docs/configuration/modules/http/index.md#server) 块。

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

## DNS 验证

验证是自动处理的。在处理证书请求时,ACME 服务器会对被验证域名的 `_acme-challenge.` 子域执行 [特殊的 DNS 查询](https://datatracker.ietf.org/doc/html/rfc8555#section-8.4)。一旦收到预期的响应,ACME 服务器确认该域名属于客户端。

我们的 ACME 模块会自动跟踪和处理此类请求,前提是您的 DNS 记录已正确配置,将 Angie 服务器指定为 `_acme-challenge.` 子域的权威名称服务器。

#### NOTE
Angie 服务器必须能够通过互联网在
UDP 53 端口(或 [acme_dns_port](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-dns-port) 中指定的端口)上访问。
如果服务器位于防火墙后,
请确保该端口对入站连接开放。

例如,要使用 IP 地址为 `93.184.215.14` 的 Angie 服务器验证域名 `example.com`,您的域名 DNS 配置应包含以下记录:

```none
_acme-challenge.example.com. 60    IN      NS       ns.example.com.
             ns.example.com. 60    IN       A       93.184.215.14
```

此配置将 `_acme-challenge.example.com` 的 DNS 解析委托给 `ns.example.com`,并通过将 `ns.example.com` 映射到 IP 地址(`93.184.215.14`)来确保其可访问。

#### WARNING
NS 记录的传播可能需要几分钟到 48 小时不等,具体取决于 TTL 和 DNS 提供商。建议在请求证书之前验证配置是否正确。

要验证 DNS 是否配置正确,您可以使用以下命令:

```console
$ dig NS _acme-challenge.example.com +short  # 检查 _acme-challenge 子域的 NS 记录

  ns.example.com.

$ dig A ns.example.com +short  # 检查名称服务器的 A 记录

  93.184.215.14

$ nc -zv 93.184.215.14 53  # 检查 DNS 服务器在端口 53 上的可访问性
```

此方法允许请求通配符证书,例如,在 Subject Alternative Name (SAN)部分包含 `*.example.com` 条目的证书。要明确请求子域的证书,例如 `www.example.com`,您必须使用上述方法单独验证该子域。

#### WARNING
此场景的适用性在很大程度上取决于您的 DNS 提供商提供的功能;某些提供商不允许此类配置。

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

### 配置示例

总体而言,配置与上一节中的示例类似。不需要 HTTP 特定的设置;只需为 [acme_client](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-client) 指令设置 `challenge=dns` 即可。

在此示例中,名为 `example` 的 ACME 客户端管理 `example.com` 和 `*.example.com` 的证书:

```nginx
http {

    resolver 127.0.0.53;

    acme_client example https://acme-v02.api.letsencrypt.org/directory
        challenge=dns;

    server {

        server_name example.com *.example.com;
        acme example;

        ssl_certificate $acme_cert_example;
        ssl_certificate_key $acme_cert_key_example;
    }
}
```

<a id="acme-config-alpn"></a>

## ALPN 验证

验证是自动处理的。ACME 服务器使用 TLS 连接并通过 ALPN 请求 `acme-tls/1` 协议。该模块为验证请求提供临时证书。

要启用此方法,请在 [acme_client](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-client) 指令中配置 `challenge=alpn`,并确保您的 TLS 监听器在端口 443(或用于 TLS 的端口)上可访问。

<a id="acme-config-hooks"></a>

## 基于钩子的验证

与之前的方法不同,此验证需要额外的工作。ACME 服务器执行标准的 [HTTP 验证](#acme-config-http) 或 [DNS 验证](#acme-config-dns),但它不是直接与 Angie 服务器交互,而是通过钩子调用([acme_hook](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-hook))与 Angie 服务器管理的外部服务通信。该服务配置一个单独的 DNS 或 HTTP 服务器,ACME 服务器向其发送请求。

一旦 ACME 服务器从配置的 DNS 或 HTTP 服务器收到预期的响应,它就会确认域名所有权。

当证书签发或续订需要进行域名验证时,
Angie 会向包含 [acme_hook](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-hook) 指令的命名 `location`
生成一个内部请求。
该请求的处理方式完全取决于同一 `location`
中配置的其他指令。

通用模式如下:

1. 创建一个带有 [acme_hook](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-hook) 指令的命名 `location`。
2. 在同一 `location` 中,
   使用适合您环境的模块配置请求处理程序:
   FastCGI 使用 [fastcgi_pass](https://cn.angie.software//angie/docs/configuration/modules/http/http_fastcgi.md#fastcgi-pass),
   HTTP 使用 [proxy_pass](https://cn.angie.software//angie/docs/configuration/modules/http/http_proxy.md#proxy-pass),
   CGI 脚本使用 `cgi`,等等。
3. 使用处理程序支持的机制,
   将 ACME [变量](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#http-acme-variables) 传递给处理程序,
   例如 FastCGI 使用 `fastcgi_param`,
   CGI 使用 `cgi_set_var`。

处理程序必须返回 `2xx` 状态码,
可以通过 `Status` 头发送。
任何其他状态码都被视为错误,
证书续订将停止。
处理程序的输出将被忽略。

<a id="acme-config-hooks-minimal-configuration"></a>

### 最小配置

无论使用哪种处理程序,
钩子 `location` 都遵循以下结构:

```nginx
location @acme_hook {

    acme_hook example;

    # Handler directive (fastcgi_pass, proxy_pass, cgi on, ...)
    # Pass ACME variables using the handler's mechanism:
    #   ACME_HOOK       — $acme_hook_name ("add" or "remove")
    #   ACME_CHALLENGE  — $acme_hook_challenge ("dns" or "http")
    #   ACME_DOMAIN     — $acme_hook_domain
    #   ACME_TOKEN      — $acme_hook_token
    #   ACME_KEYAUTH    — $acme_hook_keyauth
}
```

对于 DNS 验证,处理程序必须使用 `ACME_HOOK`
来确定操作:
当其值为 `add` 时,
为 `_acme-challenge.*ACME_DOMAIN*` 创建一条
值为 `ACME_KEYAUTH` 的 TXT 记录;
当其值为 `remove` 时,删除该记录。

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

### FastCGI 示例

在此示例中,:ref:acme_client 指令通过 `challenge=dns` 参数
将 ACME 客户端 `example` 配置为使用 DNS 验证。

`server` 块适用于 `example.com` 的所有子域(例如 `*.example.com`),
并通过 [acme](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#id4) 指令使用 ACME 客户端 `example` 来管理证书。

一个命名的 `location` 块负责处理钩子调用。
[acme_hook](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-hook) 指令将其与 ACME 客户端 `example` 关联起来。
钩子请求通过 [fastcgi_pass](https://cn.angie.software//angie/docs/configuration/modules/http/http_fastcgi.md#fastcgi-pass)
发送到运行在 9000 端口上的本地 FastCGI 服务器。
`fastcgi_param` 指令将 ACME 变量
传递给外部服务。

```nginx
acme_client example https://acme-v02.api.letsencrypt.org/directory
    challenge=dns;

server {

    listen 80;

    server_name *.example.com;

    acme example;

    ssl_certificate $acme_cert_example;
    ssl_certificate_key $acme_cert_key_example;

    location @acme_hook_location {

        acme_hook example;

        fastcgi_pass localhost:9000;

        fastcgi_param ACME_CLIENT $acme_hook_client;
        fastcgi_param ACME_HOOK $acme_hook_name;
        fastcgi_param ACME_CHALLENGE $acme_hook_challenge;
        fastcgi_param ACME_DOMAIN $acme_hook_domain;
        fastcgi_param ACME_TOKEN $acme_hook_token;
        fastcgi_param ACME_KEYAUTH $acme_hook_keyauth;

        include fastcgi.conf;
    }
}
```

以下 Perl 脚本演示了相应的外部 FastCGI 服务:

```perl
#!/usr/bin/perl

use strict; use warnings;

use FCGI;

my $socket = FCGI::OpenSocket(":9000", 5);
my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, $socket);

while ($request->Accept() >= 0) {
    print "\r\n";

    my $client =    $ENV{ACME_CLIENT};
    my $hook =      $ENV{ACME_HOOK};
    my $challenge = $ENV{ACME_CHALLENGE};
    my $domain =    $ENV{ACME_DOMAIN};
    my $token =     $ENV{ACME_TOKEN};
    my $keyauth =   $ENV{ACME_KEYAUTH};

    if ($hook eq 'add') {

        DNS_set_TXT_record("_acme-challenge.$domain.", $keyauth);

    } elsif ($hook eq 'remove') {

        DNS_clear_TXT_record("_acme-challenge.$domain.");
    }
};

FCGI::CloseSocket($socket);
```

这里,:samp:DNS_set_TXT_record() 和 `DNS_clear_TXT_record()` 是假定在外部 DNS 服务器的配置中添加和删除 TXT 记录的函数,ACME 服务器会查询该 DNS 服务器。这些记录必须包含 Angie 服务器提供的数据,以允许外部 DNS 服务器成功通过验证,类似于 [DNS 验证](#acme-config-dns) 中描述的过程。此类函数的实现细节超出了本指南的范围;例如,参数也可以通过请求 URI 传递:

```nginx
# ...

location @acme_hook_location {

    acme_hook example uri=/acme_hook/$acme_hook_name?domain=$acme_hook_domain&key=$acme_hook_keyauth;

    fastcgi_pass localhost:9000;

    fastcgi_param REQUEST_URI $request_uri;
    fastcgi_param ACME_CLIENT $acme_hook_client;
    fastcgi_param ACME_CHALLENGE $acme_hook_challenge;
    fastcgi_param ACME_TOKEN $acme_hook_token;

    include fastcgi.conf;
}
```

### PHP-FPM 示例

另一个使用 PHP-FPM 的示例:

```nginx
location @acme_hook_location {

    acme_hook example;
    root /var/www/dns;
    fastcgi_pass unix:/run/php-fpm/php-dns.sock;
    fastcgi_index hook.php;
    fastcgi_param SCRIPT_FILENAME /var/www/dns/hook.php;
    include fastcgi_params;

    fastcgi_param ACME_CLIENT $acme_hook_client;
    fastcgi_param ACME_HOOK $acme_hook_name;
    fastcgi_param ACME_CHALLENGE $acme_hook_challenge;
    fastcgi_param ACME_DOMAIN $acme_hook_domain;
    fastcgi_param ACME_TOKEN $acme_hook_token;
    fastcgi_param ACME_KEYAUTH $acme_hook_keyauth;
}
```

```ini
[dns]
listen = /run/php-fpm/php-dns.sock
listen.mode = 0666
user = angie
group = angie
chdir = /var/www/dns
# ...
```

传递的参数可以在 PHP 中通过 `$_SERVER['...']` 访问。

<a id="acme-config-stream"></a>

## Stream 模块中的 ACME

[ACME](https://cn.angie.software//angie/docs/configuration/modules/stream/stream_acme.md#stream-acme) stream 模块可为 TCP 流量启用自动化的
证书签发和使用。
为使其正常工作,您必须首先配置其 HTTP 对应部分:
ACME 客户端必须在 `http` 上下文中声明,
并且 `stream` 块本身必须放置在配置文件中 `http` 块\*之后\*。

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

### 配置示例

默认情况下,使用 HTTP 验证模式来获取证书。
如 [HTTP 验证](#acme-config-http) 部分所述,
这需要一个监听 80 端口的 HTTP 服务器:

```nginx
# HTTP 部分
http {

    resolver 127.0.0.53;

    # 用于 stream 部分的 ACME 客户端
    acme_client example https://acme-v02.api.letsencrypt.org/directory;

    # 用于 HTTP 验证的服务器
    server {

        listen 80;
        return 444;
    }
}

# Stream 部分
stream {

    server {

        listen 12345 ssl;
        proxy_pass backend_upstream;

        ssl_certificate $acme_cert_example;
        ssl_certificate_key $acme_cert_key_example;

        server_name example.com www.example.com;
        acme example; # 引用 HTTP 部分中定义的 ACME 客户端
    }

    upstream backend_upstream {

        server 127.0.0.1:54321;
    }
}
```

您也可以使用 DNS 验证,
方法是在 [acme_client](https://cn.angie.software//angie/docs/configuration/modules/http/http_acme.md#acme-client) 指令中配置 `challenge=dns`;
在这种情况下,将不需要该服务器。

<a id="acme-config-certbot"></a>

## 从 **certbot** 迁移

如果您之前在 [从 nginx 迁移到 Angie](https://cn.angie.software//angie/docs/configuration/migration.md#migration) 之前
使用 [certbot](https://certbot.eff.org/)
从 Let's Encrypt 获取和续订 SSL 证书,
请按照以下步骤过渡到使用我们的 ACME 模块。

假设您按如下方式配置了证书:

```console
$ sudo certbot --nginx -d example.com -d www.example.com
```

此命令自动创建的配置
通常位于 `/etc/nginx/sites-available/example.conf`,
看起来类似这样:

```nginx
server {

    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {

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

    root /var/www/example;
    index index.html;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
```

在上面的示例中,需要修改高亮显示的行。
根据您的情况和偏好,使用 ACME 模块配置
[HTTP 验证](#acme-config-http)
或 [DNS 验证](#acme-config-dns)。

最终的 [Angie 配置](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)
可能如下所示:

```nginx
http {

    resolver 127.0.0.53;

    acme_client example https://acme-v02.api.letsencrypt.org/directory;

    server {

        listen 80;
        server_name example.com www.example.com;
        return 301 https://$host$request_uri;
    }

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

        root /var/www/example;
        index index.html;

        acme                 example;

        ssl_certificate      $acme_cert_example;
        ssl_certificate_key  $acme_cert_key_example;
    }
}
```

请记住在 [更改后重新加载配置](https://cn.angie.software//angie/docs/configuration/runtime.md#control-config-change):

```console
$ sudo kill -HUP $(cat /run/angie.pid)
```

一旦您验证了此配置可以正常工作,
您可以删除 **certbot** 证书
并禁用或从服务器上完全移除 certbot
(如果它不再在其他地方使用),
例如:

```console
$ sudo rm -rf /etc/letsencrypt

$ sudo systemctl stop certbot.timer
$ sudo systemctl disable certbot.timer
$ # -- 或 --
$ sudo rm /etc/cron.d/certbot

$ sudo apt remove certbot
$ # -- 或 --
$ sudo dnf remove certbot
```
