Or the SSL Cert Extension that saves your back during development

I recently wrote an article on how to generate and upload a self-signed SSL Certificate to AWS Certificate Manager. One of the cases I had missed to address there was the inconsistency of the Load Balancer and development domain names during the early phases of any project. This is a practical issue, fortunately that an extension in the SSL Certificate standard addresses.

Subject Alternative Name, or SAN, allows to specify a list of hostnames, IP addresses, and other common names, addition to the Common Name (CN) field specified in the certificate. If the SAN field is populated and if the CN hostname verification during the SSL Certificate verification, the values in the SAN field are matched against the hostname. This is where the flexibility of the SAN field becomes evident.

Suppose you’re using an AWS ELB to front your cluster of servers, and perform SSL termination at the ELB. In this case, the public DNS name of the ELB would be of the format elb-name.region.elb.amazonaws.com . Out of this format, the latter part region.elb.amazonaws.com is fairly constant (as long as you don’t start expanding to different regions).

If you’re frequently recreating ELBs, the public DNS name would also change. If you use CN as the only hostname verification mechanism, you would have to regenerate the certificate every time a new ELB is created.

You can instead specify the pattern *.region.elb.amazonaws.com as a SAN field while generating the certificate and upload it to ACM to be used in every HTTPS listener in the newly created ELBs.

To specify the SAN fields while generating a self-signed certificate with OpenSSL, the parameter -extensions has to be used. In short, the commands to follow are,

  1. Generate the private key
openssl genrsa 2048 > private.key
  1. Generate the self-signed certificate with SAN fields
openssl req -new -x509 -nodes -sha1 -days 3650 -extensions v3_ca -key private.key -extensions SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:*.us-east-1.elb.amazonaws.com,DNS:*.dev.acme.org")) > public.crt
  1. Upload to AWS ACM
aws acm import-certificate --certificate file://public.crt --private-key file://private.key --region us-east-1

After generating the certificate with the SAN fields, you can check if your command succeeded by looking at the certificate. To do this execute the following command.

openssl x509 -in public.crt -noout -text

You will see an output similar to the following.

According to the above output, public.crt certificate will validate to any ELB created in the us-east-1 region, along with any subdomain created under dev.acme.org .

There’s one fact to remember about the use of wild cards in the SAN fields though. You can only use wild cards to match a single level of variation.

In other words, the above certificate will validate project1.dev.acme.org while sub.project1.dev.acme.org will not match.

While it’s rather a trivial task to generate a self-signed certificate (or even an authorized certificate online), repeating it every time your CloudFormation script runs, is going to be a headache. This is where the SAN extension becomes valuable.

Written on November 6, 2017 by chamila de alwis.

Originally published on Medium