Featured image of post 使用 acme.sh 和 阿里云 DNS 申请与管理免费泛域名 SSL 证书指南 🔐

使用 acme.sh 和 阿里云 DNS 申请与管理免费泛域名 SSL 证书指南 🔐

使用 acme.sh 和 阿里云 DNS 申请与管理免费泛域名 SSL 证书指南 🔐 </

让我帮你整理这份关于使用 acme.sh 和阿里云 DNS 申请与管理免费泛域名 SSL 证书的详细指南。我会优化结构、补充细节,并确保信息的准确性和实用性。

使用 acme.sh 和阿里云 DNS 申请与管理免费泛域名 SSL 证书指南 🔐

📋 目录

🌰 简介与特点

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
2
3
4
5
6
# 使用 curl 安装
curl https://get.acme.sh | sh -s email=your_email@example.com

# 或者使用 wget 安装
wget -O - https://get.acme.sh | sh -s email=your_email@example.com
# 📦 自动下载并安装到 ~/.acme.sh/ 目录

💡 将 your_email@example.com 替换为你自己的邮箱地址,该邮箱用于接收证书相关的通知。

2. 加载环境变量

安装完成后,acme.sh 会自动添加到系统环境变量中,并且会创建一个定时任务来自动续签证书。

1
2
3
4
5
6
# 重新加载 bash 配置(或重新打开终端)
source ~/.bashrc

# 验证安装
acme.sh --version
# ✅ 应该显示版本信息

3. 创建符号链接(可选)

1
2
3
4
5
# 创建全局访问链接
ln -s ~/.acme.sh/acme.sh /usr/local/bin/acme.sh

# 现在可以直接使用
acme.sh --version

🔑 配置阿里云 DNS API

使用 DNS API 方式是申请泛域名证书(*.example.com)的推荐方式,因为它可以实现全自动验证和续期。

1. 获取阿里云 API 密钥

  1. 登录 阿里云控制台 RAM 访问控制
  2. 创建用户:建议创建一个专用于 API 调用的子用户(不推荐使用主账户),并勾选"OpenAPI 调用访问"。
  3. 添加权限:为该子用户添加 AliyunDNSFullAccess(管理云解析(DNS)的权限)策略。
  4. 保存 AccessKey:创建成功后,复制并妥善保存 AccessKey IDAccessKey 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_KeySAVED_Ali_Secret 变量。
  • 确保 ~/.acme.sh/account.conf 的文件权限设置正确,防止未授权访问。

🖋️ 申请泛域名证书

1. 申请证书命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 基本命令 - 申请泛域名证书
acme.sh --issue --dns dns_ali \
  -d '*.example.com' \
  -d 'example.com'
# 🎯 参数说明:
# --dns dns_ali: 使用阿里云 DNS API 进行验证
# -d '*.example.com': 通配符域名,保护所有子域名
# -d 'example.com': 同时申请根域名证书(可选,但建议)

