This guide is a walk through for configuring multiple secure subdomains using a wildcard SSL certificate and Apache2 on Ubuntu 8.04.
For those not familiar with the problems for this setup, a little background is in order (if you want to get to the meat of things, just skip down). If you have your domain,
example.com, it is convenient to organize things into subdomains. For example, maybe you have code repositories at
code.example.com or a development environment for testing at
test.example.com. But what if you want both of these subdomains to be secure? A standard SSL certificate for
example.com does not validate for any of the subdomains since the addresses do not match. You could get separate certificates for each subdomain, but configuring those can be tricky and time consuming. Wildcard SSL certificates allow a single certificate for any immediate subdomain of the base, i.e.
So problem solved right? Well, not exactly... due to the SSL protocol you cannot use name-based virtual hosts in Apache with SSL. Since only IP-based virtual hosts can be used Apache requires a single Virtual Host for all port 443 (SSL) traffic per IP address. The way around this is to dynamically set the document root after receiving a request on port 443. It may sound complicated, but the steps are pretty easy once you see how it is done.
Generating the Wildcard Certificate
First off, you need a wildcard SSL certificate. You can purchase one commercially or just generate one yourself. If you want to roll your you have to have Apache with mod-ssl. (Note that if you are not running as root you will need to
sudo all of the below commands):
apt-get install apache2 apache2-common
Now we can generate the certificate. First we generate a key:
openssl genrsa -out server.key 2048 chmod 400 server.key
Next we generate a certificate signing request (CSR). This is where we can designate the wildcard. Run the command below and you will be prompted with a series of questions. When prompted for Common Name, you would normally enter your domain name. We want a wildcard so enter
example.com with your domain name:
openssl req -new -key server.key -out server.csr
Finally, create the self-signed wildcard certificate (the below example is valid for a year; change the number of days to reflect how long you want the certificate to be valid):
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
First enable the Apache SSL module if it isn't already:
We also need to enable the
Apache needs to be told to listen on port 443. Edit the
ports.conf file in
/etc/apache2 and add the following:
Now we need a Virtual Host to handle all the port 443 traffic. I recommend creating and editing a new file in
Now to configure the Virtual Host. Add the following to the newly created file:
ServerAdmin webmaster@localhost ServerName *.example.com SSLEngine On SSLCertificateFile /etc/apache2/ssl/apache.pem SSLProtocol all SSLCipherSuite HIGH:MEDIUM VirtualDocumentRoot /var/www/%0/
A little explanation is in order here. The
ServerName (and any
ServerAlias as well) uses the wildcard notation (i.e.
*.example.com) since we want to handle multiple subdomains. Next are the directives to enable SSL and you will need to adjust the
SSLCertificateFile path to point to your certificate. The last line is where the magic happens using the
VirtualDocumentRoot directive. Thanks to the
vhost_alias module, we can set the document root based on the address.
Say we have the two example subdomains from earlier,
test.example.com. We have our wildcard certificate in place and someone tries to go to
%0 signifies that the entire string from the address should be substituted, yielding a
/var/www/code.example.com. If someone tried
test.example.com, it would become
/var/www/test.example.com. The documentation on the
vhost_alias module shows all the options for getting parts or all of the address string for substituting into the
Using this method, you can dynamically determine what the root document path should be and serve the correct information. The only catch is that you will have to adhere to a naming scheme that follows however you design your rewrite rule (in my example above, it will be
/var/www/<full subdomain path>. But being forced to use a consistent naming scheme for your sites (which should probably be done anyway...) is a pretty good tradeoff for running multiple secure subdomains on a single IP address with a single SSL certificate.
One last thing, make sure to reload Apache so the changes take effect:
If you are looking for a good host that will give you full control over your server, be sure to check out Linode. We use them for all our Linux hosting and love it!