背景:
系统迁移,提供的接口服务地址较多,上百个,都需要安装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、执行



31

被折叠的 条评论
为什么被折叠?



