https客户端证书安装及更新,脚本实现(批量)

背景:

          系统迁移,提供的接口服务地址较多,上百个,都需要安装https证书,若还通过之前博客提到的脚本实现https客户端证书安装及更新,脚本实现,虽比人工快,但还是比较耗时。

处理方式:

        优化脚本,通过引入一个专门存储域名列表的文件,优化脚本的逻辑,实现快速安装,功能和之前的一样,没有就安装,存在就更新。

实现方法:

 1、编写一个专门存储域名列表的文件domains.txt,内容如下,注意每行一个,端口号默认443,如需更改,则域名:端口

2、再创建一个脚本文件batch_install_ssl.sh

#!/bin/bash

# --- 全局变量 ---
DOMAIN_LIST=""
JAVAHOME=""
KEYSTOREPASSWORD=""
KEYSTORE_PATH=""

# --- 用法说明 ---
usage() {
    echo "用法: $0 <域名列表文件> [Javahome] [keystorepassword]"
    echo "示例: $0 domains.txt /usr/lib/jvm/java-11-openjdk-amd64 MyKeystorePassword"
    exit 1
}

# --- 初始化和环境检查 ---
initialize() {
    # 检查参数数量
    if [ $# -lt 1 ]; then
        usage
    fi

    DOMAIN_LIST=$1
    JAVAHOME=${2:-${JAVA_HOME}}
    KEYSTOREPASSWORD=${3:-"changeit"}

    # 检查域名列表文件是否存在
    if [ ! -f "$DOMAIN_LIST" ]; then
        echo "错误: 域名列表文件 $DOMAIN_LIST 不存在!"
        exit 1
    fi

    # 检查 Java 安装目录是否存在
    if [ ! -d "$JAVAHOME" ]; then
        echo "错误: Java 安装目录 $JAVAHOME 不存在!"
        exit 1
    fi

    # 检查 keytool 是否可用
    if ! command -v keytool &> /dev/null; then
        echo "错误: keytool 未找到,请确保 Java 已正确安装并已配置 PATH"
        exit 1
    fi

    # 检查 openssl 是否可用
    if ! command -v openssl &> /dev/null; then
        echo "错误: openssl 未找到,请安装 openssl 工具"
        exit 1
    fi

    # 检测并设置 Keystore 路径
    detect_keystore_path
}

# --- 检测 keystore 文件的真实路径 ---
detect_keystore_path() {
    echo "正在检测 Java Keystore (cacerts) 的路径..."

    # 定义一个可能路径的数组,按常见程度排序
    POSSIBLE_PATHS=(
        "${JAVAHOME}/lib/security/cacerts"           # JDK 9+ (OpenJDK/Oracle)
        "${JAVAHOME}/jre/lib/security/cacerts"       # JDK 8 (Oracle/一些OpenJDK)
        "${JAVAHOME}/lib/security/jssecacerts"       # 备用文件名
    )

    for path in "${POSSIBLE_PATHS[@]}"; do
        if [ -f "$path" ]; then
            KEYSTORE_PATH="$path"
            echo "找到 Keystore 文件: $KEYSTORE_PATH"
            return
        fi
    done

    # 如果循环结束仍未找到文件
    echo "错误: 在 $JAVAHOME 目录下未找到 cacerts 文件!"
    echo "请检查您的 Java 安装是否完整,或手动指定 JAVA_HOME。"
    echo "已搜索的路径包括:"
    printf '  %s\n' "${POSSIBLE_PATHS[@]}"
    exit 1
}

# --- 处理单个域名的函数 ---
process_domain() {
    local DOMAIN_ENTRY=$1
    local DOMAIN=""
    local PORT=""

    echo "========================================"
    echo "正在处理域名条目: $DOMAIN_ENTRY"
    echo "========================================"

    # 智能分割域名和端口
    IFS=':' read -r DOMAIN PORT <<< "$DOMAIN_ENTRY"
    PORT=${PORT:-443} # 如果端口为空,则默认为 443

    if [ -z "$DOMAIN" ]; then
        echo "警告: 跳过无效的空域名条目。"
        return
    fi

    # 创建临时目录
    TEMP_DIR=$(mktemp -d)
    CERT_FILE="$TEMP_DIR/${DOMAIN}.crt"
    # 使用不带端口的域名作为 alias
    ALIAS="$DOMAIN"

    # 下载证书
    echo "正在从 $DOMAIN:$PORT 下载 SSL 证书..."
    if ! openssl s_client -showcerts -connect "$DOMAIN:$PORT" -servername "$DOMAIN" </dev/null 2>/dev/null | openssl x509 -outform PEM > "$CERT_FILE"; then
        echo "错误: 下载证书失败,请检查域名和端口是否可达。"
        rm -rf "$TEMP_DIR"
        return 1
    fi

    # 检查证书有效期
    echo "正在检查证书有效期..."
    expiry_date=$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)
    expiry_timestamp=$(date -d "$expiry_date" +%s)
    current_timestamp=$(date +%s)
    days_left=$(( (expiry_timestamp - current_timestamp) / 86400 ))

    if [ $days_left -le 0 ]; then
        echo "警告: 证书已过期!"
    elif [ $days_left -le 30 ]; then
        echo "警告: 证书将在 $days_left 天后过期,将强制更新。"
    else
        echo "证书有效,剩余 $days_left 天。"
    fi

    # 检查证书是否已存在于 Keystore 中
    if keytool -list -keystore "$KEYSTORE_PATH" -storepass "$KEYSTOREPASSWORD" -alias "$ALIAS" &> /dev/null; then
        echo "证书别名 '$ALIAS' 已存在,正在删除旧证书..."
        keytool -delete -alias "$ALIAS" -keystore "$KEYSTORE_PATH" -storepass "$KEYSTOREPASSWORD" -noprompt
    fi

    # 安装证书到 Java 信任库
    echo "正在安装证书到 Java 信任库 (别名: $ALIAS)..."
    if keytool -importcert -alias "$ALIAS" -file "$CERT_FILE" -keystore "$KEYSTORE_PATH" \
        -storepass "$KEYSTOREPASSWORD" -noprompt; then
        echo "证书安装成功!"
    else
        echo "错误: 安装证书失败!"
        rm -rf "$TEMP_DIR"
        return 1
    fi

    # 清理临时文件
    rm -rf "$TEMP_DIR"
    echo "域名 $DOMAIN_ENTRY 处理完成!"
    return 0
}

# --- 主程序 ---
main() {
    initialize "$@"

    echo "开始批量处理域名列表: $DOMAIN_LIST"
    echo "Java Home: $JAVAHOME"
    echo "Keystore: $KEYSTORE_PATH"
    echo "------------------------------------------------"

    success_count=0
    failure_count=0

    # 逐行读取域名列表文件
    while IFS= read -r DOMAIN_ENTRY || [[ -n "$DOMAIN_ENTRY" ]]; do
        # 跳过空行和以 # 开头的注释行
        if [[ -z "$DOMAIN_ENTRY" || "$DOMAIN_ENTRY" == \#* ]]; then
            continue
        fi

        if process_domain "$DOMAIN_ENTRY"; then
            ((success_count++))
        else
            ((failure_count++))
        fi
        echo "------------------------------------------------"
    done < "$DOMAIN_LIST"

    echo "所有域名处理完成!"
    echo "成功: $success_count, 失败: $failure_count"
}

# --- 脚本入口 ---
main "$@"

3、执行

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值