# ACME

# 一、概念

acme.sh是github上的一个开源项目,实现了acme协议, 可以从letsencrypt生成免费的证书。

# Let's Encrypt

Let's Encrypt是一个于2015年三季度推出的数字证书认证机构,旨在以自动化流程消除手动创建和安装证书的复杂流程,并推广使万维网服务器的加密连接无所不在,为安全网站提供免费的SSL/TLS证书。

# ACME(自动证书管理环境)

ACME协议最初是由 Internet Security Research Group 为其公共 CA(公共证书颁发机构)——Let's Encrypt 开发的。ACME 协议通过在给定 Web 服务器上安装证书管理代理来运行。组织或域在一开始就经过验证,代理协助域控制验证,一旦完成,代理可以请求,续订和撤销证书。

详情:ACME 协议:它是什么以及如何工作——asiaregister.com (opens new window)

# 全站https,通配符证书

通配符证书是一个可以被多个子域使用的公钥证书,主域名签发的通配符证书可以在所有子域名中使用。在此之前,配置子域名也是需要每个子域名单独的申请证书的。2018年3月14日,Let’s Encrypt 对外宣布ACME v2已正式支持通配符证书,这意外味着用户可以在 Let’s Encrypt 上免费申请支持通配符的SSL证书。

# 二、具体操作

这里配合B站视频 (opens new window),食用更香。

# 1. 安装依赖

安装 SSL 证书生成脚本依赖

apt install socat netcat -y
1

socat 是一个多功能的网络工具,名字来由是“Socket CAT”,可以看作是 netcat 的加强版。它有一些netcat所不具备却又很有需求的功能,例如ssl连接。socat是强大的,可以实现任意socket的转换。而netcat被称为网络工具中的瑞士军刀,体积小巧,但功能强大。netcat可以在两台设备上面相互交互,即侦听模式/传输模式。

安装 SSL 证书生成脚本

# 请注意替换 username@example.com 为你自己的邮箱,避免无法收到上游证书的邮件通知,比如 Let's Encrypt 偶尔会错发证书,然后就会邮件通知你,这时候就需要重新签发一次证书了。
curl  https://get.acme.sh | sh -s email=username@example.com
1
2

可以开启自动更新(可选)

~/.acme.sh/acme.sh --upgrade --auto-upgrade
1

# 2. 证书签发

# 选择默认 CA

目前 acme.sh 支持四个正式环境 CA,分别是 Let's Encrypt、Buypass、ZeroSSL 和 SSL.com,默认使用 ZeroSSL

功能 LE Buypass ZeroSSL SSL.com Google Public CA
有效期 90 天 180 天 90 天 90 天 90 天
多域名 支持 支持,最多 5 个 支持 收费支持 支持
泛域名 支持 不支持 支持 收费支持 支持
Rate Limit 收费无 未知
GUI 管理
ECC 证书链 未知
客户支持 社区 收费 收费 收费 收费

简单来说,如果没有特殊需求,可以选择 Let's Encrypt,如果服务器在国内,可以选择 ZeroSSL 或 Buypass,如果愿意付费得到更好的服务和保障,可以选择 ZeroSSL 和 SSL.com,如果面向欧盟用户,可以选择 Buypass 和 ZeroSSL。

注意:经过测试 Google Public CA 的 ACME 验证域名在国内是无法访问的,只有国外服务器才可以申请,申请完成后的证书并无影响。

如果需要更换可以使用如下命令:

切换 Let's Encrypt

~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
1

切换 Buypass

acme.sh --set-default-ca --server buypass
1

切换 ZeroSSL

acme.sh --set-default-ca --server zerossl
# 注册
~/.acme.sh/acme.sh --register-account -m my@example.com
# 如果已有 ZeroSSL 帐号,可以在后台控制面板拿到 API Key,然后执行如下命令
apt install jq
curl -s -X POST "https://api.zerossl.com/acme/eab-credentials?access_key=你的API_Key" | jq
# 终端会输出如下内容
{
  "success": true,
  "eab_kid": "kid字符串",
  "eab_hmac_key": "hmac_key字符串",
}
# 然后手工添加帐号
acme.sh --register-account  --server zerossl \
        --eab-kid kid字符串  \
        --eab-hmac-key hmac_key字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

