HOWTO: Apache 2 SSL Name-Based Virtual Hosting

I recently reported being stuck trying to set up multiple SSL name-based virtual hosts on the same IP address with non-SSL name-based virtual hosts. Soon after, I figured it out. Shortly after that, one of my students suggested the same solution to me…


The key idea in achieving SSL name-based virtual hosts in Apache 2 is this: Apache's decision as to whether or not the connection is SSL is made by port number early in the process, just as one would hope. If Apache decides that the connection is SSL, it presents the site certificate.

For a self-signed cert, the vistor's browser will put up the normal "this cert is no good" warning. Since each site can have only one cert (since Apache otherwise has no idea which one to present, as the connection hasn't yet been established), the visitor's browser may also put up a "this cert doesn't match the site" warning. Big whoop.

Anyway, the only slightly tricky part in all this is understanding the rules Apache 2 uses to select a name-based virtual host. Recall that for a non-SSL host, Apache 2 will default to the first VirtualHost it finds in its config if it can't match the incoming name to a specific virtual host. It turns out that for an SSL virtual host, the rules are the same, except that it only considers the VirtualHosts on the SSL port.

So here's how:

  1. Find the "Listen 80" directive in your Apache 2 config. Add a "Listen 443" directive on the following line.
  2. Find the "NameVirtualHost *" directive in your config. Change it to say "NameVirtualHost *:80". Then add "NameVirtualHost *:443" on the following line.
  3. All your VirtualHosts currently are probably set up as "<Virtual Host *>". Change this to "<VirtualHost *:80>".
  4. Add a default SSL virtual host early in your config by using "<VirtualHost *:443>". You can decide whether this should return a 404 or do something useful on random SSL connections.
  5. Go nuts adding more SSL name-based virtual hosts.

The word on the street is that the Apache folks don't want you to know about this because it's "wrong"; presumably they're concerned about getting users used to clicking "OK" on host/cert mismatches. There's a proposal underway to modify SSL so that the web server can find out the host being requested before setting up an SSL connection and present the appropriate cert; I hear that many of the Apache folks don't like that either for some mysterious reason. For myself, I'm unwilling to pay for a commercial cert (and unsure why SSL can't have a mode that merely provides encryption without authentication), so I'm happy to have my stuff just work.

Hopefully I'm the only one who's going to hit my personal to-do list site anyhow. (B)