SSL过期自动续签脚本-腾讯云

发布于:2025-06-26 ⋅ 阅读:(22) ⋅ 点赞:(0)

效果图,使用教程:申请密钥、改域名、指定你的nginx地址。如果要开启调试模式,改true,然后写死一个证书中存在的id进行测试即可 ,配合crontab定时,自动续签
在这里插入图片描述

#!/bin/bash

# 调试模式配置
DEBUG=false  # 设为 true 时使用预定义 CertificateId 直接测试下载流程
DEBUG_CERT_ID="PFLOnElN"  # 预定义的测试用 CertificateId   

# 生产环境配置 密钥申请地址:https://console.cloud.tencent.com/cam/capi   
secret_id="****"
secret_key="****"
domain="yaoqinqin.cn"    
max_retry=3                # 最大重试次数
initial_wait=180           # 首次等待180秒(3分钟)
retry_interval=180         # 重试间隔180秒(3分钟)

# Nginx配置
nginx_ssl_dir="/usr/local/nginx/ssl"       # 证书存储目录
nginx_bin="/usr/local/nginx/sbin/nginx"    # Nginx可执行文件路径

# 腾讯云API签名函数
tencentcloud_api() {
    local service="$1"
    local host="$2"
    local action="$3"
    local payload="$4"
    local version="${5:-2019-12-05}"
    
    local timestamp=$(date +%s)
    local date=$(date -u +%Y-%m-%d)
    local algorithm="TC3-HMAC-SHA256"
    
    # 1. 构造规范请求
    local canonical_request="POST
/

content-type:application/json; charset=utf-8
host:$host
x-tc-action:${action,,}

content-type;host;x-tc-action
$(echo -n "$payload" | openssl sha256 | awk '{print $2}')"

    # 2. 构造待签字符串
    local credential_scope="$date/$service/tc3_request"
    local hashed_canonical_request=$(echo -n "$canonical_request" | openssl sha256 | awk '{print $2}')
    local string_to_sign="$algorithm
$timestamp
$credential_scope
$hashed_canonical_request"

    # 3. 计算签名
    local secret_date=$(echo -n "$date" | openssl sha256 -hmac "TC3$secret_key" | awk '{print $2}')
    local secret_service=$(echo -n "$service" | openssl sha256 -mac HMAC -macopt hexkey:"$secret_date" | awk '{print $2}')
    local secret_signing=$(echo -n "tc3_request" | openssl sha256 -mac HMAC -macopt hexkey:"$secret_service" | awk '{print $2}')
    local signature=$(echo -n "$string_to_sign" | openssl sha256 -mac HMAC -macopt hexkey:"$secret_signing" | awk '{print $2}')

    # 4. 发送请求
    curl -s -X POST "https://$host" \
        -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" \
        -H "X-TC-Region: " \
        -H "Authorization: TC3-HMAC-SHA256 Credential=$secret_id/$credential_scope, SignedHeaders=content-type;host;x-tc-action, Signature=$signature" \
        -d "$payload"
}

# 调试模式跳过申请直接使用预定义 CertificateId
if [ "$DEBUG" = "true" ]; then
    echo "     调试模式已启用,使用预定义 CertificateId: $DEBUG_CERT_ID"
    certificate_id="$DEBUG_CERT_ID"
else
    # 1. 正常流程申请证书
    echo "     正在申请证书 for $domain..."
    apply_response=$(tencentcloud_api "ssl" "ssl.tencentcloudapi.com" "ApplyCertificate" "{\"DvAuthMethod\":\"DNS_AUTO\",\"DomainName\":\"$domain\"}")

    certificate_id=$(echo "$apply_response" | jq -r '.Response.CertificateId')
    if [ -z "$certificate_id" ] || [ "$certificate_id" == "null" ]; then
        echo "❌ 证书申请失败:"
        echo "$apply_response" | jq .
        exit 1
    fi
    echo "✅ 证书申请成功, CertificateId: $certificate_id"

    # 2. 首次等待
    echo "⏳ 首次等待${initial_wait}秒确保证书进入签发流程..."
    for ((s=initial_wait; s>0; s--)); do
        echo -ne "⏱️  剩余等待时间: ${s}\033[0K\r"
        sleep 1
    done
    echo -e "\n"
fi

# 3. 获取下载链接(带重试)
for ((i=1; i<=$max_retry; i++)); do
    echo "     正在获取下载链接(尝试第${i}次)..."
    download_response=$(tencentcloud_api "ssl" "ssl.tencentcloudapi.com" "DescribeDownloadCertificateUrl" "{\"CertificateId\":\"$certificate_id\",\"ServiceType\":\"nginx\"}")
    
    download_url=$(echo "$download_response" | jq -r '.Response.DownloadCertificateUrl')
    if [ -n "$download_url" ] && [ "$download_url" != "null" ]; then
        break
    fi
    
    if [ $i -lt $max_retry ]; then
        echo "⚠️ 获取失败: $(echo "$download_response" | jq -r '.Response.Error.Message')"
        echo "⏳ ${retry_interval}秒后重试..."
        for ((s=retry_interval; s>0; s--)); do
            echo -ne "⏱️  下次尝试剩余: ${s}\033[0K\r"
            sleep 1
        done
        echo -e "\n"
    else
        echo "❌ 超过最大重试次数"
        echo "$download_response" | jq .
        exit 1
    fi
done

# 4. 下载并处理证书
echo "     下载链接: $download_url"
temp_dir=$(mktemp -d)
temp_zip="$temp_dir/cert.zip"

if ! wget -q "$download_url" -O "$temp_zip"; then
    echo "❌ 证书下载失败"
    rm -rf "$temp_dir"
    exit 1
fi

# 5. 解压并处理证书文件(修复目录问题)
echo "     解压证书文件..."
unzip -q -o "$temp_zip" -d "$temp_dir"
rm -f "$temp_zip"

# 处理可能的子目录(腾讯云默认会在zip中创建 domain_nginx 子目录)
cert_source_dir="$temp_dir"
if [ -d "$temp_dir/${domain}_nginx" ]; then
    cert_source_dir="$temp_dir/${domain}_nginx"
fi

# 6. 替换Nginx证书(强制覆盖所有文件)
echo "     替换Nginx证书..."
if ! cp -f "$cert_source_dir"/* "$nginx_ssl_dir/"; then
    echo "❌ 证书文件复制失败"
    rm -rf "$temp_dir"
    exit 1
fi

# 7. 重载Nginx配置
echo "     重载Nginx配置..."
if ! $nginx_bin -t; then
    echo "❌ Nginx配置测试失败,请手动检查"
    rm -rf "$temp_dir"
    exit 1
fi

if ! $nginx_bin -s reload; then
    echo "❌ Nginx重载失败,请手动检查"
    rm -rf "$temp_dir"
    exit 1
fi

# 清理临时文件
rm -rf "$temp_dir"
echo "     证书更新完成!当前证书文件:"
ls -lh "$nginx_ssl_dir/${domain}"* 2>/dev/null


网站公告

今日签到

点亮在社区的每一天
去签到