openssl req with SAN (subjectAltName)
Updated at by ospiI will tiptoe through generating a certificate signing request (csr) with openssl which includes X509 extension Subject Alternative Names (SAN). SAN extension in short can be used to validate multiple hostnames with the same certificate (eg. www.example.com and mail.example.com) or even combine multiple wildcards (eg. *.testing.example.com and *.example.com).
Or skip everything below and use a script from https://github.com/ospii/san. Clone https://github.com/ospii/san.git or git@github.com:ospii/san.git .
Fire up a terminal and start by generating a 4096 bit RSA keyfile in case you don't have one (bash variable substitution).
domain=example.com
openssl genrsa -out "${domain}.key" 4096
Following two variables will be passed to the openssl command when generating the CSR.
subjectAltName
with two DNS names and one IP address. More options at openssl.org/docs - Subject alternative namedn
(distinguished name) is the unique name of your certificate and it contains multiple fields like C = Country, ST = State and CN = CommonName which is also used to match the hostname.
Requirements for the dn
fields vary per certificate authority(CA) and level of validation. Some CAs might only need CN (CommonName) and some might require additional fields like emailAddress
.
subjectAltName="DNS:${domain},DNS:www.${domain},IP:127.50.50.50"
dn="C=FI \n ST=Uusimaa \n L=Helsinki \n O=Öspi \n OU=Ospi \n CN=${domain}"
openssl req -out "${domain}.csr" -new -key "${domain}.key" -config <(printf "[req] \n prompt=no \n utf8=yes \n distinguished_name=dn_details \n req_extensions=san_details \n [dn_details] \n ${dn} \n [san_details] \n subjectAltName=${subjectAltName}")
Two gotcha relating to this "beauty". dn has \n
for new lines and prompt=no
lurking in the [req]
block fills all DN stuff from dn_details
section in the -config
file. This also implies openssl wont't use any fields provided in -subj
parameter. It would have been nice to separate the static organizational fields from the CN but, alas, you can't have it all. Finally check everything is ok.
openssl req -in "${domain}.csr" -noout -text
Subject is the distinguished name
of your certificate and requested extensions should have the X509v3 Subject Alternative Name
block. Also verify the Signature Algorithm
is sha256WithRSAEncryption
. With older versions of openssl you might see sha1WithRSAEncryption
or even md5WithRSAEncryption
usually accompanied by nagging from your CA if you're to submit it. However this doesn't mean the issued certificate will use the same signature algorithm as it's only the signature of your request (csr). Anyway add -sha256
to the openssl req
if anything other than sha256 pops up.
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=FI, ST=Uusimaa, L=Helsinki, O=Ospi, OU=Ospi, CN=example.com
...
...
Attributes:
Requested Extensions:
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com, IP Address:127.50.50.50
Signature Algorithm: sha256WithRSAEncryption
That's it. Happy SANing!