2016-12-09 23:53:23 +00:00
|
|
|
#!/bin/bash
|
|
|
|
set -u
|
|
|
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
|
|
|
|
|
|
if [[ "$#" -eq 0 ]]; then
|
|
|
|
cat <<-EOF
|
|
|
|
|
|
|
|
To generate a server certificate, provide the domain name as a parameter:
|
|
|
|
$(basename $0) www.my-domain.tdl
|
|
|
|
$(basename $0) www.my-domain.tdl alternate.domain.tld
|
|
|
|
|
|
|
|
You can also create certificates for wildcard domains:
|
|
|
|
$(basename $0) '*.my-domain.tdl'
|
2017-04-07 10:58:49 +00:00
|
|
|
|
2016-12-09 23:53:23 +00:00
|
|
|
EOF
|
|
|
|
exit 0
|
|
|
|
else
|
|
|
|
DOMAIN="$1"
|
|
|
|
ALTERNATE_DOMAINS="DNS:$( echo "$@" | sed 's/ /,DNS:/g')"
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# Create a nginx container (which conveniently provides the `openssl` command)
|
|
|
|
###############################################################################
|
|
|
|
|
2017-05-04 16:57:00 +00:00
|
|
|
CONTAINER=$(docker run -d -v $DIR:/work -w /work -e SAN="$ALTERNATE_DOMAINS" nginx:1.13.0)
|
2017-04-07 10:58:49 +00:00
|
|
|
# Configure openssl
|
2016-12-09 23:53:23 +00:00
|
|
|
docker exec $CONTAINER bash -c '
|
|
|
|
mkdir -p /ca/{certs,crl,private,newcerts} 2>/dev/null
|
|
|
|
echo 1000 > /ca/serial
|
|
|
|
touch /ca/index.txt
|
|
|
|
cat > /ca/openssl.cnf <<-"OESCRIPT"
|
|
|
|
[ ca ]
|
|
|
|
# `man ca`
|
|
|
|
default_ca = CA_default
|
|
|
|
|
|
|
|
[ CA_default ]
|
|
|
|
# Directory and file locations.
|
|
|
|
dir = /ca
|
|
|
|
certs = $dir/certs
|
|
|
|
crl_dir = $dir/crl
|
|
|
|
new_certs_dir = $dir/newcerts
|
|
|
|
database = $dir/index.txt
|
|
|
|
serial = $dir/serial
|
|
|
|
RANDFILE = $dir/private/.rand
|
|
|
|
|
|
|
|
# The root key and root certificate.
|
|
|
|
private_key = /work/ca-root.key
|
|
|
|
certificate = /work/ca-root.crt
|
|
|
|
|
|
|
|
# SHA-1 is deprecated, so use SHA-2 instead.
|
|
|
|
default_md = sha256
|
|
|
|
|
|
|
|
name_opt = ca_default
|
|
|
|
cert_opt = ca_default
|
|
|
|
default_days = 10000
|
|
|
|
preserve = no
|
|
|
|
policy = policy_loose
|
|
|
|
|
|
|
|
[ policy_loose ]
|
|
|
|
countryName = optional
|
|
|
|
stateOrProvinceName = optional
|
|
|
|
localityName = optional
|
|
|
|
organizationName = optional
|
|
|
|
organizationalUnitName = optional
|
|
|
|
commonName = supplied
|
|
|
|
emailAddress = optional
|
|
|
|
|
|
|
|
[ 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
|
|
|
|
|
|
|
|
[ 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
|
|
|
|
|
|
|
|
[ server_cert ]
|
|
|
|
# Extensions for server certificates (`man x509v3_config`).
|
|
|
|
basicConstraints = CA:FALSE
|
|
|
|
nsCertType = server
|
|
|
|
nsComment = server certificate generated for test purpose (nginx-proxy test suite)
|
|
|
|
subjectKeyIdentifier = hash
|
|
|
|
authorityKeyIdentifier = keyid,issuer:always
|
|
|
|
keyUsage = critical, digitalSignature, keyEncipherment
|
|
|
|
extendedKeyUsage = serverAuth
|
|
|
|
|
|
|
|
[ san_env ]
|
|
|
|
subjectAltName=${ENV::SAN}
|
|
|
|
OESCRIPT
|
|
|
|
'
|
|
|
|
|
|
|
|
# shortcut for calling `openssl` inside the container
|
|
|
|
function openssl {
|
|
|
|
docker exec $CONTAINER openssl "$@"
|
|
|
|
}
|
|
|
|
|
|
|
|
function exitfail {
|
2017-04-07 10:58:49 +00:00
|
|
|
echo
|
2016-12-09 23:53:23 +00:00
|
|
|
echo ERROR: "$@"
|
|
|
|
docker rm -f $CONTAINER
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# Setup Certificate authority
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
if ! [[ -f "$DIR/ca-root.key" ]]; then
|
2017-04-07 10:58:49 +00:00
|
|
|
echo
|
2016-12-09 23:53:23 +00:00
|
|
|
echo "> Create a Certificate Authority root key: $DIR/ca-root.key"
|
|
|
|
openssl genrsa -out ca-root.key 2048
|
|
|
|
[[ $? -eq 0 ]] || exitfail failed to generate CA root key
|
|
|
|
fi
|
|
|
|
|
2017-04-07 10:58:49 +00:00
|
|
|
# Create a CA root certificate
|
2016-12-09 23:53:23 +00:00
|
|
|
if ! [[ -f "$DIR/ca-root.crt" ]]; then
|
2017-04-07 10:58:49 +00:00
|
|
|
echo
|
2016-12-09 23:53:23 +00:00
|
|
|
echo "> Create a CA root certificate: $DIR/ca-root.crt"
|
|
|
|
openssl req -config /ca/openssl.cnf \
|
|
|
|
-key ca-root.key \
|
|
|
|
-new -x509 -days 3650 -subj "/O=nginx-proxy test suite/CN=www.nginx-proxy.tld" -extensions v3_ca \
|
|
|
|
-out ca-root.crt
|
|
|
|
[[ $? -eq 0 ]] || exitfail failed to generate CA root certificate
|
|
|
|
|
|
|
|
# Verify certificate
|
|
|
|
openssl x509 -noout -text -in ca-root.crt
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# create server key and certificate signed by the certificate authority
|
|
|
|
###############################################################################
|
|
|
|
|
2017-04-07 10:58:49 +00:00
|
|
|
echo
|
2016-12-09 23:53:23 +00:00
|
|
|
echo "> Create a host key: $DIR/$DOMAIN.key"
|
|
|
|
openssl genrsa -out "$DOMAIN.key" 2048
|
|
|
|
|
2017-04-07 10:58:49 +00:00
|
|
|
echo
|
2016-12-09 23:53:23 +00:00
|
|
|
echo "> Create a host certificate signing request"
|
|
|
|
|
|
|
|
SAN="$ALTERNATE_DOMAINS" openssl req -config /ca/openssl.cnf \
|
|
|
|
-key "$DOMAIN.key" \
|
2017-04-07 10:58:49 +00:00
|
|
|
-new -out "/ca/$DOMAIN.csr" -days 1000 -extensions san_env -subj "/CN=$DOMAIN"
|
2016-12-09 23:53:23 +00:00
|
|
|
[[ $? -eq 0 ]] || exitfail failed to generate server certificate signing request
|
|
|
|
|
2017-04-07 10:58:49 +00:00
|
|
|
echo
|
2016-12-09 23:53:23 +00:00
|
|
|
echo "> Create server certificate: $DIR/$DOMAIN.crt"
|
|
|
|
SAN="$ALTERNATE_DOMAINS" openssl ca -config /ca/openssl.cnf -batch \
|
|
|
|
-extensions server_cert \
|
|
|
|
-extensions san_env \
|
|
|
|
-in "/ca/$DOMAIN.csr" \
|
2017-04-07 10:58:49 +00:00
|
|
|
-out "$DOMAIN.crt"
|
2016-12-09 23:53:23 +00:00
|
|
|
[[ $? -eq 0 ]] || exitfail failed to generate server certificate
|
|
|
|
|
|
|
|
|
|
|
|
# Verify host certificate
|
2017-04-07 10:58:49 +00:00
|
|
|
#openssl x509 -noout -text -in "$DOMAIN.crt"
|
2016-12-09 23:53:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
docker rm -f $CONTAINER >/dev/null
|