| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 | #!/bin/bashset -uDIR="$( 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'	EOF	exit 0else	DOMAIN="$1"	ALTERNATE_DOMAINS="DNS:$( echo "$@" | sed 's/ /,DNS:/g')"fi################################################################################ Create a nginx container (which conveniently provides the `openssl` command)###############################################################################CONTAINER=$(docker run -d -v $DIR:/work -w /work -e SAN="$ALTERNATE_DOMAINS" nginx:1.14.1)# Configure openssldocker 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 containerfunction openssl {	docker exec $CONTAINER openssl "$@"}function exitfail {		echo		echo ERROR: "$@"		docker rm -f $CONTAINER		exit 1}################################################################################ Setup Certificate authority###############################################################################if ! [[ -f "$DIR/ca-root.key" ]]; then	echo	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 keyfi# Create a CA root certificateif ! [[ -f "$DIR/ca-root.crt" ]]; then	echo	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.crtfi################################################################################ create server key and certificate signed by the certificate authority###############################################################################echoecho "> Create a host key: $DIR/$DOMAIN.key"openssl genrsa -out "$DOMAIN.key" 2048echoecho "> Create a host certificate signing request"SAN="$ALTERNATE_DOMAINS" openssl req -config /ca/openssl.cnf \	-key "$DOMAIN.key" \	-new -out "/ca/$DOMAIN.csr" -days 1000 -extensions san_env -subj "/CN=$DOMAIN"	[[ $? -eq 0 ]] || exitfail failed to generate server certificate signing requestechoecho "> 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" \		-out "$DOMAIN.crt"	[[ $? -eq 0 ]] || exitfail failed to generate server certificate# Verify host certificate#openssl x509 -noout -text -in "$DOMAIN.crt"docker rm -f $CONTAINER >/dev/null
 |