Hosting multiple SSL vhosts on a single IP/Port/Certificate with Apache2
Posted by: drax in admin, linux, osxTags: apache, ssl, vhosts
But that’s impossible!!
HTTPS is just HTTP encapsulated inside an SSL tunnel. Apache’s virtual hosts are a clever “hack” whereby the Host header in the HTTP packet is verified. This alllows a single apache instance on a single IP/Port combination to serve a (not so) infinite number of differentes sites (aka vhosts).
Problem: The SSL tunnel is created before the first HTTP packet gets sent. Apache needs an SSL certificate but doesn’t have a Host header to match, hence cannot choose a virtual host.
Solution
This trick essentially does the matching of the Host header after the SSL connection has been established. How? Via some mod_rewrite magic!
Caveats
Although I said so, it’s not really that magical. There are a few things this trick does not solve.
- The SSL certificate used will be common to all SSL vhosts.
- Certain Apache directives may be common to all SSL vhosts (example: SuExecUserGroup). Basically anything you can’t override in a .htaccess file will be shared amongst vhosts.
The trick
The process is only 2 steps and involves modifying your Apache configuration. I assume you have a working SSL vhost configured.
- Create virtual hosts “map file”.
- Modify existing SSL vhost.
1. The virtual hosts map file
Create a new file in your Apache server root. Example:/etc/apache2/ssl.map
Write a list of virtual hosts and their respective DocumentRoot. Example:
foo.example.com /var/www/foo.example.com/ bar.example.com /var/www/bar.example.com/ # you can even put comments! # Alias to bar boar.example.com /var/www/bar.example.com/
2. Edit your SSL vhost
Open your Apache config, inside the <VirtualHost> section of your SSL vhost, include the following code or include this file: Mass SSL vhosts Apache config.
Important: Make sure to edit line 8 to include the correct path to your ssl.map file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | ### Mass SSL Vhosts ### RewriteEngine on # define two maps: one for fixing the URL and one which defines # the available virtual hosts with their corresponding # DocumentRoot. RewriteMap lowercase int:tolower RewriteMap vhost txt:/etc/apache2/ssl.map # 1. make sure we don't map for common locations RewriteCond %{REQUEST_URI} !^/cgi-bin/.* RewriteCond %{REQUEST_URI} !^/icons/.* # 2. make sure we have a Host header RewriteCond %{HTTP_HOST} !^$ # 3. lowercase the hostname RewriteCond ${lowercase:%{HTTP_HOST}|NONE} ^(.+)$ # # 4. lookup this hostname in vhost.map and # remember it only when it is a path # (and not "NONE" from above) RewriteCond ${vhost:%1} ^(/.*)$ # 5. finally we can map the URL to its docroot location # and remember the virtual host for logging puposes RewriteRule ^/(.*)$ %1/$1 [E=VHOST:${lowercase:%{HTTP_HOST}}] |
Restart Apache and you’re done. You should be able to browse (in https) the vhosts you added to your ssl.map file.
Grandma says: You don’t need to reload Apache when you edit your map file. Just create the document root folder on the filesystem, add a new entry to your map and you’re good to go.

January 24th, 2008 at 6:25 pm
useful trick !
crystal explanations, simple howto… perfect
THANX !!
February 6th, 2008 at 6:00 pm
Sweet; thanks for the tip!
Is there any way this can work when each vhost also has its own separate virtualhosts.conf file? Or does this work only when they all are configured the same way within the main configuration file (and the server map)?
February 6th, 2008 at 11:12 pm
[...] Edit: Another way of achieving more or less the same is described here [...]
February 11th, 2008 at 5:27 pm
John DeStefano:
As I said, with this technique, any directive in the main configuration file for the SSL vhost, is shared amonst all the SSL vhosts.
However, you can have per-vhost directives if you move them from the configuration file (foo.conf) to a htaccess file in the corresponding DocumentRoot.
Most, but not all directives can be overidden via a htaccess file.
Hope this helped.
May 25th, 2008 at 4:19 am
very cool. thanks.