自签名 SSL 证书一键生成脚本(支持加密私钥及密码文件自动生成)
保存脚本:把脚本复制到服务器,用 vim 或 nano 保存为 generate_ssl.sh(比如用 vim generate_ssl.sh,粘贴内容后按 ESC 输入 :wq 保存)。DOMAIN="example.com"# 改成你的域名(比如 "test.com"、"api.mydomain.com")example.com.key.pass私钥的密码文件已自动设置为 rw-------(
#!/bin/bash
# 自签发SSL证书生成脚本(含加密私钥+密码文件)
# 特点:生成加密私钥时,自动创建密码文件(.key.pass),方便后续配置
###########################################################
# 【核心配置 - 请修改】
###########################################################
KEY_PASSWORD="my_secure_password" # 私钥加密密码(必须修改!)
DOMAIN="example.com" # 你的域名
VALID_DAYS=365 # 有效期(天)
KEY_SIZE=2048 # 密钥长度(2048/4096)
ENCRYPT_KEY=false # 是否加密私钥(true=加密,false=不加密)
OUTPUT_PREFIX="${DOMAIN}" # 输出文件前缀(默认用域名)
# 证书信息(可选修改)
COUNTRY="CN"
STATE="Beijing"
CITY="Haidian"
ORGANIZATION="MyOrg"
ORG_UNIT="IT"
EMAIL="admin@${DOMAIN}"
###########################################################
# 【文件路径定义】
###########################################################
KEY_FILE="${OUTPUT_PREFIX}.key" # 加密私钥文件
CRT_FILE="${OUTPUT_PREFIX}.crt" # 证书文件
PASS_FILE="${OUTPUT_PREFIX}.key.pass" # 密码文件(仅加密时生成)
CSR_FILE="${OUTPUT_PREFIX}.csr" # 中间文件(生成后删除)
###########################################################
# 【帮助信息】
###########################################################
show_help() {
echo "用法: $0 [选项]"
echo "生成自签发证书,加密私钥时会同时生成密码文件(.key.pass)"
echo "选项:"
echo " -d 域名(覆盖默认DOMAIN)"
echo " -y 有效期天数(覆盖VALID_DAYS)"
echo " -s 密钥长度(覆盖KEY_SIZE)"
echo " -e 启用私钥加密(强制生成密码文件)"
echo " -o 输出文件前缀(覆盖OUTPUT_PREFIX)"
echo " -h 显示帮助"
}
###########################################################
# 【解析参数】
###########################################################
while [[ $# -gt 0 ]]; do
case "$1" in
-d) DOMAIN="$2"; OUTPUT_PREFIX="$2"; shift 2 ;;
-y) VALID_DAYS="$2"; shift 2 ;;
-s) KEY_SIZE="$2"; shift 2 ;;
-e) ENCRYPT_KEY=true; shift ;;
-o) OUTPUT_PREFIX="$2"; shift 2 ;;
-h) show_help; exit 0 ;;
*) echo "未知选项: $1"; show_help; exit 1 ;;
esac
done
###########################################################
# 【检查依赖】
###########################################################
if ! command -v openssl &> /dev/null; then
echo "错误:请先安装openssl(yum install openssl 或 apt install openssl)"
exit 1
fi
###########################################################
# 【生成加密私钥+密码文件(核心逻辑)】
###########################################################
echo "生成私钥文件: $KEY_FILE ..."
if [ "$ENCRYPT_KEY" = true ]; then
# 生成加密私钥 -aes256 -des3 可修改替换加密方式
openssl genrsa -aes256 -passout pass:"${KEY_PASSWORD}" -out "$KEY_FILE" "$KEY_SIZE"
# 生成密码文件(仅加密时创建),并设置安全权限(仅所有者可读写)
echo "${KEY_PASSWORD}" > "$PASS_FILE"
chmod 600 "$PASS_FILE" # 关键:限制权限,避免其他用户读取密码
else
# 生成非加密私钥(不生成密码文件)
openssl genrsa -out "$KEY_FILE" "$KEY_SIZE"
fi
# 检查私钥是否生成成功
if [ $? -ne 0 ] || [ ! -f "$KEY_FILE" ]; then
echo "错误:私钥文件生成失败"
rm -f "$PASS_FILE" # 清理可能残留的密码文件
exit 1
fi
###########################################################
# 【生成证书】
###########################################################
echo "生成证书签名请求(CSR)..."
if [ "$ENCRYPT_KEY" = true ]; then
openssl req -new -key "$KEY_FILE" -passin pass:"${KEY_PASSWORD}" \
-out "$CSR_FILE" \
-subj "/C=${COUNTRY}/ST=${STATE}/L=${CITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=${DOMAIN}/emailAddress=${EMAIL}"
else
openssl req -new -key "$KEY_FILE" -out "$CSR_FILE" \
-subj "/C=${COUNTRY}/ST=${STATE}/L=${CITY}/O=${ORGANIZATION}/OU=${ORG_UNIT}/CN=${DOMAIN}/emailAddress=${EMAIL}"
fi
if [ $? -ne 0 ]; then
echo "错误:CSR生成失败,已清理文件"
rm -f "$KEY_FILE" "$PASS_FILE"
exit 1
fi
echo "生成自签名证书: $CRT_FILE ..."
if [ "$ENCRYPT_KEY" = true ]; then
openssl x509 -req -days "$VALID_DAYS" -in "$CSR_FILE" \
-signkey "$KEY_FILE" -passin pass:"${KEY_PASSWORD}" \
-out "$CRT_FILE"
else
openssl x509 -req -days "$VALID_DAYS" -in "$CSR_FILE" \
-signkey "$KEY_FILE" -out "$CRT_FILE"
fi
if [ $? -ne 0 ] || [ ! -f "$CRT_FILE" ]; then
echo "错误:证书生成失败,已清理文件"
rm -f "$KEY_FILE" "$CRT_FILE" "$PASS_FILE"
exit 1
fi
###########################################################
# 【清理与输出结果】
###########################################################
rm -f "$CSR_FILE" # 只删除中间文件
echo "----------------------------------------"
echo "生成成功!以下文件已保存:"
echo "1. 私钥文件: $KEY_FILE"
if [ "$ENCRYPT_KEY" = true ]; then
echo " (已加密)"
echo "2. 密码文件: $PASS_FILE"
echo " (权限已设置为600,仅所有者可读写)"
else
echo " (未加密,无密码文件)"
fi
echo "3. 证书文件: $CRT_FILE"
echo "----------------------------------------"
echo "后续配置示例(以Nginx为例):"
if [ "$ENCRYPT_KEY" = true ]; then
echo "server {"
echo " listen 443 ssl;"
echo " server_name $DOMAIN;"
echo " ssl_certificate $CRT_FILE;"
echo " ssl_certificate_key $KEY_FILE;"
echo " ssl_password_file $PASS_FILE; # 自动读取密码,无需手动输入"
echo "}"
fi
第一步:准备脚本并修改核心配置(最关键)
保存脚本:把脚本复制到服务器,用 vim 或 nano 保存为 generate_ssl.sh(比如用 vim generate_ssl.sh,粘贴内容后按 ESC 输入 :wq 保存)。
修改必须配置的参数:打开脚本,找到「核心配置」部分,必须修改以下 2 项(其他项可选):KEY_PASSWORD="my_secure_password" # 把这里改成你的密码(比如 "mypass_2024",越复杂越好)
DOMAIN="example.com" # 改成你的域名(比如 "test.com"、"api.mydomain.com")其他可选配置(根据需要改):
VALID_DAYS=365:证书有效期(比如改 730 为 2 年)
KEY_SIZE=2048:密钥长度(4096 更安全,可选)
ENCRYPT_KEY=false:默认不加密,想默认加密可以改成 true
第二步:赋予脚本执行权限
脚本需要 “可执行” 权限才能运行,在服务器上执行以下命令:
chmod +x generate_ssl.sh
第三步:运行脚本(3 种常用场景)
根据是否需要加密私钥(以及是否生成密码文件),有 3 种常用运行方式:场景 1:生成加密私钥 + 密码文件(推荐,最常用)
如果需要加密私钥,并且自动生成密码文件(方便后续配置),运行时加 -e 参数:./generate_ssl.sh -e
运行后会看到类似输出:
plaintext
生成私钥文件: example.com.key ...
生成证书签名请求(CSR)...
生成自签名证书: example.com.crt ...
----------------------------------------
生成成功!以下文件已保存:
1. 私钥文件: example.com.key(已加密)
2. 密码文件: example.com.key.pass(权限已设置为600,仅所有者可读写)
3. 证书文件: example.com.crt
----------------------------------------
后续配置示例(以Nginx为例):
server {
listen 443 ssl;
server_name example.com;
ssl_certificate example.com.crt;
ssl_certificate_key example.com.key;
ssl_password_file example.com.key.pass; # 自动读取密码,无需手动输入
}
场景 2:自定义域名 / 有效期等参数(临时修改)
如果想临时改域名、有效期,不需要修改脚本,直接用参数覆盖即可。例如:生成 blog.test.com 的证书,有效期 1 年(365 天),4096 位密钥,且加密私钥:
./generate_ssl.sh -d blog.test.com -y 365 -s 4096 -e参数说明:
-d:指定域名(覆盖脚本中的 DOMAIN)
-y:有效期天数(覆盖 VALID_DAYS)
-s:密钥长度(覆盖 KEY_SIZE)
-e:启用加密(强制生成密码文件)
场景 3:生成不加密的私钥(无需密码文件)
如果不需要加密私钥(比如测试环境临时用),直接运行脚本(不加 -e):
./generate_ssl.sh此时不会生成密码文件,输出中会显示 “未加密,无密码文件”。
第四步:验证生成的文件
运行脚本后,会在当前目录生成以下文件(以 example.com 为例):
文件名 作用 权限(重要)
example.com.key 加密的私钥文件 默认 -rw-r--r--
example.com.key.pass 私钥的密码文件 已自动设置为 rw-------(600 权限,仅你能读写)
example.com.crt 自签名证书文件 默认 -rw-r--r--
检查文件是否存在:运行 ls 命令查看:ls example.com.* # 替换成你的域名前缀
检查密码文件权限(确保安全):ls -l example.com.key.pass
输出应显示 rw-------(只有你能读写,其他人无权访问)。
第五步:后续配置(以 Nginx 为例,自动加载密码)
生成的文件可以直接用于 Nginx、Apache 等服务器,这里以 Nginx 为例,教你如何配置(无需手动输入密码):
把文件放到服务器证书目录(推荐,方便管理):# 创建证书目录(如果没有)
mkdir -p /etc/nginx/ssl
# 移动文件到目录
mv example.com.key example.com.key.pass example.com.crt /etc/nginx/ssl/
修改 Nginx 配置文件(比如 /etc/nginx/conf.d/default.conf):加入以下 SSL 配置(关键是引用 3 个文件):nginx
server {
listen 443 ssl;
server_name example.com; # 你的域名# 引用证书文件
ssl_certificate /etc/nginx/ssl/example.com.crt;
# 引用加密私钥文件
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 引用密码文件(自动读取密码,无需手动输入)
ssl_password_file /etc/nginx/ssl/example.com.key.pass;# 可选:添加SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3; # 支持的TLS版本
ssl_ciphers HIGH:!aNULL:!MD5; # 加密算法
}
验证 Nginx 配置并重启:nginx -t # 检查配置是否正确
systemctl restart nginx # 重启Nginx
此时 Nginx 会自动读取密码文件,启动时不会提示输入密码,直接运行~
更多推荐

所有评论(0)