Shared IP, multiple vhosts and multiple SSL certificates on Apache

I’ve been trying to figure out a way to have two domains on a single physical server with two different SSL certificates.
Turns out that it is possible to have multiple VirtualHosts on port 80 (Default http), but because of a limitation of SSL, we can’t have multiple VirtualHosts on port 443 (Default https).
I solved the problem as follows. I created the two VirtualHosts on port 80, one on port 443 and one on port 444. I then made a RewriteRule in an .htaccess file that automatically redirects requests on http://www.abc.com/user to https://www.abc.com:444/user.
How self-signed certificates are generated is described here

Example:

NameVirtualHost 12.34.45.56:80
<VirtualHost 12.34.45.56:80>
ServerName localhost
ServerAdmin root@localhost
DocumentRoot /var/www/sharedip
</VirtualHost>

##########
#Vhost 1, port 80
##########
<VirtualHost 12.34.45.56:80>
ServerName www.xyz.com
ServerAdmin root@xyz.com
DocumentRoot /var/www/website1
ErrorLog /var/log/www/website1
</VirtualHost>

##########
#Vhost 1, port 443
##########
<VirtualHost 12.34.45.56:443>
ServerName www.xyz.com
ServerAdmin root@xyz.com
DocumentRoot /var/www/website1
ErrorLog /var/log/www/website1
SSLCertificateFile /var/www/website1/ssl/cert
SSLCertificateKeyFile /var/www/website1/ssl/key
SSLEngine On
</VirtualHost>

##########
#Vhost 2, port 80
##########
<VirtualHost 12.34.45.56:80>
ServerName www.abc.com
ServerAdmin root@abc.com
DocumentRoot /var/www/website2
ErrorLog /var/log/www/website2
</VirtualHost>

##########
#Vhost 2, port 444
##########
<VirtualHost 12.34.45.56:444>
ServerName www.abc.com
ServerAdmin root@abc.com
DocumentRoot /var/www/website2
ErrorLog /var/log/www/website2
SSLCertificateFile /var/www/website2/ssl/cert
SSLCertificateKeyFile /var/www/website2/ssl/key
SSLEngine On
</VirtualHost>

Now, we only need the automatic redirect in the .htaccess file when people visit http:// instead of https://. Just add these lines to the file:

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} <actualdirname>
RewriteRule ^(.*)$ https://www.abc.com:444/<actualdirname>/

If the entire site needs to use the SSL connection, you can skip the 3rd line and the part with <actualdirname> in the 4th line.
Because we don’t use the default SSL port for this connection, we need to make sure Apache listens on port 444 as well. This is easily accomplished by adding the line
Listen 444
to your ports.conf file (usually /etc/apache2/ports.conf in Ubuntu)

The same trick can be applied to the site with the https on port 443, to prevent the usage of an unsecure http:// request, by forcing the use of https. All requests the the standard http port will be rewritten to use https.
Don’t forget to reload the Apache configuration! (/etc/init.d/apache2 reload)

Edit:
Another way of achieving more or less the same is described here

This entry was posted in Server. Bookmark the permalink.

7 Responses to Shared IP, multiple vhosts and multiple SSL certificates on Apache

  1. drax says:

    Hi,

    Just to point out… The point of SSL is for data to be encrypted. With the technique above, the user first goes to a HTTP site, then gets redirected to a HTTPS site on a particular port. Am I right?
    So the data is send in cleartext to the server, the server redirects the clients, and the clients re-sends the data, via https.
    This defeats the whole point of SSL does it not?

    Thanks for the link

  2. Guido says:

    Not entirely. It is only a little trick, when people ‘forget’ to use the https:// and the alternative port number. All requests for a certain http://www.xyz.com/ are then automatically rewritten to the https:// address.
    For instance, when I visit http://www.xyz.com/mail and I have a rewrite rule for that location, my browser address bar will show me https://www.xyz.com:444/mail.
    Another way of looking at it is that with this .htaccess method, you essentially deny access to the unsecured http:// location, and force the use of https://

  3. drax says:

    Ah ok, I understand your setup. You must make sure no user submits data to the http:// version (like a form) because it *will* work (transparently of course).
    Good idea though, I will use it for those lazy users ;)

  4. Ric says:

    This requires an additional port for each virtual host and a restart of apache each time you add one.
    The sweon solution uses a map which can be updated and require no restart and only one port.

  5. Mike Sharkey says:

    However, the sweon solution does not allow for multiple cert files, which I think limits you to using only sub-domains unless you have a cert that covers multiple fqdns? Right? Or am I missing something?

    This solution, although it consumes ports, does allow you to use the non-standard ports pretty transparently to the user, as well as allowing separate certs for each fqdn.

    –Mike

  6. Stephen says:

    You should change your wording as it is misleading. You did not “solve” anything. You are just bypassing the limitation of SSL by having it redirect to port 444.
    Traffic will still be sent to port 80 first on vhost 2, the rewrite rule will catch it and then send it on to port 444.

    I’m thinking this could be potentially dangerous at some point.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>