生成自签证书文件
其实自签证书的步骤很简单:
- 生成CA key文件
- 生成CA请求证书
- 自签CA证书
- 客户端生成域名证书key文件
- 客户端生成csr请求证书
- CA签发证书
写成openssl命令也就几行。下面这个脚本是别人写好的脚本,我拿来学习下
目录结构
]# tree -C ./certs-generator/
tools/certs-generator/
├── ca.cnf
├── flush.sh
├── gen.cert.sh
└── gen.root.sh
0 directories, 4 files
ca.cnf
[ ca ]
default_ca = ROOT_CA
[ ROOT_CA ]
new_certs_dir = ./out/newcerts
certificate = ./out/root.crt
database = ./out/index.txt
private_key = ./out/root.key.pem
serial = ./out/serial
unique_subject = no
default_days = 3650
default_md = sha256
policy = policy_loose
x509_extensions = ca_extensions
copy_extensions = copy
[ policy_loose ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ ca_extensions ]
basicConstraints = CA:false
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
# subjectAltName = IP:127.0.0.1
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
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
# Optionally, specify some defaults.
countryName_default = CN
stateOrProvinceName_default = Shanghai
localityName_default = Pudong
0.organizationName_default = DevOps
organizationalUnitName_default =
emailAddress_default =
[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning
flush.sh
#!/usr/bin/env bash
cd "$(dirname "${BASH_SOURCE[0]}")"
echo 'Removing dir out'
rm -rf out
echo 'Creating output structure'
mkdir out
cd out
mkdir newcerts
touch index.txt
echo "unique_subject = no" > index.txt.attr
echo 1000 > serial
echo 'Done'
gen.root.sh
#!/usr/bin/env bash
cd "$(dirname "${BASH_SOURCE[0]}")"
if [ -f "out/root.crt" ]; then
echo Root certificate already exists.
exit 1
fi
if [ ! -d "out" ]; then
bash flush.sh
fi
# Generate root cert along with root key
openssl req -config ca.cnf \
-newkey rsa:2048 -nodes -keyout out/root.key.pem \
-new -x509 -days 7300 -out out/root.crt \
-subj "/C=CN/ST=Shanghai/L=Pudong/O=Devops/CN=ROOT CA"
# Generate cert key
#openssl genrsa -out "out/cert.key.pem" 2048
gen.cert.sh
#!/usr/bin/env bash
if [ -z "$1" ]
then
echo
echo 'Issue a wildcard SSL certificate with Fishdrowned ROOT CA'
echo
echo 'Usage: ./gen.cert.sh <domain> [<domain2>] [<domain3>] [<domain4>] ...'
echo ' <domain> The domain name of your site, like "example.dev",'
echo ' you will get a certificate for *.example.dev'
echo ' Multiple domains are acceptable'
exit;
fi
SAN=""
for var in "$@"
do
SAN+="DNS:*.${var},DNS:${var},"
done
SAN=${SAN:0:${#SAN}-1}
# Move to root directory
cd "$(dirname "${BASH_SOURCE[0]}")"
# Generate root certificate if not exists
if [ ! -f "out/root.crt" ]; then
bash gen.root.sh
fi
# Create domain directory
BASE_DIR="out/$1"
TIME=`date +%Y%m%d-%H%M`
DIR="${BASE_DIR}/${TIME}"
mkdir -p ${DIR}
# Create domain key
openssl genrsa -out "${DIR}/$1.key" 2048
# Create CSR
openssl req -new -out "${DIR}/$1.csr.pem" \
-key "${DIR}/$1.key" \
-reqexts SAN \
-config <(cat ca.cnf \
<(printf "[SAN]\nsubjectAltName=${SAN}")) \
-subj "/C=CN/ST=Shanghai/L=Pudong/O=DevOps/OU=$1/CN=*.$1"
# Issue certificate
# openssl ca -batch -config ./ca.cnf -notext -in "${DIR}/$1.csr.pem" -out "${DIR}/$1.cert.pem"
openssl ca -config ./ca.cnf -batch -notext \
-in "${DIR}/$1.csr.pem" \
-out "${DIR}/$1.crt" \
-cert ./out/root.crt \
-keyfile ./out/root.key.pem
# Chain certificate with CA
cat "${DIR}/$1.crt" ./out/root.crt > "${DIR}/$1.bundle.crt"
ln -snf "./${TIME}/$1.bundle.crt" "${BASE_DIR}/$1.bundle.crt"
#ln -snf "./${TIME}/$1.crt" "${BASE_DIR}/$1.crt"
ln -snf "./${TIME}/$1.key" "${BASE_DIR}/$1.key"
ln -snf "../root.crt" "${BASE_DIR}/root.crt"
# Output certificates
echo
echo "Certificates are located in:"
LS=$([[ `ls --help | grep '\-\-color'` ]] && echo "ls --color" || echo "ls -G")
${LS} -la `pwd`/${BASE_DIR}/*.*
使用方法
./gen.cert.sh <domain>
]$ bash gen.cert.sh jd.com
...
输出三个文件:
- root.crt 这是CA证书
- xxx.bundle.crt 这是域名证书
- xxx.key 这是key文件