完整脚本

#!/bin/bash
# 配置信息
# 腾讯云账密
SECRET_ID=""     # 密钥ID
SECRET_KEY=""    # 密钥KEY
DOWNLOAD_DIR=""  #SSL证书保存位置
REGION="ap-guangzhou"
API_VERSION="2019-12-05"
SERVICE="ssl"
ACTION_DESCRIBE="DescribeCertificates"
ACTION_DOWNLOAD="DownloadCertificate"

# 颜色配置
RED='\e[1;31m' # 红
GREEN='\e[1;32m' # 绿
YELLOW='\e[1;33m' # 黄
BLUE='\e[1;34m' # 蓝
PINK='\e[1;35m' # 粉红
RES='\e[0m' # 清除颜色

# 检查环境
is_valid() {
    if [[ -z "$SECRET_ID" || -z "$SECRET_KEY" || -z "$DOWNLOAD_DIR" ]]; then
        echo -e "${RED}请填写信息(SECRET_ID: $SECRET_ID; SECRET_KEY: $SECRET_KEY; DOWNLOAD_DIR: $DOWNLOAD_DIR)${RES}"
        exit 0
    fi

    # 解压 ZIP 文件(需安装 unzip)
    if ! command -v unzip &> /dev/null; then
        echo -e "${RED}错误:请先安装 unzip 工具 (apt install unzip / yum install unzip)${RES}"
        exit 0
    fi

    # 检查文件权限
    if [ ! -w "$DOWNLOAD_DIR" ]; then
        echo -e "${RED}当前用户(user: $(whoami))不可对目录($DOWNLOAD_DIR)写${RES}"
        exit 0
    fi
}
is_valid

# 创建目录
mkdir -p "$DOWNLOAD_DIR"

# 生成时间戳和日期(UTC 时间)
timestamp=$(date +%s)
date_utc=$(date -u -d "@$timestamp" +"%Y-%m-%d")

# TC3-HMAC-SHA256 签名函数
generate_signature() {
  local secret_key=$1
  local date=$2
  local service=$3
  local http_request_method=$4
  local canonical_uri=$5
  local canonical_query=$6
  local canonical_headers=$7
  local signed_headers=$8
  local request_body=$9

  # 计算请求体哈希
  local hashed_request=$(echo -n "$request_body" | sha256sum | awk '{print $1}')

  # 构造规范请求(显式处理换行符)
  local canonical_request="${http_request_method}\n${canonical_uri}\n${canonical_query}\n${canonical_headers}\n${signed_headers}\n${hashed_request}"

  # 生成签名密钥链
  local k_date=$(echo -n "$date" | openssl dgst -sha256 -hmac "TC3${secret_key}" | awk '{print $2}')
  local k_service=$(echo -n "$service" | openssl dgst -sha256 -mac HMAC -macopt hexkey:${k_date} | awk '{print $2}')
  local k_signing=$(echo -n "tc3_request" | openssl dgst -sha256 -mac HMAC -macopt hexkey:${k_service} | awk '{print $2}')

  # 生成待签字符串
  local credential_scope="${date}/${service}/tc3_request"
  local hashed_canonical=$(echo -en "$canonical_request" | sha256sum | awk '{print $1}')
  local string_to_sign="TC3-HMAC-SHA256\n${timestamp}\n${credential_scope}\n${hashed_canonical}"

  # 生成最终签名
  echo -en "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt hexkey:${k_signing} | awk '{print $2}'
}

# ---------------------- 获取证书列表 ----------------------
# 定义请求参数
http_method="POST"
canonical_uri="/"
canonical_query=""
canonical_headers="content-type:application/json; charset=utf-8\nhost:ssl.tencentcloudapi.com\n"
signed_headers="content-type;host"
request_body='{"Limit": 100}'

# 生成签名
signature=$(generate_signature "$SECRET_KEY" "$date_utc" "$SERVICE" "$http_method" "$canonical_uri" "$canonical_query" "$canonical_headers" "$signed_headers" "$request_body")

# 发送请求
response=$(curl -s -X POST "https://ssl.tencentcloudapi.com/" \
  -H "Authorization: TC3-HMAC-SHA256 Credential=${SECRET_ID}/${date_utc}/${SERVICE}/tc3_request, SignedHeaders=${signed_headers}, Signature=${signature}" \
  -H "Content-Type: application/json; charset=utf-8" \
  -H "X-TC-Action: ${ACTION_DESCRIBE}" \
  -H "X-TC-Timestamp: ${timestamp}" \
  -H "X-TC-Version: ${API_VERSION}" \
  -H "X-TC-Region: ${REGION}" \
  -d "${request_body}")

