使用Let's Encrypt全自动更新阿里云oss
本方案将指导你完成从零到全自动的SSL证书配置,包括:
在服务器上安装acme.sh
配置阿里云DNS API密钥(权限最小化)
申请泛域名证书(一次配置,覆盖所有子域名)
编写自动部署脚本,将证书推送到OSS
配置定时任务,实现全自动续期
第一步:在服务器上安装 acme.sh
登录你的Linux服务器(使用SSH),执行以下命令:
# 安装acme.sh(自动安装在 ~/.acme.sh/ 目录) curl https://get.acme.sh | sh -s email=你的邮箱@example.com # 重新加载环境变量,使acme.sh命令生效 source ~/.bashrc # 验证安装成功 acme.sh --version
安装脚本会自动创建一个每日执行的定时任务(cron job),这是未来自动续期的心脏<a href="https://blog.csdn.net/weixin_29305337/article/details/158176455" target="_blank" rel="noreferrer" style="cursor: default;"></a>。可以用以下命令查看:
bash
crontab -l | grep acme
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
第二步:创建阿里云RAM子账号并授权
⚠️ 安全警告:千万不要直接使用主账号的AccessKey!必须创建权限最小化的子账号<a href="https://blog.csdn.net/weixin_29305337/article/details/158176455" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
2.1 创建RAM用户
登录<a href="https://ram.console.aliyun.com/" target="_blank" rel="noreferrer">阿里云RAM控制台</a>
点击 身份管理 > 用户 → 创建用户
填写:
登录名称:
acme-dns(可自定义)访问方式:勾选 OpenAPI调用访问(只选这一个)
点击 确定
2.2 记录AccessKey
创建成功后,系统会生成 AccessKey ID 和 AccessKey Secret。立即保存这两串字符,关闭页面后就看不到了!
示例格式:
text
AccessKey ID: LTAI5txxxxxxAccessKey Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
2.3 授权DNS完全访问权限
在用户详情页,点击 权限管理 → 添加权限
搜索框输入
AliyunDNSFullAccess,勾选这个策略点击 确定
这个策略只授权操作云解析DNS的权限,无法访问你的OSS、ECS等其他资源<a href="https://cloud.tencent.com.cn/developer/article/2548435?policyId=1004" target="_blank" rel="noreferrer" style="cursor: default;"></a><a href="https://blog.csdn.net/weixin_29305337/article/details/158176455" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
第三步:配置acme.sh的阿里云DNS API密钥
将刚才获取的AccessKey配置到acme.sh中:
# 编辑acme.sh的配置文件 vim ~/.acme.sh/account.conf
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
在文件末尾添加以下两行(替换成你自己的密钥):
export Ali_Key="LTAI5txxxxxx" # 替换为你的AccessKey ID export Ali_Secret="xxxxxxxxxxxxxxxx" # 替换为你的AccessKey Secret
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
保存退出后,让配置生效:
source ~/.acme.sh/account.conf
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
📌 说明:acme.sh会自动从
account.conf读取这两个环境变量,后续所有操作无需再手动输入<a href="https://developer.aliyun.com/article/1721022" target="_blank" rel="noreferrer" style="cursor: default;"></a><a href="https://cloud.tencent.com.cn/developer/article/2548435?policyId=1004" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
第四步:申请泛域名证书
4.1 选择CA机构(可选)
acme.sh默认使用ZeroSSL,如果你偏爱Let's Encrypt,可以切换:
acme.sh --set-default-ca --server letsencrypt
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
4.2 执行申请命令
假设你的域名是 example.com,图片使用的OSS域名是 img.example.com:
acme.sh --issue --dns dns_ali \ -d "example.com" \ -d "*.example.com" \ --keylength ec-256
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
命令说明<a href="https://developer.aliyun.com/article/1721022" target="_blank" rel="noreferrer" style="cursor: default;"></a><a href="https://itrustssl.cn/column/wiki/225.html" target="_blank" rel="noreferrer" style="cursor: default;"></a>:
<thead></thead><tbody></tbody>| 参数 | 含义 |
|---|---|
--issue | 申请新证书 |
--dns dns_ali | 使用阿里云DNS API进行验证 |
-d "example.com" | 申请主域名证书 |
-d "*.example.com" | 申请泛域名证书(覆盖所有子域名) |
--keylength ec-256 | 使用ECC加密(更安全、更快,推荐) |
💡 注意:如果同时申请泛域名
*.example.com和主域名example.com,建议两个都写上,否则访问https://example.com时会提示证书不匹配<a href="https://developer.aliyun.com/article/1721022" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
4.3 等待签发
执行后,acme.sh会自动:
调用阿里云DNS API,添加
_acme-challenge.example.com的TXT验证记录等待CA机构验证(约10-30秒)
验证通过后,自动删除该TXT记录
证书签发完成
看到类似以下输出表示成功:
[INFO] Your cert is in: /root/.acme.sh/example.com/example.com.cer[INFO] Your cert key is in: /root/.acme.sh/example.com/example.com.key[INFO] The intermediate CA cert is in: /root/.acme.sh/example.com/ca.cer[INFO] And the full chain certs is there: /root/.acme.sh/example.com/fullchain.cer
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
第五步:安装ossutil工具(用于自动推送到OSS)
5.1 下载并安装ossutil
# 下载ossutilwget
- 添加执行权限
chmod +x ossutil64
sudo mv ossutil64 /usr/local/bin/ossutil
- 移动到系统路径
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
5.2 配置ossutil
bash
ossutil config
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
按提示输入:
endpoint:你的OSS Bucket所在地域,例如
oss-cn-hangzhou.aliyuncs.comaccessKeyID:这里需要重新创建一个RAM子账号(和DNS那个分开,权限更小)
stsToken:可以不输入(临时授权用)
accessKeySecret:对应的密钥
📌 最佳实践:建议为ossutil单独创建一个RAM子账号,只授权OSS相关权限(如
AliyunOSSFullAccess),不要复用DNS的那个密钥。
配置文件会保存在 ~/.ossutilconfig<a href="https://www.alibabacloud.com/help/zh/oss/developer-reference/config?spm=a2c63.p38356.879954.17.65d33782KrI9A4" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
第六步:编写自动部署脚本
创建脚本文件:
vim ~/deploy_cert_to_oss.sh
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
将以下内容复制进去(根据实际情况修改变量值):
#!/bin/bash
- ========== 请修改变量值 ==========
DOMAIN="example.com" # 你的主域名
BUCKET_NAME="your-bucket-name" # OSS Bucket名称
- 列出所有需要更新证书的OSS自定义域名(用空格分隔)
OSS_DOMAINS="img.example.com music.example.com oss.example.com"
- =================================
- 证书文件路径(泛域名证书,所有子域名共用)
CERT_PATH="/root/.acme.sh/${DOMAIN}/fullchain.cer"
KEY_PATH="/root/.acme.sh/${DOMAIN}/${DOMAIN}.key"LOG_FILE="/var/log/cert_deploy.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> ${LOG_FILE}
}log "开始部署证书到OSS(共 $(echo ${OSS_DOMAINS} | wc -w) 个域名)"
for OSS_DOMAIN in ${OSS_DOMAINS}; do
log "全部部署完成"
log "正在部署: ${OSS_DOMAIN}"
ossutil bucket-https \
--method put \
--bucket ${BUCKET_NAME} \
--cert ${CERT_PATH} \
--key ${KEY_PATH} \
--domain ${OSS_DOMAIN} \
--force >> ${LOG_FILE} 2>&1
if [ $? -eq 0 ]; then
log "✅ ${OSS_DOMAIN} 证书部署成功"
else
log "❌ ${OSS_DOMAIN} 证书部署失败"
fi
done
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
⚠️ 重要提示:
ossutil bucket-https的具体参数可能因版本不同而有差异。建议先执行ossutil bucket-https --help查看帮助,确认命令格式<a href="https://www.alibabacloud.com/help/zh/oss/developer-reference/config?spm=a2c63.p38356.879954.17.65d33782KrI9A4" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
赋予脚本执行权限:
bash
chmod +x ~/deploy_cert_to_oss.sh
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
6.1 手动测试脚本
先手动执行一次,验证是否能成功推送到OSS:
bash
~/deploy_cert_to_oss.sh
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
检查日志:
bash
cat /var/log/cert_deploy.log
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
如果看到 ✅ 证书部署成功,说明脚本正常。然后去阿里云OSS控制台的域名管理页面确认证书是否已更新。
第七步:配置自动续期 + 自动部署
acme.sh 支持 --renew-hook 参数,可以在每次成功续期后自动执行自定义脚本<a href="https://deepwiki.com/acmesh-official/acme.sh/5.6-creating-custom-deployment-hooks" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
7.1 使用renew-hook重新申请证书
acme.sh --issue --dns dns_ali \-d "example.com" \
--renew-hook "~/deploy_cert_to_oss.sh"
-d "*.example.com" \
--keylength ec-256 \
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
这条命令会:
申请证书(如果已有证书则更新)
证书更新成功后,自动执行
deploy_cert_to_oss.sh脚本
7.2 验证定时任务已配置
acme.sh安装时会自动添加定时任务,每60天检查并续期证书<a href="https://developer.aliyun.com/article/1721022" target="_blank" rel="noreferrer" style="cursor: default;"></a><a href="https://cloud.tencent.com.cn/developer/article/2548435?policyId=1004" target="_blank" rel="noreferrer" style="cursor: default;"></a>。
crontab -l | grep acme
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
应该能看到类似这样的输出:
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
这个定时任务会在每天零点执行,检查所有证书是否需要续期。当续期发生时,会自动触发 --renew-hook 脚本,将新证书推送到OSS。
验证与测试
1. 检查证书信息
acme.sh --info -d example.com
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
2. 强制测试续期
#强制更新证书(注意不要频繁调用,更新有次数限制) acme.sh --renew -d example.com --force --renew-hook "~/deploy_cert_to_oss.sh"
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
3. 浏览器访问验证
用浏览器打开 https://img.yourdomain.com/任意图片.jpg,点击地址栏的锁图标,查看证书详情:
颁发者:Let's Encrypt(或ZeroSSL)
有效期:应该是90天内
使用者:包含
*.yourdomain.com
4. 检查部署日志
bash
cat /var/log/cert_deploy.log
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _33882ae"></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewbox="0 0 12 12" fill="none" class="_9bc997d _28d7e84"></svg>
常见问题与解决
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 申请证书失败,提示DNS错误 | DNS解析延迟 | 添加 --dnssleep 300 参数,等待5分钟再验证<a href="https://developer.aliyun.com/article/1721022" target="_blank" rel="noreferrer" style="cursor: default;"></a> |
ossutil bucket-https 报错 | 版本差异或参数错误 | 先执行 ossutil bucket-https --help 查看正确格式 |
| 证书部署后浏览器不认 | 缓存问题 | 清除CDN缓存(如有),或等待5-10分钟 |
| RAM用户权限不足 | 授权策略有遗漏 | 检查是否添加了 AliyunDNSFullAccess(DNS用)和OSS相关权限(ossutil用) |
最终效果
配置完成后,你什么都不用做。acme.sh的定时任务会自动:
每60天检查证书有效期
到期前30天自动续期
续期成功后自动推送到OSS
你的网站图片始终保持HTTPS访问
一次配置,终身免维护🎉