Name-Based Virtual Hosts with SSL using Apache2 on Ubuntu Lucid
It has now been a few years (2007) that SNI (Server Name Indication) has been introduced/supported in OpenSSL 0.9.8, but it has only been just last year that SNI was fully supported in Apache2 with version 2.2.12 released in July 2009. Now we can really having
multiple virtual hosts with different certificates on the same IP address! No need to buy any more IP addresses!
Introduction
This tutorial is mainly oriented to Ubuntu, but can also be applied to other distributions such as Debian.
The minimum requirements for SNI to work are Apache 2.2.12 (or higher) with OpenSSL 0.9.8g (or higher).
Make sure you already have your website(s) set up and running (non-SSL of course!) and listening on another port than 443 as we will use this port for SSL.
Installation of packages
We need to activate the Apache2 SSL module in order to serve websites over SSL:
sudo a2enmod sslAlso, the ssl-cert package will allow us to create certificates in a few keystrokes:
sudo apt-get install ssl-cert
If you don't have ssl-cert available in your distribution's package manager, you can find it here: http://packages.debian.org/sid/ssl-cert
Creating certificates
We will now create a self-signed SSL certificate.
When using make-ssl-cert, both the certificate and the private key are generated and stored within the same file. The generated *.crt file needs to be kept somewhere safe on your disk, it is a good practice to move it to /etc/ssl/privateand use chmod 600 and chown root:root. It should be readable by root only!
sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf \ /etc/ssl/private/mydomain.crt
It should ask you for a hostname, enter the exact domain name of the website (e.g. if you want to use https://www.myexampledomain.com then put www.myexampledomain.comas
hostname).
Enabling name-based SSL virtual hosts
Apache2 needs to know that our virtual hosts using SSL will be matched using a name-based matching rule (instead of IP-based) and also that it needs to listen for SSL connections on port 443.
Open the Apache2 ports config file, located at /etc/apache2/ports.conf and add:
NameVirtualHost *:443
It should look similar to this:
NameVirtualHost *:80
NameVirtualHost *:443
Listen 80
<IfModule mod_ssl.c>
Listen 443
</IfModule>Make surethere is Listen 443 somewhere in this file, in order to tell Apache2 to listen on this specific port for SSL connections.
Creating the virtual hosts configuration file
Important Note:
Note that not all browsers support SNI. For those without SNI support they will be redirected to the first SSL vhost defined (which is usually the first alphabetically in the /sites-enabled/ folder) in
the Apache2 configuration.
Also, it is good to know that in their browser, they will see the domain name that they typed in instead of the actual vhost's domain name, as a consequence the certificate will not be validated as it will not match the domain shown in their browser. As an alternative you can use SSLStrictSNIVHostCheck, see note below.
The best thing to do is to copy the normal configuration file of your website (with normal http:// access) and add the SSL directives.
First, make a copy:
sudo cp /etc/apache2/sites-available/{mywebsite.conf,mywebsite_ssl.conf}
Then open the mywebsite_ssl.conf file, and add/modify the bold parts:
<VirtualHost *:443> ServerName www.myexampledomain.com SSLEngine On SSLCertificateFile /etc/ssl/private/myexampledomain.crt DocumentRoot /var/www/myexampledomain </VirtualHost>
Explanation:
“*:443” along with ServerName define this configuration as a name-based virtual host.
“SSLEngine On” enables SSL for this virtual host.
“SSLCertificateFile”points to the certificate we created earlier.
Note:
Using SSLStrictSNIVHostCheckit will refuse non SNI capable browsers to access any website on your server using SSL.
This directive sets
whether a non SNI client is allowed to access a name based virtual host. If set to on in the non default name based virtual host, non SNI clients are not allowed to access this particular virtual host. If set
to on in the default name based virtual host, non SNI clients are not allowed to access any name based virtual host belonging to this IP / port combination. (http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#SSLStrictSNIVHostCheck)
Enabling the virtual host
We need to enable the virtual host, this is an important step which is often forgotten:
sudo a2ensite mywebsite_ssl.confTesting
Restart Apache2:
sudo service apache2 restartThis is time for a test, visit your website over SSL, make sure you prepend https:// to your domain name (for example https://www.myexampledomain.com)
Troubleshooting
If you cannot see your website using https you can dig into the Apache2 logs (located at /var/log/apache2/error.log) and search for [error] or [warn].
Also be certain to have activated/enabled all of the virtual hosts you want by typing sudo a2ensite yourdomain.conf and then reload or restart Apache2.
If you get a “ssl_error_rx_record_too_long” error, it can mean either SSL is not activated properly for this virtual host (check that there is SSLEngine On in your vhost config) or the virtual host configuration is not enabled
(“sudo a2ensite vhostconfigfile”).
Notes
If you already have your own certificates, you will want to use both SSLCertificateKeyFileand SSLCertificateFilein the virtual host configuration file because certificate issuers usually give
you two different files (one containing a private key and the other one containing the certificate).
It is important to be aware that some browsers do not support SNI and will not be able to access your virtual hosts.
Some browsers in mobile devices might not support SNI so be certain that your default SSL virtual host can provide some help or support to those users, like for example offering the option to switch back to regular non-SSL connection.

























Makarska said
October 1 2010 @ 3:08 PM
Thanks for this great post. The info I have gained from your blog is truly encouraging
James said
November 2 2010 @ 10:07 AM
Excellent article! I have never setup SSL on a server and this made it easy. Thank you!