使用 acme.sh 和阿里云 DNS 申请与管理免费泛域名 SSL 证书指南 🔐
使用 acme.sh 和 阿里云 DNS 申请与管理免费泛域名 SSL 证书指南 🔐
📋 目录
- 🌰 简介与特点
- 📦 安装 acme.sh
- 🔑 配置阿里云 DNS API
- 🖋️ 申请泛域名证书
- 📁 安装与部署证书
- ⚙️ Nginx 配置示例
- 🔄 自动续期管理
- 🐛 故障排除
- 📊 多域名管理
- 🔒 安全最佳实践
- 🗑️ 卸载与清理
- 💡 高级用法
- 🎯 总结与提示
🌰 简介与特点
acme.sh 是一个纯 Shell 语言编写的 ACME 协议客户端,专为从 Let’s Encrypt 等证书颁发机构(CA)自动获取和更新 SSL/TLS 证书而设计。它支持泛域名证书(Wildcard Certificate),这意味着一个证书可以保护一个域名及其所有子域名(如 *.example.com
),非常适合拥有多个子域名的场景。
主要特性与优势:
- 完全免费与自动化:依托 Let’s Encrypt 和 ZeroSSL 等服务,提供免费的泛域名证书,并自动化申请和续期流程。
- 强大的兼容性:支持众多的 DNS 提供商 API,通过阿里云 DNS API 可以实现自动化的 DNS 验证,无需手动操作。
- 非侵入式安装:安装简单,所有文件通常位于
~/.acme.sh/
目录下,不会影响系统其他部分。 - 自动续期与维护:自动创建定时任务(cron job)来检查并续期即将过期的证书(Let’s Encrypt 证书有效期通常为 90 天),确保网站持续加密。
GitHub 地址: https://github.com/acmesh-official/acme.sh
中文文档: https://github.com/acmesh-official/acme.sh/wiki/说明
📦 安装 acme.sh
1. 自动安装脚本
1 | # 使用 curl 安装 |
💡 将
your_email@example.com
替换为你自己的邮箱地址,该邮箱用于接收证书相关的通知。
2. 加载环境变量
安装完成后,acme.sh 会自动添加到系统环境变量中,并且会创建一个定时任务来自动续签证书。1
2
3
4
5
6# 重新加载 bash 配置(或重新打开终端)
source ~/.bashrc
# 验证安装
acme.sh --version
# ✅ 应该显示版本信息
3. 创建符号链接(可选)
1 | # 创建全局访问链接 |
🔑 配置阿里云 DNS API
使用 DNS API 方式是申请泛域名证书(*.example.com
)的推荐方式,因为它可以实现全自动验证和续期。
1. 获取阿里云 API 密钥
- 登录阿里云控制台 → RAM 访问控制。
- 创建用户:建议创建一个专用于 API 调用的子用户(不推荐使用主账户),并勾选”OpenAPI 调用访问”。
- 添加权限:为该子用户添加
AliyunDNSFullAccess
(管理云解析(DNS)的权限)策略。 - 保存 AccessKey:创建成功后,复制并妥善保存 AccessKey ID 和 AccessKey Secret。
2. 设置环境变量
将获取到的 API 密钥设置为环境变量,供 acme.sh
使用:1
2
3
4
5
6
7
8
9# 设置阿里云 API 密钥 (当前Shell会话有效)
export Ali_Key="你的阿里云AccessKey ID"
export Ali_Secret="你的阿里云AccessKey Secret"
# 永久保存到 acme.sh 的账户配置文件中 (推荐方式)
echo "SAVED_Ali_Key='你的阿里云AccessKey ID'" >> ~/.acme.sh/account.conf
echo "SAVED_Ali_Secret='你的阿里云AccessKey Secret'" >> ~/.acme.sh/account.conf
# 🔒 设置配置文件权限
chmod 600 ~/.acme.sh/account.conf
⚠️ 重要安全提示:
- 避免在命令行中直接使用
export
后接明文密钥,以免被 shell 历史记录记录。- 强烈建议使用
echo
追加到account.conf
文件的方式,acme.sh 会自动读取其中的SAVED_Ali_Key
和SAVED_Ali_Secret
变量。- 确保
~/.acme.sh/account.conf
的文件权限设置正确,防止未授权访问。
🖋️ 申请泛域名证书
1. 申请证书命令
1 | # 基本命令 - 申请泛域名证书 |
2. 测试模式(首次建议)
Let’s Encrypt 生产环境有速率限制,初次调试建议先用测试环境(--staging
)避免触发限制。1
2
3
4
5
6
7# 使用 Let's Encrypt 的测试环境(Staging)
acme.sh --issue --dns dns_ali \
-d '*.example.com' \
-d 'example.com' \
--server letsencrypt \
--staging \
--debug
测试成功,确认无误后,移除 --staging
和 --debug
参数,再次运行命令以申请正式证书。
3. 证书申请过程
执行命令后,acme.sh 会:
- 根据你的域名(如
example.com
)自动在阿里云 DNS 中添加一条用于验证的 TXT 记录(记录名通常为_acme-challenge.example.com
)。 - 等待 DNS 记录 propagate(通常需要几秒到几分钟)。
- 向 CA 机构(如 Let’s Encrypt)完成域名所有权验证。
- 验证成功后,自动删除刚才添加的 TXT 记录(保持 DNS 清洁)。
- 最终下载并保存泛域名证书到
~/.acme.sh/*.example.com/
目录下。
📁 安装与部署证书
证书申请成功后,默认保存在 ~/.acme.sh/
目录下,但不建议直接让 Web 服务器(如 Nginx)使用该目录下的证书文件,因为该目录结构是 acme.sh 内部管理的,且续期后证书文件会更新。你应该使用 --install-cert
命令将证书文件复制到指定位置。
1. Nginx 证书安装
1 | # 创建证书存放目录 (按需修改路径) |
--reloadcmd
参数非常重要:它指定了证书自动续期后需要执行的命令,通常是重载 Web 服务器以使新证书生效。请确保此命令正确无误。
2. Apache 证书安装
1 | # 创建证书目录 |
3. 通用证书安装(仅复制)
1 | # 如果你在其他地方管理重载逻辑,可以只复制证书文件 |
⚙️ Nginx 配置示例
1. SSL 服务器配置片段
1 | # /etc/nginx/snippets/ssl_example.com.conf |
2. HTTPS 服务器块示例
1 | # /etc/nginx/conf.d/example.com_ssl.conf |
3. HTTP 重定向到 HTTPS
1 | # /etc/nginx/conf.d/example.com_redirect.conf |
4. 测试并应用配置
1 | # 测试 Nginx 配置语法是否正确 |
🔄 自动续期管理
acme.sh 的核心优势之一是其全自动续期能力。
1. 自动续期原理
- 安装时,acme.sh 会自动为你创建一个 cron 定时任务。
- 该任务每天凌晨自动运行,检查所有已颁发证书的有效期。
- 如果证书距离过期小于 30 天,则会自动执行续期操作。
- 续期成功后,会执行你之前通过
--install-cert
设置的--reloadcmd
命令(如systemctl reload nginx
),使新证书立即生效。
1 | # 查看现有的 cron 任务(通常可以看到 acme.sh 的任务) |
2. 手动续期命令
虽然通常不需要,但你可以手动强制续期:1
2
3
4
5# 手动强制续期特定证书
acme.sh --renew -d 'example.com' --force
# 启用调试模式查看续期详情
acme.sh --renew -d 'example.com' --force --debug
3. 检查证书状态
1 | # 查看 acme.sh 管理的所有证书列表 |
🐛 故障排除
1. 常见错误与解决
DNS API 验证失败:
- 症状:执行
--issue
命令时超时或报错。 - 排查:确保阿里云 RAM 用户的
AliyunDNSFullAccess
权限已正确附加;仔细检查Ali_Key
和Ali_Secret
是否填写正确,并无多余空格。 - 命令:
acme.sh --issue --dns dns_ali -d '*.example.com' --debug 2
(开启调试模式查看详细输出)。
- 症状:执行
证书已过期未自动续期:
- 排查:运行
crontab -l
检查定时任务是否存在;检查~/.acme.sh/account.conf
中的 API 密钥配置是否仍然有效。 - 命令:手动执行
acme.sh --cron
检查自动续期过程。
- 排查:运行
Nginx 重载失败:
- 排查:检查
--reloadcmd
中的命令是否正确(例如,是否需要sudo
);使用nginx -t
检查 Nginx 配置语法。
- 排查:检查
2. 日志文件
- acme.sh 的详细运行日志通常位于:
~/.acme.sh/acme.sh.log
。 - 使用
tail -f ~/.acme.sh/acme.sh.log
可以实时查看日志,方便调试。
📊 多域名管理
1. 申请多个泛域名证书
如果你有多个主域名,需要为每个域名分别申请证书:1
2
3
4
5
6# 为 example.com 申请
acme.sh --issue --dns dns_ali -d '*.example.com' -d 'example.com'
# 为 example.net 申请
acme.sh --issue --dns dns_ali -d '*.example.net' -d 'example.net'
# 为 example.org 申请
acme.sh --issue --dns dns_ali -d '*.example.org' -d 'example.org'
2. 证书管理命令
1 | # 查看 acme.sh 管理的所有证书 |
🔒 安全最佳实践
API 密钥安全:
- 始终使用 RAM 子账户,并遵循最小权限原则,只授予
AliyunDNSFullAccess
权限,而非主账户 AK。 - 将密钥保存在
~/.acme.sh/account.conf
中,并使用chmod 600 ~/.acme.sh/account.conf
设置严格的文件权限。
- 始终使用 RAM 子账户,并遵循最小权限原则,只授予
证书文件权限:
1
2
3
4# 设置严格的证书文件权限
sudo chmod 644 /etc/nginx/ssl/example.com/fullchain.cer # 证书链可读
sudo chmod 600 /etc/nginx/ssl/example.com/private.key # 私钥仅 root 可读
sudo chown root:root /etc/nginx/ssl/example.com/* # 所有者设为 root定期备份:
1
2
3# 备份证书文件和 acme.sh 配置
tar -czf /backup/ssl-certs-$(date +%Y%m%d).tar.gz /etc/nginx/ssl/
tar -czf /backup/acme-config-$(date +%Y%m%d).tar.gz ~/.acme.sh/
🗑️ 卸载与清理
1 | # 优雅地卸载 acme.sh(会清理 cron 任务等) |
卸载前,请确保你已经备份了重要的证书文件,或者已经将证书部署到了安全的地方。
💡 高级用法
1. ECC 证书(推荐)
ECC(椭圆曲线密码学)证书比 RSA 证书更安全、更快速,且密钥长度更短。现代浏览器均支持 ECC。1
2
3
4
5
6
7
8# 申请 ECC 椭圆曲线证书
acme.sh --issue --dns dns_ali -d '*.example.com' --keylength ec-256
# 安装 ECC 证书 (注意使用 --ecc 参数)
acme.sh --install-cert -d 'example.com' --ecc \
--key-file /etc/nginx/ssl/example.com/ecc.key \
--fullchain-file /etc/nginx/ssl/example.com/ecc.cer \
--reloadcmd "systemctl reload nginx"
在 Nginx 配置中,将 ssl_certificate
和 ssl_certificate_key
指向对应的 ECC 文件即可。
2. 更换默认 CA
acme.sh 默认可能使用 ZeroSSL,你可以切换回 Let’s Encrypt:1
2# 设置默认 CA 为 Let's Encrypt
acme.sh --set-default-ca --server letsencrypt
3. 证书自动部署到远程服务器
如果你有多台服务器,可以在续期后自动将证书部署到远程机器:1
2
3acme.sh --deploy -d 'example.com' --deploy-hook ssh \
--deploy-srv "user@server1:/path/to/ssl" \
--deploy-srv "user@server2:/path/to/ssl"
🎯 总结与提示
通过本指南,你应该已经成功使用 acme.sh
和阿里云 DNS API 申请并部署了免费的泛域名 SSL 证书。自动化是 acme.sh 的核心价值,一旦正确设置,证书将在后台静默更新,你几乎无需再手动干预。
核心要点回顾:
- 使用 DNS API 是实现泛域名证书自动化的关键。
- 安全地管理 你的阿里云 API 密钥(RAM 子账户 +
account.conf
)。 --install-cert
命令比直接使用~/.acme.sh/
目录下的证书更可靠。--reloadcmd
参数必须正确设置,以确保续期后服务能加载新证书。- 定期执行
acme.sh --list
或检查日志,确认自动续期工作正常。
💡 提示: 泛域名证书(
*.example.com
)不能保护二级以上的子域名。例如,它能保护blog.example.com
和api.example.com
,但不能保护dev.api.example.com
。如果需要保护多级子域名,需要单独为api.example.com
再申请一个泛域名证书*api.example.com
或具体域名证书。
如果遇到问题,请首先查阅 ~/.acme.sh/acme.sh.log
日志文件,或者开启 --debug
模式运行命令。acme.sh 的 GitHub Wiki 也是非常宝贵的资源。