SSL Certificate with SAN Extensions

I keep forgetting how to do this, so I’m putting it here for my own edification.  Chrome and Firefox browsers require SAN extensions for ssl certificates to be valid.  Create / request certificates with the extensions to save yourself a headache.

openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.key \
-new \
-out server.crt \
-subj /CN=dev.mycompany.com \
-reqexts SAN \
-extensions SAN \
-config <(cat /System/Library/OpenSSL/openssl.cnf \
<(printf '[SAN]\nsubjectAltName=DNS:dev.mycompany.com')) \
-sha256 \
-days 3650

The above is for MacOS, as can been seen by the openssl.cnf being in /System/Library/OpenSSL.  You can adjust this for whatever Linux distro you are using by changing that to something like:

-config <(cat /etc/ssl/openssl.cnf \

for Ubuntu 16.04.5.  Or:

-config <(cat /etc/pki/tls/openssl.cnf \

for Fedora 29 / CentOS 7.

To do a csr for a legit certificate request, create a configuration file, req.conf:

[req]
default_bits = 4096
default_md = sha256
distinguished_name = dn

req_extensions = v3_req
prompt = no
encrypt_key = no

[ dn ]
C=US
ST=CA
L=Oakland
O=Example Company
OU=Example Department
[email protected]
CN=hostname.example.com

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = hostname.example.com
DNS.2 = alt-hostname.example.com

Then generate the csr with the following command:

openssl req -new -config req.conf -keyouthostname.example.com.key -out hostname.example.com.csr

Note: you can use any name for the configuration file (req.conf), private key (hostname.example.com.key) and csr (hostname.example.com.csr).