SSL过期自动续签脚本-腾讯云
效果图,使用教程:申请密钥、改域名、指定你的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" ]; thenecho " 调试模式已启用,使用预定义 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" ]; thenecho "❌ 证书申请失败:"echo "$apply_response" | jq .exit 1fiecho "✅ 证书申请成功, CertificateId: $certificate_id"# 2. 首次等待echo "⏳ 首次等待${initial_wait}秒确保证书进入签发流程..."for ((s=initial_wait; s>0; s--)); doecho -ne "⏱️ 剩余等待时间: ${s}秒\033[0K\r"sleep 1doneecho -e "\n"
fi# 3. 获取下载链接(带重试)
for ((i=1; i<=$max_retry; i++)); doecho " 正在获取下载链接(尝试第${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" ]; thenbreakfiif [ $i -lt $max_retry ]; thenecho "⚠️ 获取失败: $(echo "$download_response" | jq -r '.Response.Error.Message')"echo "⏳ ${retry_interval}秒后重试..."for ((s=retry_interval; s>0; s--)); doecho -ne "⏱️ 下次尝试剩余: ${s}秒\033[0K\r"sleep 1doneecho -e "\n"elseecho "❌ 超过最大重试次数"echo "$download_response" | jq .exit 1fi
done# 4. 下载并处理证书
echo " 下载链接: $download_url"
temp_dir=$(mktemp -d)
temp_zip="$temp_dir/cert.zip"if ! wget -q "$download_url" -O "$temp_zip"; thenecho "❌ 证书下载失败"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" ]; thencert_source_dir="$temp_dir/${domain}_nginx"
fi# 6. 替换Nginx证书(强制覆盖所有文件)
echo " 替换Nginx证书..."
if ! cp -f "$cert_source_dir"/* "$nginx_ssl_dir/"; thenecho "❌ 证书文件复制失败"rm -rf "$temp_dir"exit 1
fi# 7. 重载Nginx配置
echo " 重载Nginx配置..."
if ! $nginx_bin -t; thenecho "❌ Nginx配置测试失败,请手动检查"rm -rf "$temp_dir"exit 1
fiif ! $nginx_bin -s reload; thenecho "❌ Nginx重载失败,请手动检查"rm -rf "$temp_dir"exit 1
fi# 清理临时文件
rm -rf "$temp_dir"
echo " 证书更新完成!当前证书文件:"
ls -lh "$nginx_ssl_dir/${domain}"* 2>/dev/null