# 明确指定使用 Let's Encrypt(acme.sh 默认可能是 ZeroSSL)
acme.sh --issue --dns dns_ali \
  -d '*.example.com' \
  -d 'example.com' \
  --server letsencrypt

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 会:

  1. 根据你的域名(如 example.com)自动在阿里云 DNS 中添加一条用于验证的 TXT 记录(记录名通常为 _acme-challenge.example.com)。
  2. 等待 DNS 记录 propagate(通常需要几秒到几分钟)。
  3. 向 CA 机构(如 Let’s Encrypt)完成域名所有权验证。
  4. 验证成功后,自动删除刚才添加的 TXT 记录(保持 DNS 清洁)。
  5. 最终下载并保存泛域名证书到 ~/.acme.sh/*.example.com/ 目录下。

📁 安装与部署证书

证书申请成功后,默认保存在 ~/.acme.sh/ 目录下,但不建议直接让 Web 服务器(如 Nginx)使用该目录下的证书文件,因为该目录结构是 acme.sh 内部管理的,且续期后证书文件会更新。你应该使用 --install-cert 命令将证书文件复制到指定位置。

1. Nginx 证书安装

1
2
3
4
5
6
7
8
# 创建证书存放目录 (按需修改路径)
sudo mkdir -p /etc/nginx/ssl/example.com/

# 安装证书到指定位置
acme.sh --install-cert -d 'example.com' \
  --key-file /etc/nginx/ssl/example.com/private.key \
  --fullchain-file /etc/nginx/ssl/example.com/fullchain.cer \
  --reloadcmd "sudo systemctl reload nginx"

--reloadcmd 参数非常重要:它指定了证书自动续期后需要执行的命令,通常是重载 Web 服务器以使新证书生效。请确保此命令正确无误。

2. Apache 证书安装

1
2
3
4
5
6
7
8
# 创建证书目录
sudo mkdir -p /etc/apache2/ssl/example.com/

# 安装证书
acme.sh --install-cert -d 'example.com' \
  --key-file /etc/apache2/ssl/example.com/private.key \
  --fullchain-file /etc/apache2/ssl/example.com/fullchain.cer \
  --reloadcmd "sudo systemctl reload apache2"

3. 通用证书安装(仅复制)

1
2
3
4
5
# 如果你在其他地方管理重载逻辑,可以只复制证书文件
acme.sh --install-cert -d 'example.com' \
  --cert-file /path/to/cert.pem \
  --key-file /path/to/private.key \
  --fullchain-file /path/to/fullchain.pem

⚙️ Nginx 配置示例

1. SSL 服务器配置片段

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# /etc/nginx/snippets/ssl_example.com.conf
# SSL 证书路径(指向 --install-cert 安装的位置)
ssl_certificate /etc/nginx/ssl/example.com/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/example.com/private.key;

# SSL 协议和加密套件优化(增强安全性)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# 启用 SSL session 缓存,提升性能
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

2. HTTPS 服务器块示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# /etc/nginx/conf.d/example.com_ssl.conf
server {
    listen 443 ssl http2;
    server_name example.com *.example.com; # 泛域名匹配

    # 引入 SSL 配置片段
    include /etc/nginx/snippets/ssl_example.com.conf;

    root /var/www/html;
    index index.html index.htm;

    # 其他特定配置...
    location / {
        try_files $uri $uri/ =404;
    }
}

3. HTTP 重定向到 HTTPS

1
2
3
4
5
6
7
8
# /etc/nginx/conf.d/example.com_redirect.conf
server {
    listen 80;
    server_name example.com *.example.com;

    # 强制重定向所有 HTTP 请求到 HTTPS
    return 301 https://$host$request_uri;
}

4. 测试并应用配置

1
2
3
4
5
6
7
8
# 测试 Nginx 配置语法是否正确
sudo nginx -t

# 如果测试成功,重新加载 Nginx 配置(无需完全重启)
sudo systemctl reload nginx

# 检查 Nginx 状态
sudo systemctl status nginx

🔄 自动续期管理

acme.sh 的核心优势之一是其全自动续期能力。

1. 自动续期原理

  • 安装时,acme.sh 会自动为你创建一个 cron 定时任务
  • 该任务每天凌晨自动运行,检查所有已颁发证书的有效期。
  • 如果证书距离过期小于 30 天,则会自动执行续期操作。
  • 续期成功后,会执行你之前通过 --install-cert 设置的 --reloadcmd 命令(如 systemctl reload nginx),使新证书立即生效。
1
2
3
# 查看现有的 cron 任务(通常可以看到 acme.sh 的任务)
crontab -l
# 示例输出:0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

2. 手动续期命令

虽然通常不需要,但你可以手动强制续期:

1
2
3
4
5
# 手动强制续期特定证书
acme.sh --renew -d 'example.com' --force

# 启用调试模式查看续期详情
acme.sh --renew -d 'example.com' --force --debug

3. 检查证书状态

1
2
3
4
5
6
7
8
# 查看 acme.sh 管理的所有证书列表
acme.sh --list

# 查看特定证书的详细信息
acme.sh --info -d 'example.com'

# 使用 OpenSSL 检查证书文件的详细信息和过期时间
openssl x509 -in /etc/nginx/ssl/example.com/fullchain.cer -noout -dates

🐛 故障排除

1. 常见错误与解决

  • DNS API 验证失败

    • 症状:执行 --issue 命令时超时或报错。
    • 排查:确保阿里云 RAM 用户的 AliyunDNSFullAccess 权限已正确附加;仔细检查 Ali_KeyAli_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
2
3
4
5
6
7
8
# 查看 acme.sh 管理的所有证书
acme.sh --list

# 删除某个域名的证书(从 acme.sh 管理中移除,不会删除文件)
acme.sh --remove -d 'example.com'

# 撤销证书(在证书泄露等情况下使用)
acme.sh --revoke -d 'example.com'

🔒 安全最佳实践

  1. API 密钥安全

    • 始终使用 RAM 子账户,并遵循最小权限原则,只授予 AliyunDNSFullAccess 权限,而非主账户 AK。
    • 将密钥保存在 ~/.acme.sh/account.conf 中,并使用 chmod 600 ~/.acme.sh/account.conf 设置严格的文件权限。
  2. 证书文件权限

    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
    
  3. 定期备份

    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
2
3
4
5
# 优雅地卸载 acme.sh(会清理 cron 任务等)
acme.sh --uninstall

# 强制删除整个 acme.sh 目录(如果 --uninstall 不成功)
rm -rf ~/.acme.sh

卸载前,请确保你已经备份了重要的证书文件,或者已经将证书部署到了安全的地方。


💡 高级用法

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_certificatessl_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
3
acme.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.comapi.example.com,但不能保护 dev.api.example.com。如果需要保护多级子域名,需要单独为 api.example.com 再申请一个泛域名证书 *api.example.com 或具体域名证书。

如果遇到问题,请首先查阅 ~/.acme.sh/acme.sh.log 日志文件,或者开启 --debug 模式运行命令。acme.sh 的 GitHub Wiki 也是非常宝贵的资源。

最后更新于 2025-09-28