SSL证书的自动化管理

作者 | 黄超    


640?wx_fmt=jpeg

杏仁运维工程师,关注容器技术和自动化运维。

前言

当今随着人们对网络安全意识的增强,越来越多的网站都开启了 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


SSL证书的自动化管理_第1张图片

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)有两种:

  1. dns-01: 在 DNS 域名解析记录中新增一条 TXT 类型的记录。

  2. http-01: 在域名的指定目录放入一个文件。

下面就根据 http-01 验证的方式来说明,Let's Encrypt 要求将 ed98 文件放入到 https://examole.com/8303 目录下,通过会发送一个 nonce (随机数)9cf0b331 要求 Client 用上诉注册账户用的私钥签名。

SSL证书的自动化管理_第2张图片

Client 将 nonce(随机数) 9cf0b331 使用私钥进行签名发送给 Server,Server 验证签名和目录下的文件成功后,就代表你对这个域名有控制权了。

SSL证书的自动化管理_第3张图片

接着 Client 会构建一个 PKCS#10 证书签名请求 CSR (包含证书一对公私钥)发送给 Server 端,同时用私钥对这个 CSR 进行签名,Server 根据签名确定你申请的这个域名是授权过的(上一步证明过了这个私钥对这个域名有控制权),对证书进行签名,然后颁发给 Client 端,这样就完成了证书的申请。

SSL证书的自动化管理_第4张图片

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  .com   \
--key-file /etc/nginx/ssl/.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)申请证书。

SSL证书的自动化管理_第5张图片

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,然后在重新申请证书并替换,再将旧的证书吊销。

参考

  • ACME 协议 : https://ietf-wg-acme.github.io/acme/

  • Let's Encrypt 是如何工作的

        https://blog.csdn.net/canghaiguzhou/article/details/79945001


全文完



以下文章您可能也会感兴趣:

  • 了解一下第三方登录

  • 分布式 ID 生成策略

  • 可线性化检查:与 NP 完全问题做斗争

  • Java 类型系统从入门到放弃

  • 使用 RabbitMQ 实现 RPC

  • 原来你是这样的 Stream —— 浅析 Java Stream 实现原理

  • 分布式锁实践之一:基于 Redis 的实现

  • ConcurrentHashMap 的 size 方法原理分析

  • 从 ThreadLocal 的实现看散列算法

  • 单元测试 -- 工程师 Style 的测试方法

  • 理解 RabbitMQ Exchange

  • JVM 揭秘: 一个 class 文件的前世今生



我们正在招聘 Java 工程师,欢迎有兴趣的同学投递简历到 [email protected]

640?wx_fmt=png


杏仁技术站

长按左侧二维码关注我们,这里有一群热血青年期待着与您相会。


你可能感兴趣的:(SSL证书的自动化管理)