使用 DNS 验证获取 Let's Encrypt 的 SSL 证书
Let’s Encrypt 是一个非盈利的证书颁发机构,为互联网站点提供免费的 SSL 证书。通常,可以通过 HTTP 认证(HTTP Validation)获取 Let’s Encrypt 的证书。比如 Caddy 服务器就内置了自动获取 Let’s Encrypt 或者 ZeroSSL 证书的特性。但这种 HTTP 认证的方式,需要域名指向一个可以被互联网公网访问的 HTTP 服务器,并开放 HTTP端口(80) 和 HTTPS 端口(443)。这在某些情况下可能并不适用。幸运的是,还可以通过 DNS 认证(DNS Validation)获取 SSL 证书。当然在获取(以及续期)的过程中,需要修改域名的 DNS 的记录,以便证明对域名的所有权。
开源工具 lego 介绍
开源工具 lego 是一个用Go语言编写的 Let’s Encrypt/ACME 客户端和库。它提供了只包含一个二进制文件的命令行工具,用于获取 SSL 证书,既支持 HTTP 认证,也支持 DNS 认证。对于 DNS 认证,它支持上百个DNS提供商,比如 Name.com、阿里云DNS 等。
使用方法
安装
参考 lego 的安装文档,可以使用包管理工具安装,也可以从 Github Releases 页面下载所需平台的命令行二进制文件。当然,也可以下载源码自行编译。
使用方法
获取域名服务的 API 凭证
由于使用 DNS 验证时,为了验证 DNS 的所有权,需要修改 DNS 记录。因此,首先在 DNS 提供商处获取能够修改域名记录的 API 凭证。
获取证书
在 lego的DNS提供商 的文档中,找到域名提供商对应的文档页。设置对应的环境变量,然后运行 lego 程序即可。
比如 Name.com 的文档页为 https://go-acme.github.io/lego/dns/namedotcom/。参考其说明,在命令行中执行:
NAMECOM_USERNAME=foo.bar \NAMECOM_API_TOKEN=a379a6f6eeafb9a55e378c118034e2751e682fab \lego --email you@example.com --dns namedotcom --domains my.example.org run成功执行后,获取到的证书文件位于当前目录下的 .lego/certificates 目录中。
注意事项
Let’s Encrypt 颁发的证书的有效期通常为 90 天,到期之前应该续期(renew),否则在访问依赖此证书的网站等服务会出现安全问题。
补记
通过 Cloudflare 获取超过4层域名的证书
参考 Lego 的文档针对 Cloudflare 的文档 《Cloudflare》,当使用如下命令获取证书时:
CLOUDFLARE_DNS_API_TOKEN=1234567890abcdefghijklmnopqrstuvwxyz \lego --email you@example.com --dns cloudflare -d '4th.subdomain.example.com' run可能会遇到如下错误:
2024/11/10 15:53:54 [WARN] [4th.subdomain.example.com] acme: cleaning up failed: cloudflare: could not find zone for domain "4th.subdomain.example.com": [fqdn=_acme-challenge.4th.subdomain.example.com.] unexpected response for '4th.subdomain.example.com.' [question='4th.subdomain.example.com. IN SOA', code=NOTIMP]2024/11/10 15:53:54 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/4280890701272024/11/10 15:53:55 Could not obtain certificates: error: one or more domains had a problem:[4th.subdomain.example.com] [4th.subdomain.example.com] acme: error presenting token: cloudflare: could not find zone for domain "4th.subdomain.example.com": [fqdn=_acme-challenge.4th.subdomain.example.com.] unexpected response for '4th.subdomain.example.com.' [question='4th.subdomain.example.com. IN SOA', code=NOTIMP]Lego 项目的 Github 项目中已经有过这个议题,比如《Cloudflare can’t find zone for sub-domain #1303》。幸运的是,有人在《[cloudns] unable to request certificate for fourth level domain #884》 提到了解决方法,那就是使用 --dns.resolvers 选项。因此可将获取证书的命令修改为:
CLOUDFLARE_DNS_API_TOKEN=1234567890abcdefghijklmnopqrstuvwxyz \lego --email you@example.com --dns cloudflare -d '4th.subdomain.example.com' --dns.resolvers "8.8.8.8" run