本文介绍如何使用 acme.sh 工具来自动更新 HTTPS 泛域名证书。acme.sh 是一个用 Shell 编写的 ACME 协议客户端,它简化了证书的申请和更新过程。
我的 web 服务器使用的是腾讯云服务器,之前 https 证书也是使用腾讯云的免费证书,是采用的手动更新,一年一次也还能接受。但腾讯云前不久公告说在 2024 年 4 月 25 日以后免费的 SSL 证书有效期由 12 个月缩短至 3 个月,继续采用手动方式就有点频繁了,于是使用 acme.sh 通过 dnspod api 的方式实现 https 证书申请和更新的自动化操作。
1. 安装 acme.sh
首先,确保你的服务器系统中已经安装了 acme.sh。你可以通过以下命令来安装它:
curl https://get.acme.sh | sh -s email=my@example.com
# 或者
# wget -O - https://get.acme.sh | sh -s email=my@example.com
source ~/.bashrc
安装脚本会执行以下三个操作:
- 创建并复制
acme.sh
到你的 home 目录 ($HOME
):~/.acme.sh/
,所有的证书都会放在该目录下 - 创建 alias:
acme.sh=~/.acme.sh/acme.sh
- 创建 cronjob 每天检测证书是否过期,发现即将过期的证书将会自动完成证书的更新
安装完成后,你可以使用acme.sh -h
来检查是否安装成功。
2. 生成 DNSPod API 密钥
之前使用的腾讯云免费证书不能使用泛域名,每个子域名都得单独生成一个证书,而使用 ACME 可以申请免费的泛域名证书,但需要通过 DNS 验证的方式,因此需要到域名提供商后台生成 api id 和 key。
我这里是腾讯云 DNSPod,所以在生成证书之前,首先需要从 DNSPod 获取 API Token。访问DNSPod 控制台,点击“头像”,再点击”API 密钥“来创建一个 Token。
3. 签发证书
DNSPod 创建 Token 后,设置环境变量以便 acme.sh 可以使用这些凭证(注意大小写):
export DP_Id='你的ID'
export DP_Key='你的Token'
接下来,使用以下命令来生成泛域名证书:
acme.sh --issue --dns dns_dp -d 'example.com' -d '*.example.com'
请确保将example.com
替换为你的域名。
其他厂商 DNS API 参考文档:https://github.com/acmesh-official/acme.sh/wiki/dnsapi
更多签发证书的方式可以参考官方文档:https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
4. 安装证书
生成证书后,你需要将证书安装到你的 web 服务器配置指定的路径下,以 openresty 为例。以下是安装证书的步骤:
- 创建一个目录来专门存放证书文件:
mkdir -p /etc/nginx/cert.d/example.com_acme
- 使用 acme.sh 来安装证书,并指定证书和密钥的路径:
acme.sh --install-cert -d 'example.com' -d '*.example.com' \
--key-file /etc/nginx/cert.d/example.com_acme/key.pem \
--fullchain-file /etc/nginx/cert.d/example.com_acme/cert.pem \
--reloadcmd "openresty -t && openresty -s reload"
-d *.example.com -d example.com
:执行生成证书命令时配置了哪些域名,这里安装就用哪些域名--key-file /etc/nginx/cert.d/example.com_acme/key.pem
:配置证书密钥文件的安装(复制)位置,配置路径可以自己定义--fullchain-file /etc/nginx/cert.d/example.com_acme/cert.pem
:配置证书文件的安装(复制)位置,配置路径可以自己定义--reloadcmd 'openresty -t && openresty -s reload'
:定义安装成功后的重启命令
5. 配置证书
安装完成后,还需要把证书配置 WEB 服务器中。相关的配置网上比较多,我在这里列一个简单的 Nginx 配置,如果有其他需求,可以自行去了解。
upstream webserver {
server 127.0.0.1:8888;
keepalive 600;
}
server {
listen 443 ssl;
# 自己加任意个域名都行,因为我们用的是泛域名证书
server_name example.com www.example.com sub.example.com;
# 安装证书时配置的证书密钥文件地址
ssl_certificate_key /etc/nginx/cert.d/example.com_acme/key.pem;
# 安装证书时配置的证书文件地址
ssl_certificate /etc/nginx/cert.d/example.com_acme/cert.pem;
ssl_session_timeout 30m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://webserver/;
}
}
server {
listen 80;
server_name example.com www.example.com sub.example.com;
return 301 https://$host$request_uri;
}
配置完成后,重启一下 openresty,https 就生效了。
6. 配置检测更新通知
acme 完成定时任务的执行后支持各种邮件、webhook 等通知机制,参考文档:https://github.com/acmesh-official/acme.sh/wiki/notify
我这里采用的是企业微信 webhook 的方式,通过群聊机器人发送更新通知。先在群设置中添加一个群机器人,获得 webhook 地址,并设置一个关键字(目前暂不支持签名模式)。
export WEIXIN_WORK_WEBHOOK='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx-xxx-xxx-xxx-xxx'
export WEIXIN_WORK_KEYWORD=acme
acme.sh --set-notify --notify-hook weixin_work --notify-level 2
结语
通过以上步骤,我们可以轻松地使用 acme.sh 来自动更新你的 HTTPS 泛域名证书。这不仅提高了安全性,也大大简化了证书管理的复杂性,你用上了吗?