前言
目前越来越多的网站都开启了 HTTPS,而且申请 SSL 证书的方式也很简单,直接在云平台上就可以免费地申请 DV 证书,你只需要填写域名信息,经过证书认证机构的域名检测后再将证书下载并配置至你的 web 服务器上即可。如果你需要管理很多份证书,当证书到期后又要一份一份地重新更新,像上诉这种纯手动的流程,即费时间而且还容易出错。
Let's Encrypt
The objective of Let’s Encrypt and the ACME protocol is to make it possible to set up an HTTPS server and have it automatically obtain a browser-trusted certificate, without any human intervention.
Let's Encrypt 是一个免费,开源的 CA 机构,它们创建一个 ACME 协议,协议规范化了证书申请,更新,撤销等流程,只要是实现了 ACME 协议的客户端就可以以自动化的方式向 Let's Encrypt 申请,更新,撤销证书。而且以有很多现成的客户端可以提供使用。
Let's Encrypt 的工作原理
Let's Encrypt 的工作原理其实是遵循 ACME 协议,如果需要自行实现 ACME 客户端,或更多细节,可查看相关的文档。
首先是注册 Let's Encrypt 的用户(account),ACME 协议规定采用公私钥方式来注册账户,Client 端会根据非对称加密算法生成一对公私钥 openssl genrsa 4096
,用私钥对注册用户所需的信息签名发送至 Let's Lencrypt 端,Let's Lencrypt 用公钥验证成功后将发送给 Client 一个 account object 和 account url,以后 server 端就能根据私钥的签名来验证账户信息的有效性了。
Client Server
[Contact Information]
[ToS Agreement]
[Additional Data]
Signature ------->
Account URL
<------- Account Object
[] Information covered by request signatures
接着 Client 会向 Sever 端询问申请这个证书需求的内容,Server 端会发送一组或多组 challenges,要求 Client 证明对申请这个域名有控制权,证明的方式(Challenge Type)有两种:
- dns-01: 在 DNS 域名解析记录中新增一条 TXT 类型的记录。
- http-01: 在域名的指定目录放入一个文件。
下面就根据 http-01 验证的方式来说明,Let's Encrypt 要求将 ed98
文件放入到 https://examole.com/8303
目录下,通过会发送一个 nonce (随机数) 9cf0b331
要求 Client 用上诉注册账户用的私钥签名。
Client 将 nonce(随机数) 9cf0b331
使用私钥进行签名发送给 Server,Server 验证签名和目录下的文件成功后,就代表你对这个域名有控制权了。
接着 Client 会构建一个 PKCS#10 证书签名请求 CSR (包含证书一对公私钥)发送给 Server 端,同时用私钥对这个 CSR 进行签名,Server 根据签名确定你申请的这个域名是授权过的(上一步证明过了这个私钥对这个域名有控制权),对证书进行签名,然后颁发给 Client 端,这样就完成了证书的申请。
acme.sh
acme.sh 是 Let's Encrypt 中列出的一个 ACME 客户端,是一个纯 shell 的脚本,通过它能自动化地实现证书的申请,更新等操作。
安装过程非常简单,只需要一个命令,脚本相关的东西都放在 ~/.acme.sh/
目录:
curl https://get.acme.sh | sh
使用下列命令,它就能申请证书并把证书和私钥文件 copy 到你指定的位置,并执行 nginx reload,让配置生效,同时会自动地去更新证书。
acme.sh --installcert -d <domain>.com \
--key-file /etc/nginx/ssl/<domain>.key \
--fullchain-file /etc/nginx/ssl/fullchain.cer \
--reloadcmd "service nginx force-reload"
cert-manager
cert-manager 是一个 kubernetes 的自定义插件,它通过 ACME 协议向支持 ACME 协议的 CA 机构(默认是 Let's Encrypt)申请证书,并将证书存放在 Secrets
中。
它能与 nginx ingress 进行整合,根据 ingress 创建的资源,自行申请,更新证书并应用至 ingress 内。
常见问题
关于通配符证书(泛域名证书)的支持:
https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578
已支持,不过需要使用 DNS 记录进行域名所有权的验证。
Let's Encrypt 证书的兼容性:
兼容性列表: https://letsencrypt.org/docs/certificate-compatibility/
证书丢失了能否通过 Let's Encrypt account private key 找回:
https://community.letsencrypt.org/t/how-to-get-certificates-which-were-lost/23438
无法只根据 account private key 将证书找回,应为证书的私钥只保存在你的本地,如果你的证书可以确认没有泄露,
就重新申请证书。
Let's Encrypt account private key 泄露了怎么办:
https://community.letsencrypt.org/t/account-key-compromise/34136
目前从 ACME 的协议里并没有针对这个问题提出改进。