在运维网站时,手动维护 SSL 证书不仅繁琐,更面临证书过期导致网站无法访问的风险。本文将手把手教你如何利用 acme.sh 配合 aliyun-cli 实现阿里云 CDN 证书的自动申请、续期、上传到 CAS 以及更新到 CDN 的全自动化流程。

方案背景 链接到标题

我的博客使用 OSS + CDN 部署,主域名为 lixx.cn,同时绑定了 blog.lixx.cn

  • 痛点:手动续期证书并同步到 CDN 耗时耗力。
  • 目标:实现“一次配置,终身无忧”的自动化管理。

1. 准备工作 链接到标题

在开始自动化之前,需要准备好必备工具和权限。

1.1 获取阿里云 RAM 权限 链接到标题

为了安全,建议在阿里云后台创建一个 RAM 子账号,并授予以下最小权限:

  • AliyunDNSFullAccess:用于 acme.sh 自动修改 DNS 解析记录进行身份校验。
  • AliyunCASFullAccess:用于上传新证书到“数字证书管理服务”。
  • AliyunCDNFullAccess:用于更新 CDN 域名的 HTTPS 配置。

1.2 安装核心工具 链接到标题

我们需要在服务器(建议 24 小时开机的 ECS 或 NAS)上安装两个工具:

1
2
3
4
5
6
# 1. 安装 acme.sh (用于申请证书)
curl https://get.acme.sh | sh -s email=your-email@example.com

# 2. 安装 aliyun-cli (用于调用阿里云 API)
# 请根据你的系统到阿里云官网下载安装,配置好 AccessKey
aliyun configure

2. 核心原理:acme.sh 是如何工作的? 链接到标题

在正式配置前,理解其背后的运行逻辑能帮助我们更好地排查问题。

2.1 ACME 协议与 DNS-01 验证 链接到标题

acme.sh 遵循 ACME (Automated Certificate Management Environment) 协议。本文采用的是 DNS-01 验证模式,其过程如下:

  1. 申请acme.sh 向证书颁发机构(如 Let’s Encrypt)发起申请。
  2. 挑战 (Challenge):CA 要求证明你对域名的控制权,给出一个随机 Token。
  3. 验证acme.sh 调用阿里云 DNS API,自动在你的域名下添加一条名为 _acme-challenge 的 TXT 解析记录,内容即为该 Token。
  4. 审核:CA 扫描该 TXT 记录,匹配成功后颁发证书。
  5. 清理acme.sh 自动删除该临时 TXT 记录,保持解析列表整洁。

2.2 触发机制:首次 vs 自动续期 链接到标题

  • 首次触发:通过手动执行 --issue 命令。执行成功后,acme.sh 会将该域名的配置(包括 API 密钥、续期命令等)记录在 ~/.acme.sh/域名/域名.conf 中。
  • 自动续期触发:当你安装 acme.sh 时,它会自动向系统的 Crontab 写入一条定时任务。

2.3 定时原理:它是如何“定时”的? 链接到标题

你可以通过 crontab -l 看到类似下面的一行:

1
24 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
  • 每天检查:这个定时任务每天凌晨会运行一次。
  • 按需续期acme.sh --cron 运行时,并不是每天都重新申请,而是检查本地证书的剩余天数。默认情况下,证书有效期小于 30 天时(通常是证书颁发后的第 60 天),它才会真正发起续期请求。
  • 自动挂载脚本:续期成功后,它会检测你之前是否配置过 reloadcmd。如果有,就会自动执行我们写的 deploy-ssl.sh 脚本。

3. 自动化配置流程 链接到标题

2.1 设置环境变量并首次申请证书 链接到标题

acme.sh 需要通过 API 修改 DNS。我们先临时导出密钥(acme.sh 会自动加密保存,以后不需要再输入)。

1
2
3
4
5
6
7
export Ali_Key="你的AccessKeyID"
export Ali_Secret="你的AccessKeySecret"

