Apache multi root SSL Site
Hosting multiple SSL vhosts on a single IP/Port/Certificate with Apache2
Posted by: drax in admin, linux, osx
Tags: 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.
1. Create virtual hosts “map file”.
2. 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.