阿里云免费ssl证书自动续期脚本

2025-01-03 0 545

前言

由于阿里云现在个人免费的ssl证书,已经从一年的有效期转变成了3个月,经常会忘记去重新生成证书进行替换。深感不方便,最近研究了下api,写下了这个脚本。核心是利用aliyuncli工具,结合在阿里云api的OpenApi,研究出来的,脚本是sh脚本,目前已在CentOS上正常使用。

使用前提

  • ssl证书和域名都是阿里云的,由于我ssl证书和域名是同一个账号,因而只使用了一个accessKey,若有多个可自己再优化一下。
  • accessKey需要有管理ssl证书(AliyunYundunCertFullAccess)的权限,和域名解析(AliyunDNSFullAccess)的权限
  • 使用到的软件有:aliyuncli(阿里云的OpenApi客户端)、jq(在Linux上处理json数据)

    安装环境

[Shell] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
# 安装jq处理json数据
yum install -y jq
# 下载aliyuncli
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz
# 解压并安装aliyuncli
tar xzvf aliyun-cli-linux-latest-amd64.tgz
mv aliyun /usr/local/bin
aliyun version
# 配置aliyuncli身份凭证信息,并删除默认配置
# region可自选,但不确定非杭州有没有影响,因为我账号的资源买的都是杭州的,虽然ssl和域名没有地域区分,可自行校验
aliyun configure set --profile AkProfile --mode AK --access-key-id {自己的accessKeyId} --access-key-secret {AccessKeySecret} --region cn-hangzhou
aliyun configure delete --profile default
aliyun configure list

脚本代码

