前两个月由于腾讯云 CDN 不支持欠费立刻暂停服务换到了多吉云 CDN。
目前 宝塔 / 1Panel 的免费 SSL 证书都只有 90 天的有效期,虽然可以自动续签,但是续签后还是需要频繁手动更新 CDN 的证书,非常麻烦。
好在多吉云提供了对应的 API,使得我们可以通过脚本的方式自动实现同步 SSL 证书到多吉云 CDN。
功能#
- 🔑 动态生成多吉云 API 访问令牌
- 📤 一键式证书上传与管理
- 🌐 多域名智能证书绑定
- 🗑️ 旧证书清理功能(可选)
- ⏰ 无缝衔接 Let's Encrypt 自动续期
- ✅ 双平台支持(宝塔 / 1Panel)
快速开始#
- 获取多吉云 API 密钥:
- 登录多吉云控制台
- 进入「用户中心」→「密钥管理」
- 创建新密钥对
- 确认证书路径:
- 宝塔面板:
/www/server/panel/vhost/ssl/域名目录/
- 1Panel 可跳过
- 宝塔面板:
配置指南#
编辑脚本中的以下参数:
# 多吉云 AccessKey 和 SecretK
ACCESS_KEY="your_access_key_here" # 替换为你的AccessKey
SECRET_KEY="your_secret_key_here" # 替换为你的SecretKey
# 证书路径配置
FULLCHAIN_PATH="/path/to/fullchain.pem" # 全链证书路径
PRIVKEY_PATH="/path/to/privkey.pem" # 私钥路径
# 域名配置
DOMAINS=("example.com" "cdn.example.com" "www.example.com") # 需要绑定的域名列表
# 旧证书处理策略
DELETE_OLD_CERT=false # true=自动删除旧证书 | false=保留历史证书
部署指南#
1Panel#
- 进入证书管理界面
- 创建 / 编辑证书:
- 启用「自动续签」
- 启用「推送证书到本地目录」
- 选择目录
- 启用「申请后执行脚本」
- 粘贴本脚本内容
- 修改证书路径为:
# 证书路径
FULLCHAIN_PATH="./fullchain.pem"
PRIVKEY_PATH="./privkey.pem"
宝塔#
- 创建定时任务:
- 任务类型:Shell 脚本
- 任务名称:随意
- 执行周期:每月 1 号 01:30 执行一次
- 执行用户:root
- 脚本内容:粘贴本脚本内容
- 配合自动续签 Let’s Encrypt 证书定时任务
/www/server/panel/pyenv/bin/python /www/server/panel/class/acme_v2.py –renew=1
理论上可以实现放养多吉云 CDN 的证书。
保存后执行一次任务,如果显示下面信息即已经完成证书的同步:
证书上传成功!
证书ID:12345
证书已成功绑定到 www.vinking.top
证书已成功绑定到 vinking.top
证书ID 12344 删除成功。
----------------------------------------------------------------------------
★[2024-12-26 16:01:29] Successful
----------------------------------------------------------------------------
代码思路#
获取密钥 & 生成 AccessToken
#
多吉云的 API 具有验证机制,使用前需要在控制台的 密钥管理 获取 AccessKey
以及 SecretKey
,然后根据 AccessKey
和 SecretKey
生成 AccessToken
。
AccessToken
的生成过程是将请求地址和请求内容拼接后,使用 SecretKey
进行 HMAC-SHA1
加密,然后将得到的加密值与 AccessKey
用冒号连接起来。具体的生成算法可以参考文档 验证机制 。
# 多吉云 AccessKey 和 SecretKey
ACCESS_KEY="xxxx"
SECRET_KEY="xxxxxx"
function generateAccessToken() {
local apiPath="$1"
local body="$2"
local signStr=$(echo -e "${apiPath}\n${body}")
local sign=$(echo -n "$signStr" | openssl dgst -sha1 -hmac "$SECRET_KEY" | awk '{print $NF}')
local accessToken="$ACCESS_KEY:$sign"
echo "$accessToken"
}
生成了 AccessToken
后,只需要在请求头中加上 Authorization: TOKEN <AccessToken>
即可通过验证。
找到宝塔的域名证书 & 上传证书#
在 /www/server/panel/vhost/ssl/
目录下,可以找到宝塔所有以域名命名的文件夹,文件夹内包含这个域名对应的完整证书链 fullchain.pem
以及私钥 privkey.pem
。
这里推荐给域名及其所有子域名使用同一个泛域名证书,可以实现一次性将域名及其所有子域名完成证书同步。
以域名 vinking.top
为例,完整证书链文件和私钥文件的目录如下:
FULLCHAIN_PATH="/www/server/panel/vhost/ssl/vinking.top/fullchain.pem"
PRIVKEY_PATH="/www/server/panel/vhost/ssl/vinking.top/privkey.pem"
获取到域名证书后,需要通过 POST 的方式向 https://api.dogecloud.com/cdn/cert/upload.json
提交证书内容。上传成功后需要获取证书 ID,以便将刚才上传的证书绑定到域名。
# 宝塔面板 Let's Encrypt 证书路径
FULLCHAIN_PATH="/www/server/panel/vhost/ssl/vinking.top/fullchain.pem"
PRIVKEY_PATH="/www/server/panel/vhost/ssl/vinking.top/privkey.pem"
# 证书备注名
CURRENT_DATE=$(date +"%y/%m/%d")
NOTE="Certificate $CURRENT_DATE"
# 需要绑定的域名列表
DOMAINS=("xxxxx.com" "cdn.xxxxx.com" "www.xxxxx.com")
# 上传证书到多吉云
function uploadCert() {
local note="$1"
local certFile="$2"
local privateKeyFile="$3"
local certContent=$(<"$certFile")
local privateKeyContent=$(<"$privateKeyFile")
local encodedCert=$(echo "$certContent" | jq -sRr @uri)
local encodedPrivateKey=$(echo "$privateKeyContent" | jq -sRr @uri)
local body="note=$note&cert=$encodedCert&private=$encodedPrivateKey"
local accessToken=$(generateAccessToken "/cdn/cert/upload.json" "$body")
local response=$(curl -s -X POST "https://api.dogecloud.com/cdn/cert/upload.json" \
-H "Authorization: TOKEN $accessToken" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "$body")
local code=$(echo "$response" | jq -r '.code')
if [ "$code" -eq 200 ]; then
echo "证书上传成功!"
local certId=$(echo "$response" | jq -r '.data.id')
echo "证书 ID:$certId"
bindCert "$certId"
else
local errMsg=$(echo "$response" | jq -r '.msg')
echo "证书上传失败,错误代码:$code,错误信息:$errMsg"
fi
}
# 绑定证书
function bindCert() {
local certId="$1"
local responses=()
for domain in "${DOMAINS[@]}"; do
(
local body="id=$certId&domain=$domain"
local accessToken=$(generateAccessToken "/cdn/cert/bind.json" "$body")
local response=$(curl -s -X POST "https://api.dogecloud.com/cdn/cert/bind.json" \
-H "Authorization: TOKEN $accessToken" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data "$body")
local code=$(echo "$response" | jq -r '.code')
if [ "$code" -eq 200 ]; then
echo "证书已成功绑定到 $domain"
else
local errMsg=$(echo "$response" | jq -r '.msg')
echo "绑定证书到 $domain 失败,错误代码:$code,错误信息:$errMsg"
fi
) &
done
wait
}
此文由 Mix Space 同步更新至 xLog
原始链接为 https://www.vinking.top/posts/codes/auto-sync-ssl-certificates-to-dogecloud-cdn