比念诗还简单 —— Let's Encrypt 泛域名证书申请体验

今天 Let’s Encrypt 官方也宣布正式对 ACMEv2 和泛域名证书提供支持,想必经常折腾 SSL 证书的同学对于 Let’s Encrypt 这个致力于免费、开放以及自动化的证书颁发机构应该是很熟悉的。

之前 Let’s Encrypt 提供的证书是单域名的,因此新的子域名需要申请签发新的证书。而我一些域名下依附的 API 较多,每次改动子域名都是一套麻烦的操作,签发后再维护一大堆碎片化的证书实在是很让人头疼。

这次趁着机会,我来申请一个泛域名证书,这样今后也会方便许多。顺便我也会记录下申请的过程,方便需要的同学参考。

正如标题所说的一样,这个简单的教程不含自动续期(renew)部分,如需要自动续期可以参考一些使用 Certbot 的用例。

找个客户端

首先,按照官方所述,我们需要一个支持 ACMEv2 的客户端,这里我们就选用 acme.sh

按照 README 中的指导,我们只需要在终端中执行:

1
curl https://get.acme.sh | sh

即可完成安装。此时新建终端会话或是手动 acme.sh=~/.acme.sh/acme.sh 之后,执行 acme.sh 应该就可以看到输出的帮助信息了。

验证域名

这个最简单的道理就不用多说了吧,这里我们选用 DNS TXT 记录验证域名所有权。为了方便我准备直接手动修改 DNS 记录,不使用各提供商的 Token。

以我要申请证书的域名 bitcat.cc 为例:

1
acme.sh --issue -d "bitcat.cc" -d "*.bitcat.cc" --dns

需要同时添加裸域名及泛域名。注意要将非泛域名的域名放在前面,否则可能会遇到一些问题。

接下来终端可能会吐出如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
Multi domain='DNS:bitcat.cc,DNS:*.bitcat.cc'
Getting domain auth token for each domain
Getting webroot for domain='bitcat.cc'
Getting webroot for domain='*.bitcat.cc'
Add the following TXT record:
Domain: '_acme-challenge.bitcat.cc'
TXT value: '<ACME_CHALLENGE_STRING>'
Please be aware that you prepend _acme-challenge. before your domain
so the resulting subdomain will be: _acme-challenge.bitcat.cc
Please add the TXT records to the domains, and retry again.
Please add '--debug' or '--log' to check more details.
See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

记录下其中的 <ACME_CHALLENGE_STRING> 并前往你的 DNS 服务提供商,为主机名 _acme-challenge 添加一条 TXT 记录,内容即为上述的 <ACME_CHALLENGE_STRING>。提交后可以等待一小段时间以便让 DNS 生效。

也可以使用 dig _acme-challenge.bitcat.cc TXT 自查一下记录是否存在。

申请签发证书

由于上一步骤中我们已经尝试过申请证书签发,只是没有验证域名所有权,才去完成验证所有权这一步骤。

因此这里我们需要使用:

1
acme.sh --renew -d "bitcat.cc" -d "*.bitcat.cc" --dns

来完成「续期」(现在的这种情况也等于申请签发)操作。

然后你的终端可能会吐出以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Renew: 'bitcat.cc'
Multi domain='DNS:bitcat.cc,DNS:*.bitcat.cc'
Getting domain auth token for each domain
Verifying:bitcat.cc
Success
*.bitcat.cc is already verified, skip dns-01.
Verify finished, start to sign.
Cert success.
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Your cert is in /Users/makito/.acme.sh/bitcat.cc/bitcat.cc.cer
Your cert key is in /Users/makito/.acme.sh/bitcat.cc/bitcat.cc.key
The intermediate CA cert is in /Users/makito/.acme.sh/bitcat.cc/ca.cer
And the full chain certs is there: /Users/makito/.acme.sh/bitcat.cc/fullchain.cer
It seems that you are using dns manual mode. please take care: The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead.
Call hook error.

至此证书签发完成,根据输出信息的提示,你也可以在其中出现的路径下找到证书以及秘钥文件。

不过我们也能注意到最后两行的提示信息提示我们正在使用手动模式:

1
2
It seems that you are using dns manual mode. please take care: The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead.
Call hook error.

那么,如何简化申请流程呢?

使用 Token

我们选用的 acme.sh 其实是支持直接使用主流 DNS 提供商的 API 接口来完成域名验证以及一些相关操作的。

可参考这篇 README,其中包含了大部分主流 DNS 提供商的 Token 使用方法。

这里咱选择了 DNSPod,只需要在执行 acme.sh --issue ... 之前设定一下 Token 的相关变量即可:

1
2
export DP_Id="<ID>"
export DP_Key="<TOKEN>"

DNSPod 的 Token 可在这里进行申请和管理。

之后在执行 acme.sh 的时候要在 --dns 参数后加上 dns_dp 来指定 DNS 服务商(这里对应的是 DNSPod)。

也就是说:

1
acme.sh --issue -d "bitcat.cc" -d "*.bitcat.cc" --dns dns_dp

这样就可以更方便的完成域名的所有权验证以及进行证书申请签发了。

后记

经过服务器的一番配置,可以看到证书已经生效。

本次 Let’s Encrypt 提供了泛域名支持对于一直在寻找免费 SSL 证书的同学来说确实是一个大新闻,在 Let’s Encrypt 的努力之下,推广 HTTPS 的网络浏览体验也将会变得相对更安全一些(与 HTTP 相比)。