123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- #!/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'
- 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)
- ###############################################################################
- CONTAINER=$(docker run -d -v $DIR:/work -w /work -e SAN="$ALTERNATE_DOMAINS" nginx:1.27.5)
- # Configure openssl
- 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 {
- 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 key
- fi
- # Create a CA root certificate
- if ! [[ -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.crt
- fi
- ###############################################################################
- # create server key and certificate signed by the certificate authority
- ###############################################################################
- echo
- echo "> Create a host key: $DIR/$DOMAIN.key"
- openssl genrsa -out "$DOMAIN.key" 2048
- echo
- echo "> 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 request
- echo
- 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" \
- -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
|