# 提取证书ID和名称
cert_ids=($(echo "$response" | grep -o '"CertificateId":"[^"]*"' | cut -d'"' -f4))
names=($(echo "$response" | grep -o '"Domain":"[^"]*"' | cut -d'"' -f4))
cert_end_times=($(echo "$response" | grep -o '"CertEndTime":"[^"]*"' | cut -d'"' -f4))
declare -A cert_map

# ---------------------- 下载证书 ----------------------
echo -e "------------------- 下载证书 -------------------"
for i in "${!cert_ids[@]}"; do
  cert_id=${cert_ids[$i]}
  name=$(echo "${names[$i]}" | tr ' ' '_' | tr -cd '[:alnum:]._-')
  cert_end_time="${cert_end_times[$i*2]} ${cert_end_times[$i*2+1]}"
  echo -e "证书ID: $cert_id"
  echo -e "证书名: $name"
  echo -e "证书过期时间: $cert_end_time"

  if [ -n "${cert_map["$name"]}" ]; then
    ts1=$(date -d "${cert_map["$name"]}" +%s 2>/dev/null)
    ts2=$(date -d "$cert_end_time" +%s 2>/dev/null)
    # 检查转换是否成功
    if [[ -z "$ts1" || -z "$ts2" ]]; then
        echo -e "${RED}ts1或ts2异常(ts1:$ts1;ts2:$ts2)${RES}"
        echo -e "--------------------------------------"
        continue
    fi
    # 比较时间戳
    if (( ! ts1 < ts2 )); then
        echo -e "${YELLOW}当前SSL证书过旧,有新的证书已下载!${RES}"
        echo -e "--------------------------------------"
        continue
    fi
  fi
  cert_map["$name"]=$cert_end_time

  # 构造下载请求
  dl_request_body="{\"CertificateId\": \"$cert_id\"}"
  
  # 生成下载签名(重新计算规范请求)
  dl_signature=$(generate_signature "$SECRET_KEY" "$date_utc" "$SERVICE" "$http_method" "$canonical_uri" "$canonical_query" "$canonical_headers" "$signed_headers" "$dl_request_body")

  # 发送下载请求
  dl_response=$(curl -s -X POST "https://ssl.tencentcloudapi.com/" \
    -H "Authorization: TC3-HMAC-SHA256 Credential=${SECRET_ID}/${date_utc}/${SERVICE}/tc3_request, SignedHeaders=${signed_headers}, Signature=${dl_signature}" \
    -H "Content-Type: application/json; charset=utf-8" \
    -H "X-TC-Action: ${ACTION_DOWNLOAD}" \
    -H "X-TC-Timestamp: ${timestamp}" \
    -H "X-TC-Version: ${API_VERSION}" \
    -H "X-TC-Region: ${REGION}" \
    -d "${dl_request_body}")

  # 提取 ZIP 内容并解码
  zip_base64=$(echo "$dl_response" | grep -o '"Content":"[^"]*"' | cut -d'"' -f4)
  if [ -z "$zip_base64" ]; then
    echo -e "${RED}错误:未找到证书 ZIP 内容(证书名: $name;证书ID: $cert_id)${RES}"
    echo -e "--------------------------------------"
    continue
  fi

  # 解码并保存为 ZIP 文件
  echo "$(echo "$zip_base64" | tr -d '\\' | tr -d '\n')" | base64 -d > "$DOWNLOAD_DIR/${name}.zip"

  unzip -o -q "$DOWNLOAD_DIR/${name}.zip" -d "$DOWNLOAD_DIR/${name}"

  # 查找证书和私钥文件(根据实际 ZIP 结构调整)
  cert_file=$(find "$DOWNLOAD_DIR/${name}" -iname "*.crt" -o -iname "*.pem" | head -1)
  key_file=$(find "$DOWNLOAD_DIR/${name}" -iname "*.key" -o -iname "*.pem" | head -1)

  # 复制到目标目录
  if [ -f "$cert_file" ] && [ -f "$key_file" ]; then
    cp "$cert_file" "$DOWNLOAD_DIR/${name}.crt"
    cp "$key_file" "$DOWNLOAD_DIR/${name}.key"
    echo -e "${GREEN}已更新证书:${name}${RES}"
  else
    echo -e "${RED}错误:未找到证书或私钥文件(ZIP 内容异常)${RES}"
  fi

  # 清理临时文件
  rm -rf "$DOWNLOAD_DIR/${name}.zip" "$DOWNLOAD_DIR/${name}"
  echo -e "--------------------------------------"
done

echo -e "${GREEN}所有证书更新完成${RES}"

如果出现 $'\r': command not found,尝试以下操作。

sed -i 's/\r$//' update_ssl.sh

请把 update_ssl_test.sh 替换为你的脚本名
 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