如下操作基于 Ubuntu 24.04 环境进行,域名在阿里云解析。
使用 acme.sh 配合阿里云 DNS API,实现支持泛域名的 SSL 证书签发。
acme.sh 安装后会自带 cron 定时任务,实现全自动续期。
特别说明:
阿里云 DNS 插件(dns_ali)是 acme.sh 内置自带的,不需要像系统软件那样单独执行 apt install 或额外下载安装。
实际上,acme.sh 的设计已经将各类 DNS 服务商的适配脚本作为内置插件来管理。
通过官方脚本安装 acme.sh 后,所有支持的 DNS 服务商脚本(包括阿里云的 dns_ali.sh)都会被自动放置到工作目录下的 dnsapi/ 文件夹中。
因此,签发命令的 --dns dns_ali 参数会直接引导 acme.sh 去调用其内部已有的 dns_ali.sh 脚本,整个过程是开箱即用的,无需额外“安装插件”这一独立步骤。
1. 前提准备:创建阿里云 RAM 子用户(安全第一)
不要使用主账号的 AccessKey。创建一个仅拥有 DNS 管理权限的 RAM 子用户,即使密钥泄露也不会危及服务器、账单等其他资源。
- 登录阿里云 RAM 访问控制控制台。
- 身份管理 → 用户 → 创建用户:
- 登录名称:例如 acme-dns
- 访问方式:只勾选“使用永久 AccessKey 访问”(不要开启控制台登录)
- 创建成功后,立即保存 AccessKey ID 和 AccessKey Secret(Secret 只显示一次)。
- 在用户列表中点击该用户 → 权限管理 → 新增授权 → 搜索并勾选系统策略
AliyunDNSFullAccess,授权范围保持“账号级别”。 - 等待约 1 分钟让权限缓存生效。
2. 安装 acme.sh
执行一键安装:
curl https://get.acme.sh | sh -s email=你的邮箱@example.com
source ~/.bashrc
acme.sh -v # 确认安装成功,应显示版本号
安装脚本会自动完成三件事:把程序装到 ~/.acme.sh/、添加 acme.sh 命令别名、注册自动续期的 cron 任务。
受中国大陆境内的网络环境限制,如果执行上述一件安装比较慢甚至无法执行安装时,可以采用如下 Gitee 源码安装 的方式。
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m 你的邮箱@example.com
source ~/.bashrc
acme.sh -v # 确认安装成功,应显示版本号
3. 配置阿里云 DNS API 凭据
将上一步获取的 AccessKey 设置为环境变量(建议写入 ~/.bashrc 以便持久化):
export Ali_Key="你的AccessKeyId"
export Ali_Secret="你的AccessKeySecret"
写入 ~/.bashrc:
echo 'export Ali_Key="你的AccessKeyId"' >> ~/.bashrc
echo 'export Ali_Secret="你的AccessKeySecret"' >> ~/.bashrc
source ~/.bashrc
注意:acme.sh 对阿里云 DNS 的变量名是 Ali_Key / Ali_Secret,不要误写成 ALIYUN_ACCESS_KEY 等其他形式。
4. 签发泛域名证书(DNS-01 验证)
假设你的主域名是 example.com,需要覆盖所有子域名。关键点:泛域名 *.example.com 不包含主域名本身,因此必须同时用 -d 指定两者。
acme.sh --issue \
--dns dns_ali \
-d example.com \
-d '*.example.com' \
--keylength ec-256
--dns dns_ali:调用阿里云 DNS API 自动添加/清理 TXT 验证记录。--keylength ec-256:签发 ECC 证书(更小、更快,现代浏览器兼容性良好)。如不需要 ECC,可省略此参数,默认签发 RSA 证书。
执行后,acme.sh 会自动在阿里云 DNS 中添加一条 _acme-challenge 的 TXT 记录,等待 Let‘s Encrypt 验证通过后自动删除该记录,无需手动干预。
签发成功后,证书默认存放于 ~/.acme.sh/example.com_ecc/ 目录下。
5. 安装证书到 Nginx 并配置自动重载
--issue 只负责“签发”,还需要把证书安装(复制) 到 Nginx 实际读取的路径,并设置续期后的重载命令。
mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com --ecc \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"
# 非root用户执行时使用需要将 systemctl reload nginx 替换为 sudo /bin/systemctl reload nginx.service
acme.sh --install-cert -d example.com --ecc \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "sudo /bin/systemctl reload nginx.service"
--install-cert 会把证书和私钥复制到指定路径,并将这些路径和 --reloadcmd 写入域名配置文件,后续每次自动续期后都会自动执行 systemctl reload nginx,使新证书立即生效。
Nginx 配置示例:
server {
listen 443 ssl;
server_name example.com *.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 其余反向代理或静态站点配置
location / {
proxy_pass http://127.0.0.1:8080;
}
}
server_name 中同时写入 example.com 和 *.example.com,才能让主域名和子域名都匹配到这张证书。
6. 验证自动续期机制
acme.sh 安装时已自动注册 cron 任务,每天凌晨随机时间检查所有证书的剩余有效期。当证书距离到期少于 30 天时,自动触发续期,续期成功后执行你设置的 --reloadcmd。
可以通过以下命令确认 cron 任务存在:
crontab -l | grep acme.sh
正常应看到类似输出:
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
如需手动测试续期流程(不等待临近过期),可强制续期一次并观察 Nginx 是否被重载:
acme.sh --renew -d example.com --ecc --force
【参考】
Nginx免费SSL自动续期
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,在下面评论区告诉我^_^^_^