阿里云使用 acme.sh 自动申请免费证书并持续更新

Last Modified: 2024/09/21

概述

本文分为以下几个部分来介绍如何使用 acme.sh 自动申请免费证书并持续更新:

  • 什么是 acme.sh
  • 安装 acme.sh
  • 签发免费证书
  • 证书自动更新
  • CDN 证书自动更新

什么是 acme.sh

acme 是 “Automated Certificate Management Environment” 首字母的缩写,它是一种协议,用于自动化与证书颁发机构(CA)之间的交互,以便于在服务器上自动获取和管理 SSL/TLS 证书。acme.sh 是一个基于 acme 协议的 shell 脚本,可以用来申请免费的证书。它的另一个好处是自动更新证书。别小看这一点,由于免费证书有效期一般只有 90 天,虽然不算太短,但是你可能会忘记更新证书,这时候 acme.sh 的自动更新功能就非常实用了。

acme.sh 支持众多 CA,如果不指定,现在默认的 CA 是 ZeroSSL,并不是大家熟知的 Let's Encrypt。更多关于 acme.sh 的介绍可以参考 wiki

安装 acme.sh

首先登录上你的服务器,然后执行以下命令的任意一个安装 acme.sh:

# 通过 curl 安装
curl https://get.acme.sh | sh -s email=my@example.com
# 或者通过 wget 安装
wget -O -  https://get.acme.sh | sh -s email=my@example.com

除此之外,还可以使用 Git 克隆的方式安装:

git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install -m my@example.com

安装脚本会替你自动完成以下三件事:

  • 1、拷贝 acme.sh 到 ~/.acme.sh/ 目录下。之后签发的所有的证书也会放在这个目录下。
  • 2、创建一个 acme.sh 别名:acme.sh=~/.acme.sh/acme.sh。别名就是一个快捷方式,你可以直接使用 acme.sh 命令来执行 acme.sh 脚本而不用每次输入完整的脚本路径。
  • 3、创建一个cron 任务,该任务每天会检查证书,并必要的情况下自动更新证书。

什么是必要的情况呢?默认情况下,acme.sh 会每隔 60 天自动更新证书,当然这是可配置的。这也是可理解的,毕竟免费证书的有效期只有 90 天。

签发免费证书

我们这里介绍如何使用阿里云的域名 API 自动签发免费证书。如果你不是阿里云用户,可以参考这里,总有一个适合你。

以我这个网站为例,我要指定的域名是 verytools.net*.verytools.net,首先需要设置好阿里云 RAM 账号的 AccessKey 和 SecretKey,然后执行以下命令:

export Ali_Key="<AccessKey>"
export Ali_Secret="<SecretKey>"
acme.sh --issue --dns dns_ali -d verytools.net -d *.verytools.net

注:*.verytools.net 并不包含 verytools.net。我希望我的网站能直接通过 verytools.net 访问,同时还需要支持一些子域名,例如:cdn.verytools.net 或 api.verytools.net,所以在签发证书时需同时指定一个泛域名和一个普通域名。* 代表任意子域名,以后想添加新的子域名,该证书也能支持。

好了,那么 Ali_Key 和 Ali_Secret 究竟如何获取?首先你需要登录阿里云账号,进入控制台搜索 RAM访问控制,或者点击这里直达访问控制

如上图,添加一个新用户,名称可随意,注意勾选OpenAPI 调用访问,用户创建完成后,注意保存 AccessKey ID 和 AccessKey Secret,这便是上面的 Ali_Key 和 Ali_Secret 需要配置的值,然后给用户添加 AliyunDNSFullAccess 权限。

执行完上面的命令后,证书会被签发到 ~/.acme.sh/verytools.net_ecc 目录下,使用 ls 命令可以查生成的证书文件:

total 36K
-rw-r--r-- 1 root root 2.7K Aug 29 17:45 ca.cer
-rw-r--r-- 1 root root 4.1K Aug 29 17:45 fullchain.cer
-rw-r--r-- 1 root root 1.5K Aug 29 17:45 verytools.net.cer
-rw-r--r-- 1 root root  822 Aug 29 17:45 verytools.net.conf
-rw-r--r-- 1 root root  485 Aug 29 17:44 verytools.net.csr
-rw-r--r-- 1 root root  206 Aug 29 17:44 verytools.net.csr.conf
-rw------- 1 root root  227 Jun 30 20:44 verytools.net.key

但是千万不要打这个目录下证书的主意,因为这里证书仅供 acme.sh 内部使用,你应该使用安装证书命令来将证书安装到正确的位置,具体操作会在下面说明。

证书自动更新

首先假设我们的 nginx 中,证书相关的配置如下:

server {
    listen 443 ssl;
    server_name verytools.net;
    ssl_certificate /usr/local/nginx/certs/cert.pem;
    ssl_certificate_key /usr/local/nginx/certs/key.pem;
    ...
}

显然我们希望将证书安装到 /usr/local/nginx/certs/ 目录下,于是我们可以执行以下命令来安装证书:

acme.sh --install-cert -d verytools.net --key-file /usr/local/nginx/certs/key.pem --fullchain-file /usr/local/nginx/certs/cert.pem --reloadcmd "/usr/local/nginx/sbin/nginx -s reload"

其中 --reloadcmd 参数指定了证书安装成功后,需要执行的命令。该命令的目的是让 nginx 重新加载证书。这里需要特别注意,请根据你的实际情况指定该命令,不管用什么命令,只要能保证 nginx 能够重新加载证书即可。

安装证书只需要执行一次,安装位置、重启命令都会被 acme.sh 记录下来,以后证书更新时,会自动安装到正确的位置,并执行正确的命令。

CDN 证书自动更新

有很多网站都会使用 CDN 来加速静态资源的访问,本站也不例外,静态资源一般也会有自己的域名,例如:cdn.verytools.net。那么 CDN 证书如何自动更新呢?

前面提到过,我们在签发证书时,使用了泛域名 *.verytools.net,所以生成的证书也可以用于 cdn.verytools.net。我们完全可以将这个证书配置到 CDN 的 https 配置部分。除了手动配置外,我们可以使用阿里云的 API 来自动完成这个过程。

具体的 API 可以参考 SetCdnDomainSSLCertificate - 设置CDN域名证书,当然阿里云也提供了 SDK,可以直接使用 SDK 来调用 API,点这里直达SDK下载地址。

你完全可以自己写一个定时任务,监测安装目录下 key.pem 和 cert.pem 是否发生变化,如果发生变化,就调用 API 来更新 CDN 证书。这里不再赘述,有兴趣的可以自己尝试。

这里还是要提醒一下,调用 API 时,需要使用 RAM 账号的 AccessKey 和 SecretKey,所以你必须先创建一个 RAM 账号,然后给该账号添加 AliyunCDNFullAccess 的权限。

有问题吗?点此反馈!

温馨提示:反馈需要登录