# ACME 证书自动化管理
Date: 2021-08-28


在搭建blog使用https服务，需要申请配置一个域名证书，使用了Let’s Encrypt申请了免费的https证书。

####  **HTTP vs HTTPS**

HTTPS 将 HTTP over TCP/IP 变成 HTTP over SSL/TLS，也就是在原有层之间增加一个SSL/TLS安全层。

![](https://garlicspace.com/wp-content/uploads/2021/08/HTTPS.png)

####  **SSL vs TLS**

![](https://garlicspace.com/wp-content/uploads/2021/08/SSLvsTLS.png) from https://dev.to/techschoolguru/a-complete-overview-of-ssl-tls-and-its-cryptographic-system-36pd

- SSL最初由网景（Netscape）开发，于1995年首次发布2.0版本， 1.0版本由于严重安全漏洞未发布过
- 1996年，发布SSL3.0版本
- 三年以后的1999年，TLS1.0有IETF定义再RFC2246标准中诞生，他是基于SSL3.0的，所有些文章也称他为SSL3.1。
- 2006年，升级到TLS1.1，但是紧接着在2008年就被TLS1.2取代。
- 2018年，TLS1.3做出了巨大改进。

SSL2.0和SSL3.0分别在2011，2015年被弃用，截至2020年3月Microsoft，Apple，Google，Mozilla，Cloudflare和Cisco， 均已弃用TLS1.0，TLS1.1。目前推荐使用协议是TLS1.2，TLS1.3

####  **HTTPS如何工作**

主要分为两个阶段：

**阶段一 获得服务器证书（a Server Certificate）**

- garlic要想给garlicspace.com申请证书, 首先生成CSR（a Certificate Signing Request），主要包含了
    - 证书使用的算法
    - 密钥对长度
    - 私钥
    - 与此同时生成自己的私钥留存本地
-  garlic找到一个证书颁发机构（CA Certificate Authority）， 比如：Comodo、GeoTrust、Thawte、RapidSSL。
- CA会判断对garlic是否其域名garlicspace.com有控制权。

![](https://garlicspace.com/wp-content/uploads/2021/08/微信图片_20210828185446.png)

> 图片来源https://devconfcz2021.sched.com/event/gmMh/acme-certificate-management-has-never-been-easier

 

**阶段二 有了SSL/TLS协议的支持HTTPS是如何工作的呢？** 

以TLS1.2为例子：

- 客户端发送ClientHello 发送随机数，客户端TLS版本号，密码套件，扩展列表
- 服务端收到后返回ServerHello服务端随机数， 确定TLS版本， 密码套件，同时返回服务器证书， 密钥交换算法参数。
- 客户端收到证书后验证其有效性，比如证书有效期，证书对应域名，通过本地已经安装CA根证书对证书验签，如果存在中间CA，进行证书链的验证。
- 客户端发送密钥交换参数， 之后改用协商好密码套件中的会话密钥加密（对称密钥）传输。

![](https://garlicspace.com/wp-content/uploads/2021/08/TLS.png)

> 图片来源： https://certs.securetrust.com/support/support-how-ssl-works.php

 

#### **Let’s Encrypt做了什么**

简单来说他自动化的完成，证书申请，验证，下载，自动化更新， 并且可以免费使用。目前ACME v2协议已经被成为IETF标准

```
Automatic Certificate Management Environment (ACME)  RFC 8555
```

#### **如何工作？**

从现在申请证书流程来看，一般向CA发起证书申请后， 响应的过程是异步的，一般等待一段时间后需要人工处理完成资质认定， 如果要实现自动化，都需要一个方便在线域名认证方法， 对此Let’s Encrypt CA提供两种方式（challenges）：

- 在 `example.com` 下配置 DNS 记录，或者
- 在 `https://example.com/` 的已知 URI 下放置一个 HTTP 资源

![](https://garlicspace.com/wp-content/uploads/2021/08/howitworks_challenge.png)

> 图片来源 https://letsencrypt.org/zh-cn/how-it-works/

以http方式为例， 证书请求启动发送给CA后，CA要求其在指定路径上创建文件8303， 要生成一个随机数ed98（nonce， 为了防止重放攻击），并使用私钥对其签名。发送给Let's encrypt CA 进行验证。

![](https://garlicspace.com/wp-content/uploads/2021/08/howitworks_authorization.png)

验证通过后请求端发送CSR请求， CA通过后签发证书

![](https://garlicspace.com/wp-content/uploads/2021/08/howitworks_certificate.png)

同时也支持证书吊销

![](https://garlicspace.com/wp-content/uploads/2021/08/howitworks_revocation.png)

#### **如何实现？**

![](https://garlicspace.com/wp-content/uploads/2021/08/https-Page-3-320x1024.png)

通过自动注册 （Register account）， 生成订单（Create Order），实现了证书请求的管理。其中也会用nonce来防止重放攻击。

 

#### **使用acme.sh 申请证书**

- 安装，安装会自动添加定时器实现证书定时更新

```
curl  https://get.acme.sh | sh
```

- 申请证书

```
sudo ~/.acme.sh/acme.sh --issue -d example.com --standalone -k ec-384 --server letsencrypt \
                --renew-hook "~/.acme.sh/acme.sh        --install-cert -d example.com --ecc \
                                        --key-file /etc/acme/ecc/private.key \
                                        --fullchain-file /etc/acme/ecc/fullchain.crt \
                                        --reloadcmd \"systemctl restart nginx\"  "

sudo ~/.acme.sh/acme.sh --issue -d example.com --standalone --keylength 4096 --server letsencrypt \
                --renew-hook "~/.acme.sh/acme.sh        --install-cert -d example.com  \
                                        --key-file /etc/acme/rsa/private.key  \
                                        --fullchain-file /etc/acme/rsa/fullchain.crt \
                                        --reloadcmd \"systemctl restart nginx\"  "
```

- 安装证书

```
sudo ~/.acme.sh/acme.sh --installcert -d example.com \
                        --fullchainpath /etc/acme/ecc/fullchain.crt \
                         --keypath /etc/v2ray/ecc/private.key --ecc

sudo ~/.acme.sh/acme.sh --installcert -d example.com \
                        --fullchainpath /etc/v2ray/rsa/fullchain.crt \
                         --keypath /etc/v2ray/rsa/private.key
```

这里域名， 密钥长度， 使用CA， key-file 和 fullchain-file ，以及域名对应路径需要根据实际情况指定。 第一次申请需要安装一下。

当证书过期需要acme自动renew，并会从.acme目录中对应域名的目录中找到申请证书的配置文件.conf， 找renew-hook对应的执行语句， 自动安装。

 

#### **需要注意的几个问题**

1. 双证书申请： 申请RSA和ECDSA两种证书，兼容RSA客户端， ngnix增加通知增加两种证书配置即可；
2. Rate Limit： Let’s Encrypt 对证书颁发个数频率都有限制 具体可以参考 https://letsencrypt.org/zh-cn/docs/rate-limits/
3. 由于我使用单机申请域名， 所有使用--standalone如果多台机器的话需要使用dns-01 challenge；
4. DNS中配置CAA指定证书颁发机构 https://sslmate.com/caa/

 

####  **参考及引用**

1. [How SSL/TLS Works:](https://certs.securetrust.com/support/support-how-ssl-works.php)
2. [A complete overview of SSL/TLS and its cryptographic system](https://dev.to/techschoolguru/a-complete-overview-of-ssl-tls-and-its-cryptographic-system-36pd) 
3. [Let's Encrypt 的运作方式](https://letsencrypt.org/zh-cn/how-it-works/)
4. https://gitlab.com/sinclair2/bacme/-/blob/master/bacme
5. https://segmentfault.com/a/1190000011097942

Photo by **[Erik Karits](https://www.pexels.com/@erik-karits-2093459?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)** from **[Pexels](https://www.pexels.com/photo/two-gray-owls-on-a-tree-branch-4823986/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)**

