创建证书脚本 create-cert.sh
#!/usr/bin/env bash
#set -x
# 输出目录
output_dir=$(date "+%Y-%m-%d-%H-%M")-certificate
inst_msg() {
# 绿色
echo -e "\033[32mINFO: [$(date +"%Y-%m-%d %H:%M:%S")] $1\033[0m"
}
create_secret(){
mkdir -p "$output_dir" || { echo "无法创建目录 $output_dir"; exit 1; }
# 使用第一个域名作为CA证书的CN
local primary_domain="${domains[0]}"
openssl genrsa -out "$output_dir/ca.key" 4096
openssl req -x509 -new -nodes -sha512 -days 365000 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=*.${primary_domain}" \
-key "$output_dir/ca.key" -out "$output_dir/ca.crt"
openssl genrsa -out "$output_dir/server.key" 4096
# 使用第一个域名作为CSR的CN
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=${primary_domain}" \
-key "$output_dir/server.key" -out "$output_dir/server.csr"
}
create_ext(){
# 初始化v3.ext文件
cat > "$output_dir/v3.ext" <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
EOF
# 添加域名
local dns_count=1
for domain in "${domains[@]}"; do
echo "DNS.${dns_count}=${domain}" >> "$output_dir/v3.ext"
echo "DNS.$((dns_count+1))=*.${domain}" >> "$output_dir/v3.ext" # 添加泛域名
((dns_count+=2))
done
# 添加IP地址
local ip_count=1
for ip in "${ips[@]}"; do
echo "IP.${ip_count}=${ip}" >> "$output_dir/v3.ext"
((ip_count++))
done
}
create_zs(){
openssl x509 -req -sha512 -days 365000 \
-extfile "$output_dir/v3.ext" \
-CA "$output_dir/ca.crt" -CAkey "$output_dir/ca.key" \
-CAcreateserial -in "$output_dir/server.csr" \
-out "$output_dir/server.crt"
openssl x509 -inform PEM -in "$output_dir/server.crt" -out "$output_dir/server.cert"
}
create_st(){
create_secret
create_ext
create_zs
}
# 检查是否安装了openssl
if ! command -v openssl &> /dev/null; then
echo "错误: 需要安装openssl才能运行此脚本"
exit 1
fi
# 读取用户输入
read -p "输入证书IP地址(多个IP用空格分隔,如: 192.168.4.4 10.0.0.1): " ip_input
read -p "输入域名(多个域名用空格分隔,如: example.com demo.com): " domain_input
# 将输入转换为数组
IFS=' ' read -ra ips <<< "$ip_input"
IFS=' ' read -ra domains <<< "$domain_input"
# 验证IP地址格式
ip_count=0
for ip in "${ips[@]}"; do
if [[ ! "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "错误: 输入的IP地址格式不正确: $ip"
exit 1
fi
((ip_count++))
done
# 验证域名输入
if [[ ${#domains[@]} -eq 0 ]]; then
echo "错误: 至少需要输入一个域名"
exit 1
fi
# 验证域名格式
for domain in "${domains[@]}"; do
if [[ ! "$domain" =~ ^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]$ ]]; then
echo "错误: 域名格式不正确: $domain"
exit 1
fi
done
inst_msg "开始生成证书到目录 $output_dir..."
inst_msg "包含的IP地址: ${ips[*]}"
inst_msg "包含的域名: ${domains[*]}"
create_st # 生成证书
# 使用第一个域名作为目录名
primary_domain="${domains[0]}"
if [ -d "${primary_domain}" ]; then
rm -rf "${primary_domain}"
fi
mv "${output_dir}" "${primary_domain}"
# 查询证书到期时间
certificate=$(openssl x509 -in "${primary_domain}/server.crt" -text -noout | grep -A 1 "Not After" | awk -F': ' 'NR==1{print $2}')
echo ""
inst_msg "######## 证书生成完成! ########"
inst_msg "CA证书路径: ${primary_domain}/ca.crt"
inst_msg "服务器证书: ${primary_domain}/server.crt"
inst_msg "服务器密钥: ${primary_domain}/server.key"
inst_msg "包含的IP地址: ${ips[*]}"
inst_msg "包含的域名: ${domains[*]}"
inst_msg "泛域名: *.${domains[0]}, *.${domains[1]}, ..."
inst_msg "证书到期时间: ${certificate}"
inst_msg "验证证书命令: openssl x509 -in ${primary_domain}/server.crt -text -noout"添加权限
chmod +x create-cert.sh执行脚本
create-cert.sh
评论 (0)