# 申请涵盖主域名及子域名的通配符/多域名证书
# --issue: 申请新证书
# --dns dns_ali: 使用阿里云 DNS 验证方式
~/.acme.sh/acme.sh --issue --dns dns_ali -d lixx.cn -d blog.lixx.cn

2.2 编写全自动同步脚本 链接到标题

申请成功后,我们需要一个脚本把证书推送到阿里云 CDN。在项目 scripts/ 目录下创建 deploy-ssl.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
# ------------------------------------------------------------------------------
# 脚本功能:读取本地 acme.sh 证书,上传至阿里云 CAS,并强制同步至所有 CDN 域名
# ------------------------------------------------------------------------------

# 1. 配置基础信息
DOMAIN="lixx.cn"
CDN_DOMAINS="lixx.cn blog.lixx.cn" # 需要同步的域名列表
CERT_PATH="$HOME/.acme.sh/${DOMAIN}_ecc" # acme.sh 默认 ECC 存储路径
CERT_NAME_PREFIX="lixx-cn-$(date +%Y%m%d)" # 证书在云端的显示名称

# 2. 读取证书文件内容
PRIV_KEY=$(cat "$CERT_PATH/$DOMAIN.key")
FULL_CHAIN=$(cat "$CERT_PATH/fullchain.cer")

# 3. 上传证书到阿里云数字证书管理服务 (CAS)
# 这里必须指定 --region cn-hangzhou,因为 CAS 服务的管理中心在杭州
aliyun cas UploadUserCertificate \
    --region cn-hangzhou \
    --CertName "$CERT_NAME_PREFIX" \
    --Cert "$FULL_CHAIN" \
    --Key "$PRIV_KEY"

# 4. 循环更新每个 CDN 域名的 HTTPS 配置
for domain in $CDN_DOMAINS; do
    echo "正在更新域名 HTTPS 配置: $domain ..."
    # SSLProtocol="on" 开启 HTTPS
    # CertType="upload" 表示使用脚本直接上传证书内容
    # SSLPub/SSLPri 分别对应公钥和私钥
    aliyun cdn SetCdnDomainSSLCertificate \
        --region cn-hangzhou \
        --DomainName "$domain" \
        --SSLProtocol "on" \
        --CertType "upload" \
        --SSLPub "$FULL_CHAIN" \
        --SSLPri "$PRIV_KEY"
done

关键操作:给脚本添加执行权限:

1
chmod +x scripts/deploy-ssl.sh

2.3 挂载自动化 Hook (关键) 链接到标题

这一步是灵魂。我们告诉 acme.sh“以后你每次自动续期成功后,就运行一下这个脚本。”

1
2
~/.acme.sh/acme.sh --install-cert -d lixx.cn \
--reloadcmd "/root/codes/lixx/lixx-coder/scripts/deploy-ssl.sh"

注:--reloadcmd 后面必须是脚本的绝对路径。


3. 域名 301 重定向:统一入口 链接到标题

为了让用户访问 blog.lixx.cn 时自动跳转到 lixx.cn,推荐在 CDN 层面做 301 重定向,性能最好。

操作步骤: 链接到标题

  1. 登录阿里云 CDN 控制台 -> 域名管理。
  2. 选中需要跳走的域名(blog.lixx.cn),点击 管理
  3. 进入 缓存配置 -> 自定义重定向
  4. 添加规则:
    • 匹配类型URI
    • 待匹配路径/(.*)
    • 跳转类型HTTP 301
    • 目标 URIhttps://lixx.cn/$1

4. 总结 链接到标题

通过上述方案,我们实现了:

  1. 自动验证:无需手动修改解析记录。
  2. 自动申请:由 acme.sh 负责证书生命周期。
  3. 自动同步:脚本将证书推送到云端 CDN 边缘节点。
  4. 统一跳转:优化 SEO 并统一用户访问体验。

建议:整套流程请部署在 24 小时开机 的服务器上。如果部署在笔记本上,请确保在证书到期前(通常是申请后的 60 天内)有开机联网,否则 Crontab 无法触发自动续期。