Apache name-based SSL vhosts with SNI
Name-based SSL virtual hosts have always been a problem with older versions of Apache. I had previously found a way to allow several SSL virtual hosts to share a common certificate, but this setup is now (almost) useless thanks to the Server Name Indication extension.
The Apache wiki sums up the interest of the SNI extension:
with SNI, you can have many virtual hosts sharing the same IP address and port, and each one can have its own unique certificate
In this article, I will explain how you can generate self-signed SSL certificates for all your SSL virtual hosts, using TinyCA to manage your own Certification Authority.
Creating self-signed certificates using TinyCA
After creating a new CA in TinyCA, you will need to create a unique certificate for each SSL vhost. This is very intuitive for simple hosts, but some “special” setups require more detailed explanations.
If you use ServerAlias directive so that eg. smtp.domain.com is handled in the same vhost than mail.domain.com, your certificate will need to know about both names so that your browser doesn’t trigger a warning when visiting the website via its alias:
Certificate:
[...]
Subject: C=FR, CN=smtp.domain.com/emailAddress=admin@domain.com
[...]
X509v3 Subject Alternative Name:
DNS:smtp.domain.com, DNS:mail.domain.com
This can be done easily when using openSSL directly, as explained previously, but requires to configure TinyCA accordingly:
- Go to the “Server Certificate Settings” tabs in the preferences
- Change the “Subject alternative name” to “Ask User”, and tick the “raw” option
Then create a server certificate as usual. When the signing window appears, add eg. “DNS: smtp.domain.com, DNS: mail.domain.com” in the Subject alternative name (raw) field as per the following screenshot:

You will then need to export the certificate and the private key, and export them to your server running Apache.
Note that you can export a private key without password, just think and tick the appropriate option in the export window.
Ben Artin’s post on the same topic explains this method isn’t supported by all browsers. I have personally successfully tested with Iceweasel, but Android 2.3.4 default web browser (undoubtedly based on Chrome) fails to recognize the AltNames and hence displays a warning about the non-matching name in the SSL certificate and the domain name.
Using SNI in Apache
Just define some virtual hosts with SSL, including the paths to the certificate and the private key files:
<IfModule mod_ssl.c>
<VirtualHost *:443>
[...]
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/smtp.domain.com-cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/smtp.domain.com-key.pem
</VirtualHost>
</IfModule>So that browsers not supporting SNI can still access your websites, I would advise you to disable the SNI strict verification in your Apache configuration:
SSLStrictSNIVHostCheck off
This way, the non-SNI clients will access the websites using the SSL certificate of your default SSL vhost (ie. the first defined in the Apache configuration). You can still use a multiple names certificate for this vhost so that even non-SNI browsers can access the various vhosts without warning about non-matching names.
Importing the CA certificate
You will also obviously need to import your CA certificate to your browser. In Iceweasel/Firefox, it is done in the advanced settings tab.
My own CA certificate can be found at https://nix.kirya.net/Kirya-cacert.pem.