切换 SSL.com

acme.sh --set-default-ca --server ssl.com
1

切换 Google Public CA

acme.sh --set-default-ca --server google
1

# 证书申请

假设服务器在运行着的,网站域名为 example.com,根目录为 /home/wwwroot/example.com。那么只需要执行下面这条语句就行。

acme.sh  --issue  -d example.com  -w /home/wwwroot/example.com
1

# 多域名证书申请

~/.acme.sh/acme.sh --issue -d bihell.com -d www.bihell.com --standalone -k ec-384 --force
1

# 通配域名申请

阿里云域名 (opens new window)为例,我们通过DNS进行验证。首先拿到阿里云的AccessKey (opens new window)

然后终端创建对应key的变量

# 将xxxxx替换成你自己的key
export Ali_Key="xxxxxxx"
export Ali_Secret="xxxxxxx"
1
2
3

执行以下语句申请证书

# 注意将域名改为你自己的
~/.acme.sh/acme.sh --issue --dns dns_ali -d bihell.com -d '*.bihell.com' -k ec-256 --force
1
2

# 3. 安装证书

前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方。

请注意,默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件,例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件。这里面的文件都是acmesh工具内部使用, 目录结构在将来可能会变化,进而导致服务器配置文件中填写的证书路径错误的情况。

正确的使用方法是使用 --installcert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置, 例如:

# 单域名或多域名配置

mkdir /data
~/.acme.sh/acme.sh --installcert -d bihell.com -d www.bihell.com --fullchainpath /data/dice.crt --keypath /data/dice.key --ecc
1
2

# 通配域名配置

mkdir /data
~/.acme.sh/acme.sh --installcert -d bihell.com -d '*.bihell.com' --fullchainpath /data/dice.crt --keypath /data/dice.key --ecc
1
2

# 4. 更新 acme.sh

目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步。

升级 acme.sh 到最新版 :

acme.sh --upgrade
1

如果你不想手动升级, 可以开启自动升级:

acme.sh --upgrade --auto-upgrade
1

你也可以随时关闭自动更新:

acme.sh --upgrade --auto-upgrade 0
1

# 5. 更新证书

证书的有效期为 90 天,acme.sh 会 60 天更新(Renew)一次。

在安装 acme.sh 的时候就自动配置了一条 cron 任务了,会每天检查证书的情况。当然可以到 crontab 里看一下。

29 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
1

也可以试着用上面这条命令执行看一下相关的配置是否正确。

强制更新可以这样

acme.sh --renew -d example.com --force

acme.sh --renew -d example.com --force --ecc  # 如果用的是ECC证书
1
2
3

# 6. 停止更新证书

# 查看证书列表
acme.sh --list

# 停止 Renew
acme.sh --remove -d example.com [--ecc]
1
2
3
4
5

# 7.Nginx 配置

server {

server_name example.com;

listen       443 ssl http2 default_server;

listen       [::]:443 ssl http2 default_server;

# ...

# ssl 相关配置

ssl_certificate /etc/nginx/ssl/example.com.fullchain.cer;

ssl_certificate_key /etc/nginx/ssl/example.com.key;

ssl_dhparam /etc/nginx/ssl/dhparam.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers '[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES';

ssl_prefer_server_ciphers on;

# ...

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

TLSv1.3(可选)

现在很多网站都上 TLSv1.3 了,证书检测的网站对于 TLSv1、TLSv1.1 都认为不安全了,Firefox 自 74.0 版本开始也完全放弃对加密协议 TLS 1.0 和 TLS 1.1 的支持了。

开启 HSTS(可选)

当然,为了更加安全,可以选择开启 HSTS(HTTP Strict Transport Security,HTTP严格传输安全协议),强制浏览器通过 https 进行访问。需要在 location 下的设置中加入一个 header。

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
1
更新时间: 4/13/2022, 12:20:23 PM