近期国外SSL证书厂商调整了免费证书的续签规则,一年期的证书全部取消,现在只能申请90天有效期的免费证书。普通web站点可以通过宝塔面板或部署acme.sh等证书自动管理工具来实现自动化申请和部署,但是阿里云之类的CDN服务就只能通过手动或OpenAPI接口来实现证书更新。如果管理的SSL证书比较多,一是容易遗漏,另外纯靠手动更新,这个工作量就很可怕了。
找了一圈资料,这篇文章比较有参考价值: 这篇文章比较有参考价值:申请通配符域名证书并自动推送至阿里云 CDN功能和特性 能够申请域名通配符证书 每两个月自动 renew 证书 自动将证书推送到阿里云 CDN 准备 Linux 服务器(参考系统:Ubuntu 20.04) 在阿里云托管的域名https://www.wqy.ac.cn/p/2311-acme-aliyuncdn/
但是其中 UpdateSSLCert.sh 脚本跑不通(证书申请成功之后无法推送至CDN,提示UploadUserCertificate方法没有权限), 不知是不是阿里云又调整了规则。
仔细查看了下阿里云的OpenAPI文档,发现CDN证书更新只需要调用SetCdnDomainSSLCertificate 这个接口方法就可以,参考上述文章的脚本,直接使用阿里云CLI命令行工具做了下简化:
服务器先按照官方说明安装CLI命令行工具,安装指南_阿里云CLI(CLI)-阿里云帮助中心
#!/usr/bin/env bash# 使用的 OpenAPI
# CAS: https://help.aliyun.com/document_detail/126507.html
# CDN:https://help.aliyun.com/document_detail/106661.html# 可配合 acme.sh 使用的 renewHook 脚本:自动将新证书上传至阿里云并更新对应 CDN 域名,然后删除对应域名的旧证书。
# 每次 API 执行都会检测是否失败,如果失败,会中断脚本执行并返回自定义错误代码。# RIBO: 修改为自己的 AccessKey
AliAccessKeyId="<AliAccessKeyId>"
AliAccessKeySecret="<AliAccessKeySecret>"# shellcheck source=AliyunOpenApiSDK.sh
# RIBO: 这里需要修改 aliyun-openapi-bash-sdk 的路径
#source /root/aliyun-openapi-bash-sdk/AliyunOpenApiSDK.sh# acme.sh 执行 renewHook 时导出的环境变量列表
ACME_ENV_LIST=("CERT_KEY_PATH""CERT_FULLCHAIN_PATH""Le_Domain"
)
# 检查环境变量是否存在
for value in "${ACME_ENV_LIST[@]}" ; do[[ -v "$value" ]] || exit 1
done
unset value
# 获取证书自定义函数
get_cert() {# 使用 sed 删除掉证书文件的空行sed -e "/^$/d" "$CERT_FULLCHAIN_PATH"
}
# 获取密钥自定义函数
get_key() {cat "$CERT_KEY_PATH"
}# shellcheck disable=SC2154
DOMAIN=$Le_Domain
# 证书名称 (替换域名的 . 为 _,以符合阿里云证书名称规范)
CERT_NAME="${DOMAIN//./_}-$(date +%s)"
# 需要更新证书的 CDN 域名列表
# RIBO: 修改这里的 CDN 域名列表
DOMAIN_LIST=("example.com""www.example.com"
)# 设置 CDN 域名列表使用新的证书
for _domain in "${DOMAIN_LIST[@]}"; doaliyun cdn SetCdnDomainSSLCertificate --DomainName "$_domain" --SSLPub="$(get_cert)" --SSLPri="$(get_key)" --CertType upload --SSLProtocol on || exit 103
done
unset _domain
RAM 用户授权也只需两项
- AliyunDNSFullAccess 管理云解析(DNS)的权限
- AliyunCDNFullAccess 管理CDN的权限
实测跑通,目前发现的唯一问题就是随着时间推移,证书管理服务里的列表估计会越来越大,需要定期手动清理掉过期的证书。