证书生成脚本

元气满满
2025-06-27 / 0 评论 / 0 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2025年06月27日,已超过487天没有更新,若内容或图片失效,请留言反馈。

创建脚本 cert.sh

touch 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"

Test

0

评论 (0)

取消