ACME申请SSL证书并自动续期

1、安装acme.sh

1.1、安装依赖

[!CAUTION]

本文以Debian12+Nginx环境测试,其他环境配置可能略有不同,如有报错,请自行对照报错修改。

安装SSL证书生成脚本依赖

1
apt install socat netcat-openbsd -y

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

1.2、运行安装脚本

1
wget -O -  https://get.acme.sh | sh

1.3、让 acme.sh 命令生效

1
. .bashrc

1.4、 开启 acme.sh 的自动升级

升级 acme.sh 到最新版 :

1
acme.sh --upgrade

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

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

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

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

2、证书签发

2.1、选择默认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

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

切换 Buypass

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

切换 ZeroSSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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字符串

切换 SSL.com

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

切换 Google Public CA

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

2.2、测试证书申请

在正式申请证书之前,我们先用测试命令(--issue --test)来验证是否可以成功申请,这样可以避免在本地配置有误时,反复申请证书失败,超过 Let’s Encrypt 的频率上限(比如,每小时、每个域名、每个用户失败最多 5 次),导致后面的步骤无法进行。

测试证书申请的命令如下

1
acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/www/public --keylength ec-256

[!CAUTION]

此测试证书的验证方式为使用Webroot方式配合Nginx 认证操作,所以需要保证服务器的80端口开放,并且Nginx服务运行,此处/home/www/public 目录即Nginx中的root目录。

说明

ECC证书的主要优势在于它的 Keysize 更小,意味着同等大小下安全性的提升和加密解密速度的加快。如 ECC-256bit 的强度大约相当于 RSA-3072bit,何乐而不为呢?当然,有人说 ECC 证书握手会明显更快,这我觉得就有些夸张了,因为 RSA 握手也没有太慢,就算有差别应该也是毫秒级,很难直接感知。

另外,如果有些网站确实需要兼容某些古老设备的,那也还是请按需选择RSA证书。

最终应该看到类似这样的提示

1
2
3
4
[Sat Dec  11 02:27:05 UTC 2024] Your cert is in: /root/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer
[Sat Dec 11 02:27:05 UTC 2023] Your cert key is in: /root/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key
[Sat Dec 11 02:27:05 UTC 2023] The intermediate CA cert is in: /root/.acme.sh/二级域名.你的域名.com_ecc/ca.cer
[Sat Dec 11 02:27:05 UTC 2023] And the full chain certs is there: /root/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer

如果这一步出错的话,你可以运行下面的命令,来查看详细的申请过程和具体的错误。

1
acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --debug

2.3、正式证书申请

2.3.1、单域名证书申请

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

1
2
acme.sh --set-default-ca --server letsencrypt
acme.sh --issue -d 二级域名.你的域名.com -w /home/www/public --keylength ec-256 --force

说明

–force 参数的意思就是,在现有证书到期前,手动(强行)更新证书。上一步我们从“测试服”申请的证书虽然不能直接用,但是它本身是尚未过期的,所以需要用到这个参数。

最终应该看到跟上面类似的提示:

1
2
3
4
[Wed 30 Dec 2022 15:22:52 AM EST] Your cert is in  /home/www/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer
[Wed 30 Dec 2022 15:22:52 AM EST] Your cert key is in /home/www/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key
[Wed 30 Dec 2022 15:22:52 AM EST] The intermediate CA cert is in /home/www/.acme.sh/二级域名.你的域名.com_ecc/ca.cer
[Wed 30 Dec 2022 15:22:52 AM EST] And the full chain certs is there: /home/www/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer

仔细观察,你会发现这次给你发证书的域名是 https://acme-v02.api.letsencrypt.org,少了 staging,自然就是【正式服】了!

2.3.2、多域名证书申请
1
~/.acme.sh/acme.sh --issue -d bihell.com -d www.bihell.com --standalone -k ec-384 --force
2.3.3、DNS API 申请

DNS API列表

2.3.4、CloudFlare通配域名申请

以CloudFlare为例,我们首先需要准备好CloudFlare的Global API Key

Global API Key获取方式

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

1
2
3
# 将下面的key值替换成你自己的Key及CF的邮箱
export CF_Key="763eac4f1bcebd8b5c95e9fc50d010b4"
export CF_Email="alice@example.com"

执行以下语句申请证书

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

2.4、安装证书

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

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

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

2.4.1、单域名或多域名配置
1
2
mkdir /SSL
~/.acme.sh/acme.sh --installcert -d example.com -d www.example.com --fullchainpath /SSL/example.crt --keypath /SSL/example.key --ecc
2.4.2、通配域名配置
1
2
mkdir /SSL
~/.acme.sh/acme.sh --installcert -d example.com -d '*.example.com' --fullchainpath /SSL/example.crt --keypath /SSL/example.key --ecc

2.5、更新证书

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

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

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

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

强制更新可以这样

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

2.6、停止更新证书

1
2
3
4
# 查看证书列表
acme.sh --list
# 停止 Renew
acme.sh --remove -d example.com [--ecc]

2.7、Nginx 配置

配置文件中网址及路径需修改为自己对应的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
#监听443端口
listen 443 ssl;
#你的域名
server_name example.com www.example.com;
#ssl证书的pem文件路径
ssl_certificate /SSL/example.crt;
#ssl证书的key文件路径
ssl_certificate_key /SSL/example.key;
location / {
root /root/www/public/;
index index.html;
try_files $uri $uri/ =404;
}
}
server {
listen 80;
server_name example.com www.example.com;
#将请求转成https
rewrite ^(.*)$ https://$host$1 permanent;
}

2.8、其他配置

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。

1
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

ACME申请SSL证书并自动续期
https://www.sajuna.cn/2024/04/12/ACME申请SSL证书并自动续期/
作者
ZikQ
发布于
2024年4月12日
许可协议