Working with OpenSSL and DNS alternative names

Why This Story

In Today’s world in some case you would want your certificates to be able to be legitimate for more then one domain. For that purpose we can apply DNS alternative names to our SSL certificates.

This tutorial

In our tutorial I will setup a certificate for my docker registry and at the end I will show additional step due to the way the docker command works.

Answer files

When running the “openssl” command without an answer file the command will ask use to feel in the blanks (unless we set then up in openssl.cnf in advanced). To same use time we will start by creating 2 answer files , one for the CA and one for our certificate , the reason for the separation is that the CA should not have alternatives names given to him at the certificate creation.

# export DOMAIN="example.local"
# export SHORT_NAME="registry"
$ cat > ${SHORT_NAME}_answer.txt << EOF
[req]
default_bits = 4096
prompt = no
default_md = sha256
x509_extensions = req_ext
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C=US
ST=New York
L=New York
O=MyOrg
OU=MyOrgUnit
emailAddress=me@working.me
CN = ${SHORT_NAME}

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ${SHORT_NAME}
DNS.2 = ${SHORT_NAME}.${DOMAIN}
EOF
$ cat > csr_ca.txt << EOF
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
x509_extensions = usr_cert

[ dn ]
C=US
ST=New York
L=New York
O=MyOrg
OU=MyOU
emailAddress=me@working.me
CN = server.example.com

[ usr_cert ]
basicConstraints=CA:TRUE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF

CA certificate and Key

We will start by creating the files we need for our CA. as a why of work we will always start with generate the RSA key with the length of 4096 (at the very list) .

Generate the Key:

$ openssl genrsa -out ca.key 4096

Generate the CA

$ openssl req -new -x509 -key ca.key -days 730 -out ca.crt -config <( cat csr_ca.txt )
  1. ca.crt

Server Certificate and Key

for the following step we will create 2 additional files for our server (registry). One is (and obviously) the Server key and the other is the server certificate request.

Generate Server Key

Same as we done for the CA , we are generating an RSA key with the length of 4096 chars.

$ openssl genrsa -out ${SHORT_NAME}.key 4096

Generate Server CSR

Now we will generate the certificate request using the domain Key and the domain answer file which we created in the beginning of the this tutorial.

$ openssl req -new -key ${SHORT_NAME}.key -out ${SHORT_NAME}.csr -config <( cat ${SHORT_NAME}_answer.txt )
$ openssl req -in ${SHORT_NAME}.csr -noout -text | grep DNS
DNS:registry, DNS:registry.example.local

Sign the CSR :

now comes the tricky part , we need to tell the CA to use the “altrnames” we setup in the answer file but we need to tell it which section to look at for the values we need so we are going to add 2 more arguments for this purpose.

$ openssl x509 -req -in ${SHORT_NAME}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out ${SHORT_NAME}.crt -days 730 -extensions 'req_ext' -extfile <(cat ${SHORT_NAME}_answer.txt)
  1. extfile — configuration file with X509V3 extensions to add

Certificate bundle

In some cases it is a good practice to join the certificate and the CA into a single file (not all servers has a CA configuration options).

$ mv ${SHORT_NAME}.crt ${SHORT_NAME}-certonly.crt
$ cat ${SHORT_NAME}-certonly.crt ca.crt > ${SHORT_NAME}.crt

Testing the Certificate

Now all that is left to do is to test our certificate :

$ openssl x509 -in ${SHORT_NAME}.crt -noout -text | grep DNS
DNS:registry, DNS:registry.example.local
$ openssl verify -CAfile ca.crt ${SHORT_NAME}.crt
registry.crt: OK

updating the Registry

As promise to update the registry first we will copy our ca.crt to our “anchors” directory :

$ cp ca.crt /etc/pki/ca-trust/source/anchors/${SHORT_NAME}.crt
$ update-ca-trust extract
$ export MY_SERVER="registry.example.local"
$ mkdir /etc/docker/certs.d/${MY_SERVER}
$ cp ca.crt /etc/docker/certs.d/${MY_SERVER}/
$ systemctl restart docker

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store