使用 acme.sh 与腾讯云 DNS 申请 Let's Encrypt 泛域名证书教程
在国内网络环境下,直接通过 GitHub 安装 acme.sh 常常会遇到连接超时或下载失败的问题。本文记录了在 Debian / WSL2 环境下,利用 Gitee 官方镜像源安装 acme.sh、通过腾讯云 DNS (dns_tencent) 插件完成 Let's Encrypt 泛域名(Wildcard SSL)证书签发,并配置 Nginx 安全免密自动重载的完整最佳实践。
一、 从 Gitee 镜像源安装 acme.sh
acme.sh 是一个纯 Shell 编写的自动化证书管理脚本,不依赖 apt 管理。我们通过 Gitee 官方镜像将其安装到当前普通用户(如 ops)家目录下:
# 1. 从 Gitee 下载安装脚本
curl -Lo /tmp/acme.sh https://gitee.com/neilpang/acme.sh/raw/master/acme.sh
# 2. 执行安装并绑定邮箱
cd /tmp
sh /tmp/acme.sh --install -m your-email@example.com
# 3. 刷新环境变量
source ~/.bashrc
安装完成后,建议将默认的证书颁发机构(CA)从 ZeroSSL 切换为更纯粹、无数量限制的 Let's Encrypt:
acme.sh --set-default-ca --server letsencrypt
二、 配置腾讯云 DNS 插件
由于单文件安装默认不包含云厂商的 DNS API 脚本,需要从 Gitee 的 dnsapi/ 目录手动拉取腾讯云插件:
# 1. 下载腾讯云 DNS 插件源码
curl -Lo ~/.acme.sh/dns_tencent.sh https://gitee.com/neilpang/acme.sh/raw/master/dnsapi/dns_tencent.sh
# 2. 赋予可执行权限
chmod +x ~/.acme.sh/dns_tencent.sh
三、 配置 Nginx 免密自动重载(安全最佳实践)
证书每 90 天需要自动续期。为了让后台定时任务在非交互式环境下能够顺利执行 systemctl reload nginx 而不被密码阻断,我们采用 Linux 标准的 /etc/sudoers.d/ 目录进行精准权限授权。
- 在
/etc/sudoers.d/下创建独立的配置文件:
bash
sudo visudo -f /etc/sudoers.d/acme
- 写入精准的免密提权规则(请将
ops替换为你的实际用户名):
text
ops ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx
(保存并退出:在编辑器中按 Ctrl + O 保存,Enter 确认,再按 Ctrl + X 退出)
- 刷新 systemd 守护进程并测试验证:
bash
sudo systemctl daemon-reload
sudo systemctl reload nginx
若终端无密码提示且瞬间执行成功,说明免密规则已生效。
四、 申请泛域名证书
配置好腾讯云的 API 密钥环境变量后,即可执行签发命令:
# 1. 设置腾讯云 API 凭证
export Tencent_SecretId="你的SecretId"
export Tencent_SecretKey="你的SecretKey"
# 2. 签发并自动安装证书到指定 Nginx 目录
acme.sh --issue \
-d steggy.cn \
-d "*.steggy.cn" \
--dns dns_tencent \
--server letsencrypt \
--key-file /etc/nginx/cert/steggy.cn/steggy.cn.key \
--fullchain-file /etc/nginx/cert/steggy.cn/fullchain.cer \
--reloadcmd "sudo systemctl reload nginx"
五、 验证自动续期任务
安装成功后,acme.sh 会自动在当前用户下注册一个定时任务(crontab),用于每日自动检查并续期。
- 查看定时任务:
bash
crontab -l
输出应类似于:
text
24 5,11,17,23 * * * "/home/ops/.acme.sh"/acme.sh --cron --home "/home/ops/.acme.sh" > /dev/null
- 手动模拟续期测试:
bash
"/home/ops/.acme.sh"/acme.sh --cron --home "/home/ops/.acme.sh" --force
检查日志是否提示续期成功,并且成功触发了 sudo systemctl reload nginx。