openssl / sign / subject alternative names
Recently, an automated job of mine failed because the latest and greatest Python refused to validate an SSL certificate with 127.0.0.1 in the common name (CN).
Apparently CN=127.0.0.1
will not be accepted anymore, as using the
common name for hostname validation has been deprecated for ages now.
The fix? Use subject alternative names (SANs).
Generally, you’ll already have these when you have your certificates signed by somebody else. But if you’re signing certificates yourself, you’ll need to know how to pass them to openssl:
The old way of creating a self-signed certificate:
$ openssl genrsa -out lo_server.key 4096 &&
openssl req -new -key lo_server.key -out lo_server.csr -batch \
-subj '/CN=127.0.0.1/emailAddress=example@localhost' &&
openssl x509 -in lo_server.csr -out lo_server.crt -req \
-signkey lo_server.key -days 3650
The new way, with SANs. Note how that third call fetches the SAN extension values from the ‘csr’ (using bash process substitution) so we don’t have to configure them twice:
$ openssl genrsa -out lo_server.key 4096 &&
openssl req -new -key lo_server.key -out lo_server.csr -batch \
-subj '/CN=localhost/emailAddress=example@localhost' \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1" &&
openssl x509 -in lo_server.csr -out lo_server.crt -req \
-signkey lo_server.key -days 3650 -extfile <(
printf 'subjectAltName=%s' \
$(openssl req -in lo_server.csr -noout -text |
sed -e '/DNS:/!d;s/^[[:blank:]]*//;s/, /,/g;s/IP Address:/IP:/g') )
And, these subjectAltName=
extensions also come in handy when you want
to play with proper SIP URIs matching, as defined in RFC5922-7.1 SIP
Identities.