Running mod_ssl with Virtual Hosts

Like many Drupal developers, at any particular time I'm running dozens of Apache virtual hosts on my workstation. This allows access to each project under a friendly url. We frequently create sites that employ SSL, which creates a wrinkle: officially, it's not possible to used name-based virtual hosting with SSL.

Simply disabling the SSL features on a development copy isn't the best option, because we need to test this functionality as we're developing.

It turns out that you can use SSL and vhosts together, sort of. Name-based virtual hosts can be configured on port 443 just like any other port. Apache won't stop you, though it will throw a stern warning when it starts up:

[warn] Init: You should not use name-based virtual hosts in conjunction with SSL!!

Double exclamation! This is SERIOUS!! Down to business:
# httpd-vhosts.conf
# Use name-based virtual hosting.
NameVirtualHost *:80
NameVirtualHost *:443
 
# [PROJECT].conf
# Create two virtual hosts, one on each port
# You can have as many of these as you want
<VirtualHost *:80>
  DocumentRoot [/OVER/THE/RAINBOW/TRUNK/DRUPAL]
  ServerName [PROJECT].[HOST].example.com
</VirtualHost>
 
<VirtualHost *:443>
  DocumentRoot [/OVER/THE/RAINBOW/TRUNK/DRUPAL]
  ServerName [PROJECT].[HOST].example.com
 
  SSLEngine on
  SSLCertificateFile ["/ETC/APACHE2/SERVER.CRT"]
  SSLCertificateKeyFile ["/ETC/APACHE2/SERVER.KEY"]
</VirtualHost>

Now, the limitation described in the Apache manual still applies – we can only have one SSL certificate. This means that without doing anything further, you're going to get "host mismatch" validation errors in your browser. This can be a real pain, especially with Firefox 3's more aggressive stance on untrusted certs (which I fully support, for reasons that have been discussed to death).

So what's needed is a wildcard certificate, which can be created by putting a * in the cert's common name, like *.[HOST].example.com.

Since we want the browser to trust our cert, without needing to manually add an exception for each virtual host, we also need to create our own certificate authority. Here is a straightforward recipe for setting up a CA; it's an easy process requiring only a few more commands than a self-signed certificate. When you're finished, you can import your ca.crt into your browser's list of trusted roots.

In Firefox, this is done under
Preferences » Advanced » Encryption » View Certificates » Authorities » Import.
For Safari, simply double-click the ca.crt file, it will open in Keychain Access. When asked, say "Always Trust".

The conclusion is that SSL and virtual hosts can play nice, as long as they share a common domain. Looking to the future, there is a solution in a newer set of TLS extensions, called Server Name Indication. This supersedes an earlier, now abandoned approach known as TLS Upgrade, described in RFC 2817.

Tagged as: Apache, Drupal, SSL, Virtual Hosts

5 comments

Garrett Albright (not verified) wrote 1 year 14 weeks ago

This was useful info.

This was useful info. Thanks.

In my case, I generally use domains with the .test suffix when testing locally. Using *.test as the common name seemed to work as intended.

balaji (not verified) wrote 1 year 2 weeks ago

hai, This is the better

hai,

This is the better useful info for each beginners and developers for easy to test the site locally.

Thanks

Andrew Vandever (not verified) wrote 26 weeks 2 days ago

Great demo!

Found good documentation in apache docs, but wanted a real-world demo. Thanks!

Svenni (not verified) wrote 2 weeks 4 days ago

Great Tip, thank you!

Your blog provided right the info that I needed. Thanks a lot!

Add your comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

More information about formatting options