What is a SAN
A SAN is a Subject Alternative Name, and as the name implies it serves as a secondary (or tertiary, etc.) DNS name that your web application could be identified as. This is useful in the context of web farms behind a reverse proxy, load-balancing solutions, etc.
For example:
#DNS name used to reach an example website, which has an SSL certificate store.scriptech.io #Back-end servers that serve store.scriptech.io behind a load balancer, included as SANs on the SSL certificate webserver1.scriptech.io webserver2.scriptech.io
Modern Browsers will show an SSL certificate as invalid if a proper SAN is not included, so it’s best practice for us to be in the habit of including SANs in our CSRs.
How to include a SAN
Because we want to include a SAN (Subject Alternative Name) in our CSR (and certificate), we need to use a customized openssl.cnf file.
While you could edit the ‘openssl req’ command on-the-fly with a tool like ‘sed’ to make the necessary changes to the openssl.cnf file, I will walk through the step of manually updating the file for clarity.
Example openssl.cnf file
[req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no [req_distinguished_name] C = <Country> ST = <State> L = <City> O = <Company> OU = <Department> CN = store.scriptech.io [v3_req] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS = webserver1.scriptech.io #DNS.1 = <servername.domain.com> #DNS.2 = <servername2.domain.com> #DNS.3 = <servername3.domain.com> #DNS.4 = <servername4.domain.com>
Note that the subjectAltName declaration calls an array called @alt_names, which is defined at the bottom of the file.
To include a single SAN in your CSR, update the ‘DNS’ declaration to the appropriate value (in this example, ‘webserver1.scriptech.io’), and leave the DNS.x declarations commented out (#). The result is an @alt_names array with a single entry.
To include multiple SANS in your CSR, comment out (#) the ‘DNS’ declaration, and uncomment the DNS.x declarations that you need. For example, your [alt_names] section would look like:
[alt_names] #DNS = <servername.domain.com> DNS.1 = webserver1.scriptech.io DNS.2 = webserver1.scriptech.io #DNS.3 = <servername3.domain.com> #DNS.4 = <servername4.domain.com>
The result is an @alt_names array with multiple entries.
Generate the new key and CSR
If you have not already, copy the contents of the example openssl.cnf file above into a file called ‘openssl.cnf’ somewhere. Make note of the location.
Also make sure you update the DN information (Country, State, etc.)
Create a new key
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out store.scriptech.io.key.pem
Create a new CSR
openssl req -new -sha256 -key store.scriptech.io.key.pem -config /etc/ssl/openssl.cnf -out store.scriptech.io.csr
Verify the CSR
To view the contents of your new CSR, use the following command:
openssl req -text -noout -verify -in store.scriptech.io.csr Certificate Request: Data: ... Requested Extensions: ... X509v3 Subject Alternative Name: DNS:webserver1.scriptech.io
This example shows a single SAN which I included in my openssl.cnf file.
Sign the CSR
Now that you have your properly-formatted CSR, you need to sign it using a Trusted Root Certificate Authority. Depending on your context, this could be a third-party CA like DigiCert or GoDaddy, or it could be an internal Certificate Authority (OpenSSL CA, Active Directory Certificate Services)
The contents of a certificate in the openssl format can be viewed with the following command:
openssl x509 -in store.scriptech.io.cer.pem -text -noout