使用 acme.sh 自动部署 SSL 证书

本文最后更新于:2022年3月22日 上午

启用 HTTPS 协议需要 SSL 证书,SSL 是一种安全协议,目的是为互联网通信,提供安全及数据完整性保障。SSL 证书遵循 SSL 协议,可安装在服务器上,实现数据传输加密。

SSL 证书需要到证书颁发机构(Certificate Authority,缩写为 CA)申请。通常,DNS 解析服务提供商都会给用户提供免费证书申请,例如腾讯云就给用户提供 TrustAsia 品牌的免费型 DV 版 SSL 证书,你可以在腾讯云文档中心查看 域名型(DV)免费 SSL 证书申请流程

腾讯云提供的一年期免费证书虽然够用,但是每当证书到期,就需要到腾讯云中对证书进行续期,还要在 Web 服务器上重新部署新证书,实属麻烦。另外,腾讯云不提供免费的泛域名证书,泛域名证书需要购买,价格不菲。如果服务器里有多个子域名网站的话,就需要申请多个域名的 SSL 证书,不同域名的 SSL 证书容易弄混,部署起来也颇为头疼。

本篇文章介绍如何使用 acme.sh 脚本客户端来自动部署证书,解放你的双手,摆脱续期证书的一系列烦恼。

一. 什么是 acme.sh

acme.sh 是一个用 Shell(Unix shell)语言编写的支持 ACME 协议的脚本客户端,可以从 ZeroSSL 签发免费的证书。

其优势在于:

  • 支持签发 ECDSA 证书(ECC 证书)、泛域名证书
  • 简单易学易部署(3分钟即会)
  • 支持几乎所有的操作系统(MacOS、Windows、Linux等)
  • 一个命令就可完成证书的签发、续期和安装
  • 支持 Docker
  • 支持 IPv6
  • 支持创建任务计划自动续期

下文主要从 acme.sh 的 Wiki 中截取重要操作进行说明,详细内容请查看 https://wiki.acme.sh。

二. 安装 acme.sh

首先从最新的 Ubuntu 软件包管理器中更新 ca-certificates 和系统修补程序,否则在生成免费 SSL 时会出现一些问题。

1
2
sudo apt update
sudo apt upgrade ca-certificates

完成后,开始安装 acme.sh:

1
wget -O -  https://get.acme.sh | sh -s email=my@example.com

或者:

1
wget -O -  https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m  my@example.com

其中 my@example.com 需要修改为你自己的电子邮箱。

由于是从 Github 下载 acme.sh 客户端,可能会出现无法连接的情况。如果网络不佳,请多试几次。

如果成功安装,屏幕中应该显示以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> Installing from online archive.
> Downloading https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
> Extracting master.tar.gz
> It is recommended to install socat first.
> We use socat for standalone server if you use standalone mode.
> If you don't use standalone mode, just ignore this warning.
> Installing to /root/.acme.sh
> Installed to /root/.acme.sh/acme.sh
> Installing alias to '/root/.bashrc'
> OK, Close and reopen your terminal to start using acme.sh
> Installing cron job
> Good, bash is found, so change the shebang to use bash as preferred.
> OK
> Install success!

三. 签发证书

推荐使用两种方法来签发证书,分别是 Webroot 模式和 DNS API 模式。

1. Webroot 模式

如果你有一个运行的 Web 服务器,推荐使用 Webroot 模式。只需要你对网站的根目录有写入权限即可。

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

其中 example.com 为网站的域名,/home/wwwroot/example.com 为网站的根目录,例如 nginx 的根目录为 /var/www/html

-d 或者 --domain 参数用来指定你要签发、续期或者吊销证书的域名。你可以指定多个域名,分别用 -d 或者 --domain 参数添加。如果你要申请泛域名证书,更改为 -d example.com -d '*.example.com' 即可。

如果你用 nginx 搭建你的网站,acme.sh 可以使用 nginx 签发证书。请不要担心,acme.sh 会在证书签发后恢复你的 nginx.conf 文件。

