# 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
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
2
可以开启自动更新(可选)
~/.acme.sh/acme.sh --upgrade --auto-upgrade
# 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
切换 Buypass
acme.sh --set-default-ca --server buypass
切换 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字符串
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
切换 Google Public CA
acme.sh --set-default-ca --server google
# 证书申请
假设服务器在运行着的,网站域名为 example.com,根目录为 /home/wwwroot/example.com。那么只需要执行下面这条语句就行。
acme.sh --issue -d example.com -w /home/wwwroot/example.com
# 多域名证书申请
~/.acme.sh/acme.sh --issue -d bihell.com -d www.bihell.com --standalone -k ec-384 --force
# 通配域名申请
以阿里云域名 (opens new window)为例,我们通过DNS进行验证。首先拿到阿里云的AccessKey (opens new window)
然后终端创建对应key的变量
# 将xxxxx替换成你自己的key
export Ali_Key="xxxxxxx"
export Ali_Secret="xxxxxxx"
2
3
执行以下语句申请证书
# 注意将域名改为你自己的
~/.acme.sh/acme.sh --issue --dns dns_ali -d bihell.com -d '*.bihell.com' -k ec-256 --force
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
2
# 通配域名配置
mkdir /data
~/.acme.sh/acme.sh --installcert -d bihell.com -d '*.bihell.com' --fullchainpath /data/dice.crt --keypath /data/dice.key --ecc
2
# 4. 更新 acme.sh
目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步。
升级 acme.sh 到最新版 :
acme.sh --upgrade
如果你不想手动升级, 可以开启自动升级:
acme.sh --upgrade --auto-upgrade
你也可以随时关闭自动更新:
acme.sh --upgrade --auto-upgrade 0
# 5. 更新证书
证书的有效期为 90 天,acme.sh 会 60 天更新(Renew)一次。
在安装 acme.sh 的时候就自动配置了一条 cron 任务了,会每天检查证书的情况。当然可以到 crontab 里看一下。
29 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
也可以试着用上面这条命令执行看一下相关的配置是否正确。
强制更新可以这样
acme.sh --renew -d example.com --force
acme.sh --renew -d example.com --force --ecc # 如果用的是ECC证书
2
3
# 6. 停止更新证书
# 查看证书列表
acme.sh --list
# 停止 Renew
acme.sh --remove -d example.com [--ecc]
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;
# ...
}
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";