如何使用acme-dns-certbot在Ubuntu 18.04上通过DNS验证获取Let’s Encrypt证书

作者选择了COVID-19救助基金作为写作为捐赠计划中接收捐赠的对象。

简介

大部分的Let’s Encrypt证书是通过HTTP验证来发行的,这使得证书容易安装在单一服务器上。然而,HTTP验证并不总是适合为负载均衡的网站发行证书,也不能用来发行通配符证书

DNS验证允许通过DNS记录来验证证书发行请求,而不是通过HTTP提供内容。这意味着可以为位于负载均衡器后面的多个Web服务器集群或无法直接通过互联网访问的系统同时发行证书,通配符证书也支持通过DNS验证。

acme-dns-certbot工具用于将Certbot与第三方DNS服务器连接,当您请求证书时,可以通过API自动设置证书验证记录。这样做的好处是,您不需要直接将Certbot与DNS提供商帐户集成,也不需要为其提供对完整DNS配置的无限制访问权限,这有助于提高安全性。

使用委派的DNS区域可以将证书验证记录的查询重定向到第三方DNS服务,因此一旦完成初始设置,您可以请求任意数量的证书而无需执行任何手动验证操作。

acme-dns-certbot的另一个关键优点是,它可以用于为可能在负载均衡器后运行的单个服务器或者其他无法通过HTTP直接访问的服务器颁发证书。在这些情况下,传统的HTTP证书验证无法使用,除非您在每个服务器上设置验证文件。如果您想为无法通过互联网访问的服务器(如内部系统或者暂存环境)颁发证书,acme-dns-certbot工具也非常有用。

在本教程中,您将使用acme-dns-certbot钩子来为Certbot发放使用DNS验证的Let’s Encrypt证书。

先决条件

要完成本教程,您需要:

  • 一台按照使用Ubuntu 18.04进行初始服务器设置搭建的Ubuntu 18.04服务器,包括一个具有sudo权限的非root用户。

  • 一个您可以获取TLS证书的域名,包括添加DNS记录的能力。在本文档的特定示例中,我们将使用your-domainsubdomain.your-domain,以及*.your-domain作为通配符证书。如果需要,这可以调整为其他域名、子域名或通配符。

准备好这些后,以您的非root用户登录服务器开始操作。

步骤1 — 安装 Certbot

在本步骤中,您将安装 Certbot,这是一个用于颁发和管理 Let’s Encrypt 证书的程序。

Certbot 可在官方 Ubuntu Apt 仓库中找到,然而,建议使用由 Certbot 开发者维护的仓库,因为这样可以确保软件版本是最新的。

首先,添加 Certbot 仓库:

sudo apt-add-repository ppa:certbot/certbot

您需要按下 ENTER 键以接受提示并将新仓库添加到您的系统中。

接下来,安装 Certbot 包:

sudo apt install certbot

安装完成后,您可以检查 Certbot 是否已成功安装:

certbot --version

这将输出类似以下内容:

Output
certbot 0.31.0

在本步骤中,您已安装了 Certbot。接下来,您将下载并安装 acme-dns-certbot 钩子。

步骤2 — 安装 acme-dns-certbot

既然已经安装了基础的 Certbot 程序,您可以下载并安装 acme-dns-certbot,这将允许 Certbot 以 DNS 验证模式运行。

首先,下载脚本的副本:

注意: 作为一个最佳实践,请确保在运行此Github仓库中的脚本之前,先审阅该仓库和脚本。您还可以首先克隆这个仓库,然后使用acme-dns-certbot.py脚本。这个克隆提供了一层额外的安全保护,确保脚本处于我们的控制之下,并且不易受到未经验证的更改。

wget https://github.com/joohoi/acme-dns-certbot-joohoi/raw/master/acme-dns-auth.py

下载完成后,将脚本标记为可执行文件:

chmod +x acme-dns-auth.py

然后,使用您喜欢的文本编辑器编辑文件,并调整第一行以强制其使用Python 3:

nano acme-dns-auth.py

在第一行的末尾添加一个3

acme-dns-certbot.py
#!/usr/bin/env python3
. . .

这样做是为了确保脚本使用最新支持的Python 3版本,而不是遗留的Python 2版本。

完成后,保存并关闭文件。

最后,将脚本移动到Certbot Let’s Encrypt目录中,以便Certbot可以加载它:

sudo mv acme-dns-auth.py /etc/letsencrypt/

在这一步中,您下载并安装了acme-dns-certbot钩子。接下来,您可以开始设置过程,并朝着发行您的第一个证书努力。

第3步 — 设置acme-dns-certbot

为了开始使用acme-dns-certbot,您需要完成一个初始设置过程并至少发行一个证书。

首先运行Certbot以强制它使用DNS验证发行证书。这将运行acme-dns-certbot脚本并触发初始设置过程:

sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.your-domain -d your-domain

您使用--manual参数来禁用Certbot的所有自动化集成功能。在这种情况下,您只是发行一个原始证书,而不是自动将其安装在服务上。

您通过--manual-auth-hook参数配置Certbot使用acme-dns-certbot钩子。您运行--preferred-challenges参数,使Certbot优先考虑DNS验证。

您还必须告诉Certbot在尝试验证证书之前暂停,您使用--debug-challenges参数来实现。这是为了让您有时间设置DNS CNAME记录(稍后在本步骤中介绍),这是acme-dns-certbot所必需的。没有--debug-challenges参数,Certbot不会暂停,所以您不会有时间进行所需的DNS更改。

请记得使用-d参数替换您希望使用的每个域名。如果您需要颁发通配符证书,请确保将星号(*)用反斜杠(\)转义。

在按照标准的Certbot步骤操作后,您最终会看到类似于以下的消息:

Output
... Output from acme-dns-auth.py: Please add the following CNAME record to your main DNS zone: _acme-challenge.your-domain CNAME a15ce5b2-f170-4c91-97bf-09a5764a88f6.auth.acme-dns.io. Waiting for verification... ...

您需要向您的域的DNS配置中添加所需的CNAME记录。这将把_acme-challenge子域的控制权委托给ACME DNS服务,这将允许acme-dns-certbot设置所需的DNS记录以验证证书请求。

如果您使用DigitalOcean作为DNS提供商,您可以在控制面板中设置DNS记录:

建议将TTL(生存时间)设置为大约300秒,以帮助确保记录的任何更改都能快速传播。

配置完DNS记录后,返回Certbot并按ENTER键以验证证书请求并完成颁发过程。

这将需要几秒钟,然后您会看到一条确认证书已颁发的消息:

Output
... Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your-domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your-domain/privkey.pem ...

您首次运行acme-dns-certbot,设置了所需的DNS记录,并成功颁发了证书。接下来,您将设置证书的自动续签。

第4步 – 使用acme-dns-certbot

在这一最后步骤中,您将使用acme-dns-certbot来颁发更多证书和续签现有证书。

首先,既然您已经成功使用acme-dns-certbot颁发了至少一个证书,那么您可以继续为相同的DNS名称颁发证书,而无需添加另一个DNS CNAME 记录。然而,如果您希望为不同的子域或全新的域名获取证书,系统将提示您添加另一个CNAME记录。

例如,您可以尝试颁发另一个独立的通配符证书,而无需再次进行验证:

sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d \*.your-domain

但是,如果您尝试为子域颁发证书,系统将提示您为子域添加一个CNAME记录:

sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges -d subdomain.your-domain

这将显示一个与第3步中您执行的初始设置类似的输出:

Output
... Please add the following CNAME record to your main DNS zone: _acme-challenge.subdomain.your-domain CNAME 8450fb54-8e01-4bfe-961a-424befd05088.auth.acme-dns.io. Waiting for verification... ...

现在您已经能够使用acme-dns-certbot来颁发证书,考虑证书续签过程也很重要。

当您的证书即将到期时,Certbot可以自动为您续签:

sudo certbot renew

证书续签过程可以无需用户干预从开始到结束,并且会记住您在初始设置时指定的所有配置选项。

为了在不等到过期日期的情况下测试这个功能是否正常工作,您可以触发一次模拟运行。这将模拟续签过程,而不会对您的配置做出任何实际更改。

您可以使用标准的renew命令加上--dry-run参数来触发一次模拟运行:

sudo certbot renew --dry-run

这将输出类似于以下内容的信息,从而让您确信续签过程正在正确运行:

Output
... Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator manual, Installer None Renewing an existing certificate Performing the following challenges: dns-01 challenge for your-domain dns-01 challenge for your-domain Waiting for verification... Cleaning up challenges ...

在这个最后步骤中,您发布了另一个证书,并在Certbot中测试了自动续签过程。

结论

在本文中,您使用acme-dns-certbot设置了Certbot,以便使用DNS验证发布证书。这解锁了使用通配符证书的可能性,以及管理可能位于负载均衡器后面的多个不同web服务器。

请确保关注acme-dns-certbot仓库中脚本的任何更新,因为始终建议运行最新支持的版本。

如果您想了解更多关于acme-dns-certbot的信息,您可能希望查看acme-dns项目的文档,该项目是acme-dns-certbot的服务器端部分:

Acme-dns 软件也可以自行托管,如果您在高安全性或复杂环境中运行,这可能是有益的。

另外,您可以通过查看官方 RFC 文档中相关章节的技术细节来深入了解 ACME DNS 验证的工作原理:

Source:
https://www.digitalocean.com/community/tutorials/how-to-acquire-a-let-s-encrypt-certificate-using-dns-validation-with-acme-dns-certbot-on-ubuntu-18-04