1
acme.sh  --issue  -d example.com  --nginx

有时 nginx.conf 文件无法自动被找到,你可以指定它的路径:

1
acme.sh  --issue  -d example.com  --nginx /etc/nginx/nginx.conf

您还可以指定某个网站的配置文件:

1
acme.sh  --issue  -d example.com  --nginx /etc/nginx/conf.d/example.com.conf

2. DNS API 模式

如果你的 Web 服务器使用的不是标准端口,无法通过 80 或者 443 端口访问,那么你只能使用 DNS API 模式。

很多的 DNS 解析提供商都提供相关的 API 便于管理员添加主机记录,例如 DNSPod.cn、阿里云、华为云等。可以在 How to use DNS API 页面中查看相关 DNS 解析提供商对应的设置。

以 DNSPod.cn 为例,你首先需要在 DNSPod 控制台 - 账户中心 中申请 API ID 和 key,然后在终端中将生成的 API ID 和 key 导入到 $DP_Id$DP_Key 变量:

1
2
export DP_Id="123456"
export DP_Key="sADDsdasdgdsf"

然后运行以下命令,签发证书:

1
./acme.sh --issue --dns dns_dp -d example.com -d www.example.com

-d 或者 --domain 参数用来指定你要签发、续期或者吊销证书的域名。你可以指定多个域名,分别用 -d 或者 --domain 参数添加。如果你要申请泛域名证书,更改为 -d example.com -d '*.example.com' 即可。

推荐签发 ECC 证书!内置 ECDSA 公钥的证书一般被称之为 ECC 证书,内置 RSA 公钥的证书就是 RSA 证书。由于 256 位 ECC Key 在安全性上等同于 3072 位 RSA Key,加上 ECC 运算速度更快,ECDHE 密钥交换 + ECDSA 数字签名无疑是最好的选择。由于同等安全条件下,ECC 算法所需的 Key 更短,所以 ECC 证书文件体积比 RSA 证书要小一些[1]

并不是所有浏览器都支持 ECDHE 密钥交换,也就是说 ECC 证书的兼容性要差一些。但是不兼容的平台大多都已经被淘汰,例如 Windows XP。所以依然推荐签发 ECC 证书。你只需要在 --issue 参数后面添加 --keylength ec-256 参数,acme.sh 就会给你签发 ECC 证书。

如果在签发 ZeroSSL 证书时,不停的循环 Order status is processing, lets sleep and retry。可以选择将 CA 更换为 Let’s Encrypt。

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

四. 安装证书

生成证书后,你可能希望将证书安装/复制到 Apache/Nginx 或其他服务器。你必须使用此命令将证书复制到目标文件,请勿使用 ~/.acme.sh/ 文件夹中的证书文件,它们仅供内部使用,文件夹结构将来可能会更改。

Nginx 安装方法:

1
2
3
4
acme.sh --install-cert --ecc -d example.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx force-reload"

如果你签发的是 ECC 证书,需要在 --install-cert 参数后添加 --ecc 参数。默认情况下,证书将每 60 天续期一次(可配置)。续期证书后,Apache/Nginx 服务将通过以下命令自动重新加载:service apache2 force-reloadservice nginx force-reload

请注意:reloadcmd 非常重要。证书可以自动续期,但是如果没有正确的 reloadcmd,证书可能不会刷新到你的服务器(如 nginx 或 apache),那么你的网站将无法在 60 天内显示续期的证书。

五. 续期证书

你无需手动续期证书。所有证书将每 60 天自动续期一次。但是,你也可以强制续期证书:

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

参考资料

  1. Jerry Qu. 开始使用 ECC 证书. (https://imququ.com/post/ecc-certificate.html) August 27, 2016.

使用 acme.sh 自动部署 SSL 证书
https://vickey.fun/2022/03/22/auto-deploy-ssl-certificate-using-acme-sh/
作者
饶玮琪
发布于
2022年3月22日
许可协议