mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2026-08-13 12:33:30 +02:00
Add Baidu Cloud CDN deploy hook (#6951)
* add Baidu Cloud CDN deploy hook Code generated by GitHub Copilot with Claude Sonnet 4.6. Tested with local environment by human. * inline functions Code generated by OpenAI Codex with GPT-5.5 Sol. Tested with local environment by human.
This commit is contained in:
parent
e828b285ad
commit
cd486cfbb9
1 changed files with 222 additions and 0 deletions
222
deploy/baidu_cdn.sh
Normal file
222
deploy/baidu_cdn.sh
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034,SC2154
|
||||
|
||||
# Deploy hook: Baidu Cloud CDN
|
||||
#
|
||||
# Code generated by GitHub Copilot with Claude Sonnet 4.6 and OpenAI Codex with GPT-5.6 Sol
|
||||
#
|
||||
# API Doc: https://cloud.baidu.com/doc/CDN/s/Zkna2r57w
|
||||
#
|
||||
# Uses the same credential variables as dnsapi/dns_baidu.sh:
|
||||
# export Baidu_AK="your-access-key-id"
|
||||
# export Baidu_SK="your-secret-access-key"
|
||||
#
|
||||
# To deploy to a CDN domain different from the certificate CN
|
||||
# (e.g. wildcard or multi-domain certs):
|
||||
# export DEPLOY_BAIDU_CDN_DOMAIN="cdn.example.com"
|
||||
#
|
||||
# Multiple CDN domains sharing the same certificate:
|
||||
# export DEPLOY_BAIDU_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
|
||||
|
||||
BAIDU_CDN_HOST="cdn.baidubce.com"
|
||||
_BAIDU_CDN_BCE_AUTH_RESULT=""
|
||||
|
||||
baidu_cdn_deploy() {
|
||||
_cdomain="$1"
|
||||
_ckey="$2"
|
||||
_ccert="$3"
|
||||
_cca="$4"
|
||||
_cfullchain="$5"
|
||||
|
||||
_debug _cdomain "$_cdomain"
|
||||
_debug _ckey "$_ckey"
|
||||
_debug _ccert "$_ccert"
|
||||
_debug _cca "$_cca"
|
||||
_debug _cfullchain "$_cfullchain"
|
||||
|
||||
if ! _baidu_cdn_load_credentials; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_getdeployconf DEPLOY_BAIDU_CDN_DOMAIN
|
||||
if [ "$DEPLOY_BAIDU_CDN_DOMAIN" ]; then
|
||||
_savedeployconf DEPLOY_BAIDU_CDN_DOMAIN "$DEPLOY_BAIDU_CDN_DOMAIN"
|
||||
else
|
||||
DEPLOY_BAIDU_CDN_DOMAIN="$_cdomain"
|
||||
fi
|
||||
|
||||
# Build JSON "domains" array from space-separated domain list
|
||||
_domains_json=""
|
||||
for _d in $DEPLOY_BAIDU_CDN_DOMAIN; do
|
||||
_d_e="$(_baidu_cdn_json_escape "$_d")"
|
||||
if [ -z "$_domains_json" ]; then
|
||||
_domains_json="\"${_d_e}\""
|
||||
else
|
||||
_domains_json="${_domains_json},\"${_d_e}\""
|
||||
fi
|
||||
done
|
||||
|
||||
# Build a valid cert name: must start with a letter, allow [A-Za-z0-9-/.], max 65 chars
|
||||
_cert_name="$(printf "%s" "$_cdomain" | sed 's/\*\./wildcard./g;s/[^A-Za-z0-9./]/-/g' | cut -c 1-65)"
|
||||
case "$_cert_name" in
|
||||
[A-Za-z]*) ;;
|
||||
*) _cert_name="c${_cert_name}" ;;
|
||||
esac
|
||||
|
||||
# PEM content is already Base64 inside the -----BEGIN/END----- wrappers.
|
||||
# The API expects the raw PEM as a JSON string, so newlines must be escaped as \n.
|
||||
_cert_pem="$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n')"
|
||||
_key_pem="$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')"
|
||||
|
||||
_debug2 _cert_name "$_cert_name"
|
||||
_debug2 _domains_json "[$_domains_json]"
|
||||
|
||||
# Build JSON payload
|
||||
_payload="{\"domains\":[${_domains_json}],\"certificate\":{\"certName\":\"${_cert_name}\",\"certServerData\":\"${_cert_pem}\",\"certPrivateData\":\"${_key_pem}\"}}"
|
||||
|
||||
# Generate BCE v1 authorization header (query string included in canonical request)
|
||||
_cdn_path="/v2/domain/certificate"
|
||||
_cdn_query="action=put"
|
||||
_ts="$(_utc_date | sed 's/ /T/')Z"
|
||||
_content_type="application/json; charset=utf-8"
|
||||
_payload_hash="$(printf "%s" "$_payload" | _digest sha256 hex)"
|
||||
|
||||
if ! _baidu_cdn_bce_auth "POST" "$_cdn_path" "$_cdn_query" "$BAIDU_CDN_HOST" "$_ts" "3600" "$_content_type" "$_payload_hash"; then
|
||||
_err "Failed to sign request"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_H1="Authorization: $_BAIDU_CDN_BCE_AUTH_RESULT"
|
||||
_H2="x-bce-date: $_ts"
|
||||
_H3="x-bce-content-sha256: $_payload_hash"
|
||||
_H4="Host: $BAIDU_CDN_HOST"
|
||||
_H5=""
|
||||
|
||||
_url="https://${BAIDU_CDN_HOST}${_cdn_path}?${_cdn_query}"
|
||||
response="$(_post "$_payload" "$_url" "" "POST" "$_content_type")"
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "Failed to call Baidu Cloud CDN API"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
|
||||
if _contains "$response" "\"certId\""; then
|
||||
_info "Certificate deployed to Baidu Cloud CDN for: $DEPLOY_BAIDU_CDN_DOMAIN"
|
||||
return 0
|
||||
fi
|
||||
|
||||
_err "Failed to deploy certificate to Baidu Cloud CDN: $response"
|
||||
return 1
|
||||
}
|
||||
|
||||
# BCE v1 signing with canonical query string support.
|
||||
# The CDN endpoint uses ?action=put so it must be included in the canonical request.
|
||||
_baidu_cdn_bce_auth() {
|
||||
_method="$1"
|
||||
_uri="$2"
|
||||
_query="$3"
|
||||
_host="$4"
|
||||
_ts="$5"
|
||||
_expire="$6"
|
||||
_ct="$7"
|
||||
_payload_hash="$8"
|
||||
|
||||
_BAIDU_CDN_BCE_AUTH_RESULT=""
|
||||
|
||||
_auth_prefix="bce-auth-v1/${Baidu_AK}/${_ts}/${_expire}"
|
||||
_signed_headers="content-type;host;x-bce-content-sha256;x-bce-date"
|
||||
_canonical_uri="$(_baidu_cdn_bce_encode_path "$_uri")"
|
||||
|
||||
_host_e="$(printf "%s" "$_host" | _url_encode upper-hex)"
|
||||
_date_e="$(printf "%s" "$_ts" | _url_encode upper-hex)"
|
||||
_ct_e="$(printf "%s" "$_ct" | _url_encode upper-hex)"
|
||||
_hash_e="$(printf "%s" "$_payload_hash" | _url_encode upper-hex)"
|
||||
|
||||
_canonical_headers="content-type:${_ct_e}
|
||||
host:${_host_e}
|
||||
x-bce-content-sha256:${_hash_e}
|
||||
x-bce-date:${_date_e}"
|
||||
|
||||
_canonical_request="${_method}
|
||||
${_canonical_uri}
|
||||
${_query}
|
||||
${_canonical_headers}"
|
||||
|
||||
_sk_hex="$(printf "%s" "$Baidu_SK" | _hex_dump | tr -d " ")"
|
||||
_signing_key="$(_baidu_cdn_hmac_sha256_hexkey "$_sk_hex" "$_auth_prefix")"
|
||||
_signing_key_hex="$(printf "%s" "$_signing_key" | _hex_dump | tr -d " ")"
|
||||
_signature="$(_baidu_cdn_hmac_sha256_hexkey "$_signing_key_hex" "$_canonical_request")"
|
||||
|
||||
_BAIDU_CDN_BCE_AUTH_RESULT="${_auth_prefix}/${_signed_headers}/${_signature}"
|
||||
}
|
||||
|
||||
_baidu_cdn_load_credentials() {
|
||||
Baidu_AK="${Baidu_AK:-$(_readaccountconf_mutable Baidu_AK)}"
|
||||
Baidu_SK="${Baidu_SK:-$(_readaccountconf_mutable Baidu_SK)}"
|
||||
|
||||
Baidu_AK="$(_baidu_cdn_trim_ws "$Baidu_AK")"
|
||||
Baidu_SK="$(_baidu_cdn_trim_ws "$Baidu_SK")"
|
||||
|
||||
if [ -z "$Baidu_AK" ] || [ -z "$Baidu_SK" ]; then
|
||||
_err "Baidu_AK and Baidu_SK are required"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable Baidu_AK "$Baidu_AK"
|
||||
_saveaccountconf_mutable Baidu_SK "$Baidu_SK"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_baidu_cdn_bce_encode_path() {
|
||||
_p="$1"
|
||||
_out=""
|
||||
if [ "${_p#"/"}" != "$_p" ]; then
|
||||
_out="/"
|
||||
fi
|
||||
|
||||
_rest="${_p#/}"
|
||||
while [ -n "$_rest" ]; do
|
||||
_seg="${_rest%%/*}"
|
||||
if [ "$_seg" ]; then
|
||||
if [ -z "$_out" ] || [ "$_out" = "/" ]; then
|
||||
_out="${_out}$(printf "%s" "$_seg" | _url_encode upper-hex)"
|
||||
else
|
||||
_out="${_out}/$(printf "%s" "$_seg" | _url_encode upper-hex)"
|
||||
fi
|
||||
fi
|
||||
if [ "${_rest#*/}" = "$_rest" ]; then
|
||||
break
|
||||
fi
|
||||
_rest="${_rest#*/}"
|
||||
done
|
||||
|
||||
if [ -z "$_out" ]; then
|
||||
_out="/"
|
||||
fi
|
||||
printf "%s" "$_out"
|
||||
}
|
||||
|
||||
_baidu_cdn_trim_ws() {
|
||||
printf "%s" "$1" | tr '\r\n\t' ' ' | tr -s ' ' | sed 's/^ *//;s/ *$//'
|
||||
}
|
||||
|
||||
_baidu_cdn_json_escape() {
|
||||
_s="$1"
|
||||
_s="$(printf "%s" "$_s" | tr -d '\r\n')"
|
||||
printf "%s" "$_s" |
|
||||
sed 's/\\/\\\\/g; s/ /\\t/g' |
|
||||
_baidu_cdn_json_encode
|
||||
}
|
||||
|
||||
_baidu_cdn_json_encode() {
|
||||
_j_str="$(sed 's/"/\\"/g' | sed "s/\r/\\r/g")"
|
||||
printf "%s" "$_j_str" | _hex_dump | _lower_case | sed 's/0a/5c 6e/g' | tr -d ' ' | _h2b | tr -d "\r\n"
|
||||
}
|
||||
|
||||
_baidu_cdn_hmac_sha256_hexkey() {
|
||||
_key_hex="$1"
|
||||
_msg="$2"
|
||||
printf "%s" "$_msg" | _hmac sha256 "$_key_hex" hex
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue