I’ve finally worked out how to create self-signed SSL certificates for multiple domain names with openssl.
These notes relate to Debian GNU/Linux, but the principles will apply to other operating systems.
The first step to make the process easier and repeatable in the future is to copy the default configuration file from /etc/ssl/openssl.cnf to a working directory where you can adapt it
Let’s assume that you’ve copied /etc/ssl/openssl.cnf to ~/project-openssl.cnf. Edit the new file and set the various default values to the ones that you need — that’s better than having to respond to openssl’s prompts every time you run it.
For real non-self-signed certificates, you would generate a certificate signing request (.csr) file, ready for a certificate authority to sign it for you. In that case, you need to follow the instructions at http://wiki.cacert.org/FAQ/subjectAltName.
But for a self-signed certificate, the subjectAltName has to go in a different place. Make sure you’ve got this line present and un-commented in the [req] section of the config file:
[req] ... x509_extensions = v3_ca
and then this goes at the end of the [v3_ca] section:
[v3_ca] ... subjectAltName = @alt_names [alt_names] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = example.co.uk DNS.4 = www.example.co.uk
There is (apparently) a limit to the number (or total length) of the alternate names, but I didn’t reach it with 11 domain names.
It’s also possible to add IP addresses to the alt_names section like this:
IP.1 = 192.168.1.1 IP.2 = 192.168.69.14
Then to create the key and self-signed certificate, run commands similar to these:
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout project.key -out project.crt -config ~/project-openssl.cnf cp project.crt /etc/ssl/localcerts/ mv project.key /etc/ssl/private/
Note that I move (rather than copy) the key to the private directory to avoid leaving a copy of it lying around unprotected.
You can check that the certificate contains all the domains that you added by running this:
openssl x509 -in project.crt -text -noout | less
I haven’t tried this, but according to http://apetec.com/support/GenerateSAN-CSR.htm it’s also possible to create a CSR and then self-sign it like this:
openssl x509 -req -days 3650 -in project.csr -signkey project.key -out project.crt v3_req -extfile project-openssl.cnf