前言
当今随着人们对网络安全意识的增强,越来越多的网站都开启了 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 机构,而且基本上不会有数量上的限制还能实现自动化。
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 的用户(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 是一个纯 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 .com \
--key-file etc/nginx/ssl/.key \
--fullchain-file etc/nginx/ssl/fullchain.cer \
--reloadcmd "service nginx force-reload"
配合上 crontab 中的 job, 就能够实现证书的自动更新了。
cert-manager 是一个 kubernetes 的自定义插件,它通过 ACME 协议向 CA 机构(默认是 Let's Encrypt)申请证书。
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 张证书 (例如 www.example.com 的主域是 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,然后在重新申请证书并替换,再将旧的证书吊销。
https://blog.csdn.net/canghaiguzhou/article/details/79945001
全文完
以下文章您可能也会感兴趣:
我们正在招聘 Java 工程师,欢迎有兴趣的同学投递简历到 rd-hr@xingren.com 。
长按左侧二维码关注我们,这里有一群热血青年期待着与您相会。