先讲一下心路历程。
-
为什么是主域名来使用腾讯的EdgeOne服务?
本来打算edge.nicelee.top
使用腾讯服务作博客的镜像站的,也确实是这么做的。奈何完成后才发现Github Pages有些页面301跳转会直接到主站。
在腾讯这边研究了半天,好像没什么方法将返回的location
字段的host
替换(这点不如Fastly)。
没奈何只能主域名了。原先的Serv00迁移到ser.nicelee.top
。 -
为什么使用上传的证书,而不是系统自动申请免费证书?
腾讯云会验证CNAME,而托管到Cloudflare的域名会自动拉平,验证始终通不过,也就没法自动申请了。 -
错误提示:当前为白名单功能,非白名单用户无法使用该功能,请联系SSL证书特殊处理
这个使用的是API 更新证书内容(证书ID不变)并更新关联的云资源。
根据工单,这个接口UploadUpdateCertificateInstance目前只能更新CLB资源,建议使用接口UpdateCertificateInstance去更新证书。
详情可参考一键更新新旧证书资源。 -
新生成的证书每次证书ID都在变化,那么该如何获取呢?
通过查询近三个月内的获取证书操作日志,找到最新的uploadFromYunAPI
操作,就能找到CertId
。
如果有多个证书,你可以为每个证书分配不同权限,匹配SubAccountUin
即可。
举例如下:
json_output='
{
"Response": {
"AllTotal": 3,
"TotalCount": 3,
"OperateLogs": [
{
"Action": "用户[uin: 10001] 上传 证书[id: foo1]",
"CreatedOn": "2025-07-12 18:18:18",
"Uin": "10001",
"SubAccountUin": "10001",
"CertId": "foo1",
"Type": "uploadFromYunAPI"
},
{
"Action": "用户[uin: 10001] 证书[id: foo0]",
"CreatedOn": "2025-07-12 18:18:18",
"Uin": "10001",
"SubAccountUin": "10001",
"CertId": "foo0",
"Type": "ignoreExpiringNotice-1"
},
{
"Action": "用户[uin: 10001] 上传 证书[id: foo0]",
"CreatedOn": "2025-07-12 16:16:16",
"Uin": "10001",
"SubAccountUin": "10001",
"CertId": "foo0",
"Type": "uploadFromYunAPI"
}
],
"RequestId": "xxx-xxx-xxx-xxx"
}
}'
latest_cert_id=$(echo "$json_output" | \
jq -r '.Response.OperateLogs |
map(select(.Type == "uploadFromYunAPI")) |
sort_by(.CreatedOn) |
last |
.CertId'
)
查询最近certId的脚本
## 获取 cert id
# 密钥参数
secret_id=AKID*********
secret_key=key*********
service="ssl"
host="ssl.tencentcloudapi.com"
action="DescribeCertificateOperateLogs"
version="2019-12-05"
algorithm="TC3-HMAC-SHA256"
# 获取真实当前时间戳
timestamp=$(date +%s)
date=$(date -u -d @$timestamp +"%Y-%m-%d")
# utf8编码请求体
previous_three_months_date=$(date -d "3 months ago" +"%Y-%m-%d 00:00:00")
echo "目标日期是: $previous_three_months_date"
payload=$(echo "{\"Offset\":0,\"Limit\":10,\"StartTime\":\"$previous_three_months_date\"}" | iconv -t utf-8)
# ************* 步骤 1:拼接规范请求串 *************
http_request_method="POST"
canonical_uri="/"
canonical_querystring=""
canonical_headers="content-type:application/json; charset=utf-8\nhost:$host\nx-tc-action:$(echo $action | awk '{print tolower($0)}')\n"
signed_headers="content-type;host;x-tc-action"
hashed_request_payload=$(echo -n "$payload" | openssl sha256 -hex | awk '{print $2}')
canonical_request="$http_request_method\n$canonical_uri\n$canonical_querystring\n$canonical_headers\n$signed_headers\n$hashed_request_payload"
echo "$canonical_request"
# ************* 步骤 2:拼接待签名字符串 *************
credential_scope="$date/$service/tc3_request"
hashed_canonical_request=$(printf "$canonical_request" | openssl sha256 -hex | awk '{print $2}')
string_to_sign="$algorithm\n$timestamp\n$credential_scope\n$hashed_canonical_request"
echo "$string_to_sign"
# ************* 步骤 3:计算签名 *************
secret_date=$(printf "$date" | openssl sha256 -hmac "TC3$secret_key" | awk '{print $2}')
echo $secret_date
# 转二进制
secret_service=$(printf $service | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_date" | awk '{print $2}')
echo $secret_service
secret_signing=$(printf "tc3_request" | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_service" | awk '{print $2}')
echo $secret_signing
signature=$(printf "$string_to_sign" | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_signing" | awk '{print $2}')
echo "$signature"
# ************* 步骤 4:拼接 Authorization *************
authorization="$algorithm Credential=$secret_id/$credential_scope, SignedHeaders=$signed_headers, Signature=$signature"
echo $authorization
# 使用文档中的例子则必定会失败,因为时间戳离当前时间太大
# 根据注释将密钥和时间戳timestamp调整为当前的实际值则可以调用成功
json_output=$(curl -XPOST "https://$host" -d "$payload" -H "Authorization: $authorization" -H "Content-Type: application/json; charset=utf-8" -H "Host: $host" -H "X-TC-Action: $action" -H "X-TC-Timestamp: $timestamp" -H "X-TC-Version: $version")
latest_cert_id=$(echo "$json_output" | \
jq -r '.Response.OperateLogs |
map(select(.Type == "uploadFromYunAPI")) |
sort_by(.CreatedOn) |
last |
.CertId'
)
echo "最新的Type为uploadFromYunAPI的CertId是: $latest_cert_id"
更新指定id的脚本
# 密钥参数
secret_id=AKID*********
secret_key=key*********
latest_cert_id=foobar
service="ssl"
host="ssl.tencentcloudapi.com"
action="UpdateCertificateInstance"
version="2019-12-05"
algorithm="TC3-HMAC-SHA256"
# 获取真实当前时间戳
timestamp=$(date +%s)
date=$(date -u -d @$timestamp +"%Y-%m-%d")
# utf8编码请求体
T_PEM=$(cat /path/to/pem)
T_PEM=$(echo "$T_PEM" | sed ':a;N;$!ba;s/\n/\\n/g')
T_KEY=$(cat /path/to/key)
T_KEY=$(echo "$T_KEY" | sed ':a;N;$!ba;s/\n/\\n/g')
#echo "{\"OldCertificateId\":\"PkxJNlzF\",\"CertificatePublicKey\":\"$T_PEM\",\"CertificatePrivateKey\":\"$T_KEY\",\"ResourceTypes\":[\"teo\"],\"ExpiringNotificationSwitch\":1,\"Repeatable\":true,\"AllowDownload\":true}"
payload=$(echo "{\"OldCertificateId\":\"$latest_cert_id\",\"CertificatePublicKey\":\"$T_PEM\",\"CertificatePrivateKey\":\"$T_KEY\",\"ResourceTypes\":[\"teo\"],\"ExpiringNotificationSwitch\":1,\"Repeatable\":true,\"AllowDownload\":true}" | iconv -t utf-8)
# ************* 步骤 1:拼接规范请求串 *************
http_request_method="POST"
canonical_uri="/"
canonical_querystring=""
canonical_headers="content-type:application/json; charset=utf-8\nhost:$host\nx-tc-action:$(echo $action | awk '{print tolower($0)}')\n"
signed_headers="content-type;host;x-tc-action"
hashed_request_payload=$(echo -n "$payload" | openssl sha256 -hex | awk '{print $2}')
canonical_request="$http_request_method\n$canonical_uri\n$canonical_querystring\n$canonical_headers\n$signed_headers\n$hashed_request_payload"
echo "$canonical_request"
# ************* 步骤 2:拼接待签名字符串 *************
credential_scope="$date/$service/tc3_request"
hashed_canonical_request=$(printf "$canonical_request" | openssl sha256 -hex | awk '{print $2}')
string_to_sign="$algorithm\n$timestamp\n$credential_scope\n$hashed_canonical_request"
echo "$string_to_sign"
# ************* 步骤 3:计算签名 *************
secret_date=$(printf "$date" | openssl sha256 -hmac "TC3$secret_key" | awk '{print $2}')
echo $secret_date
# 转二进制
secret_service=$(printf $service | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_date" | awk '{print $2}')
echo $secret_service
secret_signing=$(printf "tc3_request" | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_service" | awk '{print $2}')
echo $secret_signing
signature=$(printf "$string_to_sign" | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_signing" | awk '{print $2}')
echo "$signature"
# ************* 步骤 4:拼接 Authorization *************
authorization="$algorithm Credential=$secret_id/$credential_scope, SignedHeaders=$signed_headers, Signature=$signature"
echo $authorization
# 使用文档中的例子则必定会失败,因为时间戳离当前时间太大
# 根据注释将密钥和时间戳timestamp调整为当前的实际值则可以调用成功
curl -XPOST "https://$host" -d "$payload" -H "Authorization: $authorization" -H "Content-Type: application/json; charset=utf-8" -H "Host: $host" -H "X-TC-Action: $action" -H "X-TC-Timestamp: $timestamp" -H "X-TC-Version: $version"