Multiple Secure Subdomains with a Wildcard SSL Certificate
October 27th, 2008 by derek
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, mydomain.com, it is convenient to organize things into subdomains. For example, maybe you have code repositories at code.mydomain.com or a development environment for testing at test.mydomain.com. But what if you want both of these subdomains to be secure? A standard SSL certificate for mydomain.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. Wildcard SSL certificates allow a single certificate for any immediate subdomain of the base, i.e. *.mydomain.com.
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 promted for Common Name, you would normally enter your domain name. We want a wildcard so enter *.mydomain.com
, replacing mydomain.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
Configuring Apache
First enable the Apache SSL module if it isn’t already:
a2enmod ssl
We also need to enable the vhost_alias module:
a2enmod vhost_alias
Apache needs to be told to listen on port 443. Edit the ports.conf file in /etc/apache2 and add the following:
Listen 443Now we need a Virtual Host to handle all the port 443 traffic. I recommend creating and editing a new file in /etc/apache2/sites-available:
vi /etc/apache2/sites-available/ssl.mydomain.com
Now to configure the Virtual Host. Add the following to the newly created file:
ServerAdmin webmaster@localhost ServerName *.mydomain.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. *.mydomain.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, code.mydomain.com and test.mydomain.com. We have our wildcard certificate in place and someone tries to go to http://code.mydomain.com
. The %0 signifies that the entire string from the address should be substituted, yielding a DocumentRoot of /var/www/code.mydomain.com. If someone tried test.mydomain.com, it would become /var/www/test.mydomain.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 DocumentRoot.
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:
/etc/init.d/apache force-reload
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!
Posted in Guides | comments (rss)
You can leave a response, or trackback from your own site.
Responses
Ismael Casimpan on January 30th, 2009 at 5:20 pm
My employer will be configuring a website that needs a wildcard ssl certificate for many subdomains.
Your explanation makes sense. I will try to follow this instructions and let you know if everything works and what observations I could add.
Thanks.
Joe on May 7th, 2009 at 12:21 pm
Thank you for your detailed explanation, it is very helpful.
If I have a load balanced server configuration, would it be possible to share a certificate between two sites using the setup you’ve described ?
R3v0l on October 25th, 2009 at 5:45 pm
They are not subdomains, they are hostnames. http://www.code.mydomain.com and http://www.test.mydomain.com. Those subdomains would not be possible to secure with a wildcard certificate.
derek on October 25th, 2009 at 6:18 pm
All of the examples, yours (with www) and mine (code.mydomain.com and test.mydomain.com) are subdomains and this is exactly what wildcard certs are for. You do need to be careful how you create your certs as you can run into issues if you try to use them below the child subdomain level – http://www.test.mydomain.com is a grandchild of mydomain (www is a child of test and test is a child of mydomain). For your examples, you would really need certs for *.code.mydomain.com and *.test.mydomain.com (or just use mod_rewrite to drop the www).
Applying wildcard certs is pretty trivial, the real purpose of the article is to show how you can do it through Apache without assigning all of them their own IP (ie – use name based virtual hosts).
Jaylon on October 30th, 2009 at 8:07 am
Great post. I totally agree with you.