![f090951c077ddbb9731df7af3510bbe6.png](https://img-blog.csdnimg.cn/img_convert/f090951c077ddbb9731df7af3510bbe6.png)
作者 | 黄超
杏仁运维工程师,关注容器技术和自动化运维。
前言
当今随着人们对网络安全意识的增强,越来越多的网站都开启了 HTTPS 加密来保证数据传输的安全。要开启 HTTPS,首先就需要向 CA 机构申请 SSL 证书,SSL 证书根据可信强度,大概可分为: 域名型证书(DV SSL),企业型证书(OV SSL),增强型证书(EV SSL)。
证书类型审核流程审核周期价格使用场景DV SSL完成域名所有权限的验证1 天免费或几百元博客,个人站点OV SSL需要提交网站企业的资质文件(如营业执照,组织机构代码证等)经过人工审核后发放15 - 30 天几千左右一般的企业EV SSL需要提交网站企业的资质文件(如营业执照,组织机构代码证等)经过人工审核后,还需要律师函的审核才会发放15 - 30 天几千上万金融,电商等安全需求高的网站
对于我们个人而言或者是公司的内部管理系统,我们完全可以选择费用最少,申请周期短的 DV SSL 证书来开启我们站点的 HTTPS。目前在很多云平台(阿里云,腾讯云等)上都能免费地申请 DV SSL 证书,但是都会有数量限制,下面将介绍一个免费,开源的 CA 机构,而且基本上不会有数量上的限制还能实现自动化。
Let's Encrypt
![55b92dfd1306ff415d91fde11a443ed4.png](https://img-blog.csdnimg.cn/img_convert/55b92dfd1306ff415d91fde11a443ed4.png)
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 是一个由非营利性组织 互联网安全研究小组 (ISRG) 提供的免费,自动化和开放的证书颁发机构。
Let's Encrypt 的证书的 签发/续签 都是通过 ACME 协议实现的,ACME 协议最初就是由 Let's Encrypt 团队开发,协议旨在确保验证,发布和管理方法是完全自动化,一致,合规和安全的,ACME v2 如今已变成了 IETF (RFC 8555) 标准。
Let's Encrypt 的官方已列举了许多实现了 ACME 协议的自动化申请工具/脚本,后面会简单介绍两款,我们先来看看 Let's Encrypt 的工作原理。
Let's Encrypt 的工作原理
首先是注册 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 用上诉注册账户用的私钥签名。
![0da10332470e20541b5a9c6229d83ce1.png](https://img-blog.csdnimg.cn/img_convert/0da10332470e20541b5a9c6229d83ce1.png)
Client 将 nonce(随机数) 9cf0b331
使用私钥进行签名发送给 Server,Server 验证签名和目录下的文件成功后,就代表你对这个域名有控制权了。
![daa6ec67c3bb6dd7840ac00dc3d808b5.png](https://img-blog.csdnimg.cn/img_convert/daa6ec67c3bb6dd7840ac00dc3d808b5.png)
接着 Client 会构建一个 PKCS#10 证书签名请求 CSR (包含证书一对公私钥)发送给 Server 端,同时用私钥对这个 CSR 进行签名,Server 根据签名确定你申请的这个域名是授权过的(上一步证明过了这个私钥对这个域名有控制权),对证书进行签名,然后颁发给 Client 端,这样就完成了证书的申请。
![b1d5f83a3add577c74d6b56975039c95.png](https://img-blog.csdnimg.cn/img_convert/b1d5f83a3add577c74d6b56975039c95.png)
ACME 客户端
acme.sh
acme.sh 是一个纯 shell 的脚本,所以基本上没有什么环境依赖,通过它能自动化地实现证书的申请,更新等操作。
安装过程非常简单,只需要一个命令,脚本相关的东西都放在 ~/.acme.sh/
目录:
curl https://get.acme.sh | sh
安装完成后,会在 crontab 中开启每天定时更新证书的 job:
0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null
申请证书
acme.sh 默认采用 http 的方式来验证域名的所有权,可以通过 -w
参数来指定验证文件的路径,它会在 /var/www/html
中创建一个 .well-known
文件夹,Let's Encrypt 回去访问这个验证文件,验证成功后会将证书放在~/.acme.sh/certs/
中:
acme.sh --issue -d example.com -w /var/www/html
安装证书
使用下列命令,它就能申请证书并把证书和私钥文件 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"
配合上 crontab 中的 job, 就能够实现证书的自动更新了。
cert-manager
cert-manager 是一个 kubernetes 的自定义插件,它通过 ACME 协议向 CA 机构(默认是 Let's Encrypt)申请证书。
![3b8beea38ea8fe547f7a695e4efa5411.png](https://img-blog.csdnimg.cn/img_convert/3b8beea38ea8fe547f7a695e4efa5411.png)
cert-manager 会检测到你证书创建资源请求(cert.yaml)并申请证书,成功后放在 Secrets 对象中,并定义更新证书。
cert.yaml
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: example
namespace: default
spec:
secretName: example-ssl-cert
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- www.example.com
acme:
config:
- http01:
ingressClass: nginx
domains:
- www.example.com
这样就能在 ingress 中直接使用了。
常见问题
申请证书频率的限制?
- 同一个主域下一周只能申请 50 张证书 (例如 http://www.example.com 的主域是 http://example.com)
- 每个账户每个域名每小时申请验证失败的次数为 5 次
- 每周只能创建 5 个重复的证书,即使是通过不同账户创建
- 每个账户同一个 IPv4 地址每 3 小时最多可创建 10 张证书
- 每个多域名(SAN)证书最多包含 100 个子域
- 更新证书没有次数的限制,但是更新证书会受到上述重复证书的限制
查询证书列表?
可在 https://crt.sh 进行查询域名的证书详情
关于通配符证书(泛域名证书)的支持:
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 的协议里并没有针对这个问题提出改进。最好的做法是,重新申请一个 account,然后在重新申请证书并替换,再将旧的证书吊销。
参考
- ACME 协议
- Let's Encrypt 是如何工作的
全文完
我们正在招聘 Java 工程师,欢迎有兴趣的同学投递简历到 rd-hr@xingren.com 。
欢迎搜索关注微信公众号:杏仁技术站(微信号 xingren-tech)。