[Shell] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/bash
# 参数说明, 三个参数的优先级 orderId > domain > date
# --date 2025-02-01 表示要校验的是2025-02-01过期的,默认值为今天,若有且域名在domain_array数组中,则<strong><font color="#FF0000">自动</font></strong>创建证书
# --domain xxxx.xxx.com 若orderId为空,domain不为空,则表示创建此域名证书,并不会校验是否过期,此情况date参数无效
# --orderId 12714600 表示只要监听证书订单详情,订单id在CreateCertificateRequest命令创建证书时返回,并自动解析验证,生成key和pem文件,domain也必须传, 此情况date参数无效
# 证书颁发之后,自动保存key和pem文件到domain_path目录下
# 自行使用crontab 创建定时任务每天执行一次
# 所在省份和城市
province="省份"
locality="城市"
# 证书联系人信息
username="姓名"
phone="手机号"
email="邮箱"
# 根域名生成域名解析使用 必须要是根域名
domain_root="baidu.com"
# 临时设置今天的日期为 2025-02-01
today=$(date +%Y-%m-%d)
# 定义证书存放目录
domain_path="/user/local/ssl/"
# 定义域名数组
domain_array=("www.baidu.com" "www.aliyun.com" "www.52pojie.cn")
# 阿里云区域
aliyun_region="cn-hangzhou"
# 处理域名解析校验
perform_domain_verification() {
    local res="$1"
    # 提取 DNS 验证信息
    local record_domain=$(echo "$res" | jq -r '.RecordDomain')
    local record_value=$(echo "$res" | jq -r '.RecordValue')
    local rr_key_word="${record_domain/.$domain_root/}"
    echo "校验 DNS 记录:"
    echo "域名: $record_domain"
    echo "记录值: $record_value"
    echo "RRKeyWord: $rr_key_word"
    local list_res=$(aliyun alidns DescribeDomainRecords --region "$aliyun_region" --DomainName "$domain_root" --RRKeyWord "$rr_key_word" --ValueKeyWord "$record_value" --SearchMode ADVANCED --Type TXT)
    # 检查返回的 TotalCount
    local total_count=$(echo "$list_res" | jq -r '.TotalCount')
    # 若不存在则创建
    if "$total_count" -eq 0 ]; then
        aliyun alidns AddDomainRecord --region "$aliyun_region" --DomainName "$domain_root" --Type TXT --RR "$rr_key_word" --Value "$record_value"
    fi
}
# 生成证书
generate_certificate_files() {
    local res="$1"
    local domain="$2"
    # 提取证书信息
    local ssl_key=$(echo "$res" | jq -r '.PrivateKey')
    local ssl_pem=$(echo "$res" | jq -r '.Certificate')
    
    echo "$ssl_key" "$domain_path$domain.key"
    echo "$ssl_pem" "$domain_path$domain.pem"
}
# 轮询订单详情
monitor_order() {
    local order_id="$1"
    local domain="$2"
    while truedo
        res=$(aliyun cas DescribeCertificateState --region "$aliyun_region" --OrderId "$order_id")
        order_type=$(echo "$res" | jq -r '.Type')
        # 证书订单申请状态 domain_verify 待域名验证,需查看域名是否有对应的dns解析,若无则添加; certificate 已签发,需生成key和pem文件,并替换到证书目录
        if [[ "$order_type" == "domain_verify" ]]; then
            echo "证书状态为 domain_verify,进行域名解析。"
            # 调用域名解析的函数
            perform_domain_verification "$res"
        elif [[ "$order_type" == "certificate" ]]; then
            echo "证书状态为 certificate,生成 key 和 pem 文件。"
            generate_certificate_files "$res" "$domain"
            break
        else
            echo "证书状态尚未完成"
        fi
        echo "等待 30 秒后重试..."
        sleep 30
    done
}
# 函数:根据域名处理证书创建请求
create_certificate() {
    local domain="$1"
    # 证书-购买、申请和签发自带CSR文件的DV证书。证书扩展服务可通过一步完成DV证书的购买和申请
    res=$(aliyun cas CreateCertificateRequest --region "$aliyun_region" --ProductCode 'digicert-free-1-free' --Username "$username" --Phone "$phone" --Email "$email" --Domain "$domain" --ValidateType DNS)
    echo "创建证书返回 $res"
    order_id=$(echo "$res" | jq -r '.OrderId')
    # 监控证书状态
    monitor_order "$order_id" "$domain"
}
# 函数:校验是否有要过期的证书
check_certificates() {
    # 执行 aliyun cas ListUserCertificateOrder 命令并处理结果
    response=$(aliyun cas ListUserCertificateOrder --region "$aliyun_region" --OrderType CERT)
    echo "命令响应: $response"
    # 使用 jq 处理结果
    local domains=$(echo "$response" | jq -r --arg today "$today" '
    .CertificateOrderList[] |
    select(.EndDate == $today) |
    .CommonName
    ')
    # 检查是否找到了证书 ID
    if [ -z "$domains" ]; then
        echo "没有证书的结束日期是 $today。"
    else
        # 遍历所有找到要过期的域名证书
        for domain in $domains; do
            # 检查域名是否在域名数组中
            if [[ " ${domain_array[@]} " =~ " ${domain} " ]]; then
                echo "域名 $domain 存在于数组中"
                # 调用创建证书的函数
                create_certificate "$domain"
            else
                echo "域名 $domain 不在数组中,跳过。"
            fi
        done
    fi
}
# 主逻辑
while [[ $# -gt 0 ]]; do
    case "$1" in
        --date)
            today="$2"
            shift 2
            ;;
        --domain)
            domain_param="$2"
            shift 2
            ;;
        --orderId)
            order_id_param="$2"
            shift 2
            ;;
        *)
            echo "未知参数: $1"
            exit 1
            ;;
    esac
done
# 判断是否有指定域名
if [ -n "$order_id_param" ]; then
    echo "轮询校验订单是否完成"
    monitor_order "$order_id_param" "$domain_param"
elif [ -n "$domain_param" ]; then
    echo "指定域名:$domain_param,直接调用 create_certificate。"
    create_certificate "$domain_param"
else
    echo "没有指定域名,调用 check_certificates 处理所有域名。"
    check_certificates
fi

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

阿里云免费ssl证书自动续期脚本
上一篇:

已经没有上一篇了!

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务