CA自签名证书创建--证书链生成脚本
完整脚本:生成 CA 并签署网站证书
#!/bin/bash# 配置信息 下面变量按需更改
CA_DIR="/etc/pki/CA"
WEB_DIR="/etc/pki/tls"
CA_CN="MyCompany Root CA"
WEB_DOMAIN="www.a.com"
COUNTRY="CN"
STATE="Beijing"
CITY="Beijing"
ORG="MyCompany"
OU="IT Department"
EMAIL="admin@${WEB_DOMAIN}"
CA_DAYS=3650 # CA证书有效期(10年)
WEB_DAYS=730 # 网站证书有效期(2年)# 创建目录结构
mkdir -p ${CA_DIR}/{private,certs,csr,newcerts,crl} \${WEB_DIR}/{private,certs,csr}
chmod 700 ${CA_DIR}/private ${WEB_DIR}/private# 初始化CA数据库
touch ${CA_DIR}/index.txt
echo "01" > ${CA_DIR}/serial
echo "01" > ${CA_DIR}/crlnumber# 配置文件路径
CA_CONFIG="${CA_DIR}/openssl.cnf"
WEB_CONFIG="${WEB_DIR}/openssl.cnf"# 创建CA配置文件
cat > ${CA_CONFIG} << EOF
[ ca ]
default_ca = CA_default[ CA_default ]
dir = ${CA_DIR}
certs = \$dir/certs
crl_dir = \$dir/crl
database = \$dir/index.txt
new_certs_dir = \$dir/newcerts
certificate = \$dir/certs/ca.crt
private_key = \$dir/private/ca.key
serial = \$dir/serial
crlnumber = \$dir/crlnumber
crl = \$dir/crl/crl.pem
default_days = ${CA_DAYS}
default_crl_days= 30
default_md = sha256
policy = policy_strict[ policy_strict ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional[ req ]
default_bits = 4096
default_keyfile = ca.key
distinguished_name = req_distinguished_name
string_mask = utf8only
x509_extensions = v3_ca[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign[ v3_server ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names[ alt_names ]
DNS.1 = ${WEB_DOMAIN}
DNS.2 = ${WEB_DOMAIN#*.} # 泛域名支持
EOF# 创建网站证书配置文件
cat > ${WEB_CONFIG} << EOF
[ req ]
default_bits = 2096
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_req
string_mask = utf8only[ req_distinguished_name ]
countryName = Country Name (2 letter code)
stateOrProvinceName = State or Province Name
localityName = Locality Name
0.organizationName = Organization Name
organizationalUnitName = Organizational Unit Name
commonName = Common Name
emailAddress = Email Address[ req_ext ]
subjectAltName = @alt_names[ v3_req ]
subjectAltName = @alt_names[ alt_names ]
DNS.1 = ${WEB_DOMAIN}
DNS.2 = ${WEB_DOMAIN#*.}
EOF# 生成CA私钥(带密码保护)
echo "正在生成CA私钥..."
openssl genrsa -aes256 -out ${CA_DIR}/private/ca.key 4096
chmod 400 ${CA_DIR}/private/ca.key# 生成CA证书
echo "正在生成CA证书..."
openssl req -new -x509 -days ${CA_DAYS} -key ${CA_DIR}/private/ca.key \-out ${CA_DIR}/certs/ca.crt -config ${CA_CONFIG} \-subj "/C=${COUNTRY}/ST=${STATE}/L=${CITY}/O=${ORG}/CN=${CA_CN}" \-extensions v3_ca# 生成网站私钥
echo "正在生成网站私钥..."
openssl genrsa -out ${WEB_DIR}/private/${WEB_DOMAIN}.key 2048
chmod 400 ${WEB_DIR}/private/${WEB_DOMAIN}.key# 生成网站证书请求
echo "正在生成网站证书请求..."
openssl req -new -key ${WEB_DIR}/private/${WEB_DOMAIN}.key \-out ${WEB_DIR}/csr/${WEB_DOMAIN}.csr -config ${WEB_CONFIG} \-subj "/C=${COUNTRY}/ST=${STATE}/L=${CITY}/O=${ORG}/OU=${OU}/CN=${WEB_DOMAIN}/emailAddress=${EMAIL}"# 使用CA签署网站证书
echo "正在使用CA签署网站证书..."
openssl ca -batch -config ${CA_CONFIG} -extensions v3_server \-days ${WEB_DAYS} -notext -in ${WEB_DIR}/csr/${WEB_DOMAIN}.csr \-out ${WEB_DIR}/certs/${WEB_DOMAIN}.crt# 生成证书链文件(包含CA证书)
echo "正在生成证书链文件..."
cat ${WEB_DIR}/certs/${WEB_DOMAIN}.crt ${CA_DIR}/certs/ca.crt > \${WEB_DIR}/certs/${WEB_DOMAIN}.chain.crt# 生成吊销列表
echo "正在生成证书吊销列表..."
openssl ca -gencrl -out ${CA_DIR}/crl/crl.pem -config ${CA_CONFIG}echo "证书生成完成!"
echo "CA证书: ${CA_DIR}/certs/ca.crt"
echo "网站证书: ${WEB_DIR}/certs/${WEB_DOMAIN}.crt"
echo "网站私钥: ${WEB_DIR}/private/${WEB_DOMAIN}.key"
echo "证书链: ${WEB_DIR}/certs/${WEB_DOMAIN}.chain.crt"
使用说明
- 保存脚本:将上述代码保存为
generate-ssl-certs.sh
- 赋予执行权限:
chmod +x generate-ssl-certs.sh
- 运行脚本:
sudo ./generate-ssl-certs.sh
- 按提示输入 CA 私钥密码(建议使用强密码)
生成的证书文件
- CA 证书:
/etc/pki/CA/certs/ca.crt
- 网站证书:
/etc/pki/tls/certs/www.a.com.crt
- 网站私钥:
/etc/pki/tls/private/www.a.com.key
- 证书链:
/etc/pki/tls/certs/www.a.com.chain.crt
(包含网站证书和 CA 证书)
配置 Nginx 使用证书
server {listen 443 ssl http2;server_name www.a.com;ssl_certificate /etc/pki/tls/certs/www.a.com.chain.crt;ssl_certificate_key /etc/pki/tls/private/www.a.com.key;# 安全强化配置ssl_protocols TLSv1.3 TLSv1.2;ssl_prefer_server_ciphers on;ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256";ssl_session_cache shared:SSL:10m;ssl_session_timeout 1d;# 其他配置...
}
安全注意事项
-
CA 私钥安全:
- 生成后立即备份到安全位置(如离线存储)
- 限制访问权限:
chmod 400 /etc/pki/CA/private/ca.key
-
证书有效期:
- CA 证书设置为 10 年,网站证书设置为 2 年
- 建立证书监控和续期机制
-
客户端信任:
- 将 CA 证书(
ca.crt
)分发给客户端并导入受信任的根证书存储区
- 将 CA 证书(
这个脚本实现了完整的 CA 证书和网站证书生成流程,遵循了最佳安全实践,适用于生产环境的内部系统或测试环境。