Ssl – Apache: rewrite port 80 and 443 – multiple SSL vhosts setup

.htaccessapache-2.2mod-rewritessl

SETUP:

  • multiple SSL domains are configured on a single IP, by using vhosts with different port numbers (on which Apache listens)
  • Apache 2.2.8 on Windows 2003 (no comments on this pls)
  • too many Windows XP users so SNI isn't an option yet

There may be reasons why it's wrong to use this approach, but it works for now.

vhosts setup:

# secure domain 1
<VirtualHost IP:443>
  SSL stuff specifying certificate etc.
  ServerName domain1.org
</VirtualHost>

# secure domain 2
<VirtualHost IP:81>
  SSL stuff for domain2.org
  ServerName domain2.org
</VirtualHost>

GOAL:
Some folders inside the domain2.org docroot need to be secure. I used a .htaccess file to rewrite the URL to https on port 81:

RewriteEngine On
RewriteCond %{SERVER_PORT} !^81$
RewriteRule (.*) https://%{HTTP_HOST}:81%{REQUEST_URI} [R]

Suppose I put the .htaccess in the folder 'secfolder'.
When accessing http://domain2.org/secfolder this gets succesfully rewritten to https://domain2.org:81/secfolder.


ISSUE:
When accessing https://domain2.org/secfolder (without port 81), the certificate from the first vhost (domain1.org) is used and the browser complains that the site is insecure because the certificate is not valid for domain2.org.

I thought that RewriteCond %{SERVER_PORT} !^81$ would also rewrite https://domain2.org to https://domain2.org:81, but it doesn't. It seems that the .htaccess file is not being used at all in this case.

At this point I am not sure how to apply a RewriteRule to https://domain2.org.
I tried creating an additional vhost for domain2 on port 443 before the one for domain1.org, but Apache seems to choke on that. I hope someone of you has an idea how to approach this. TIA.


Edit:
There was an answer which has been deleted, but it said:
"You can't connect to the server without first verifying the certificate and because the certificate is for the wrong domain, you can't redirect." Is the certificate mismatch really the end of the line? No forced redirect/url rewrite possible after that?

Best Answer

Remember that when you make an HTTPS connection to https://domain2.org (which is really a connection to https://domain2.org:443), the order is roughly

  1. Browser opens connection to IP on port 443
  2. Apache looks for a VirtualHost matching the combination IP:443
  3. In this case it finds the VirtualHost for domain1.org
  4. Apache sends the SSL certificate associated with that VirtualHost (i.e. the cert for domain1.org)
  5. [The rest of the SSL negotiation]
  6. Browser sends its HTTP request headers, including the Host: header telling Apache what domain it thinks it's talking to.
  7. If applicable, mod_rewrite processing of the HTTP request headers happens here.

i.e. when Apache decides which certificate to send, it hasn't yet received the information that mod_rewrite would use to do the redirect.

To get around this you'd need a single certificate that was valid for both domains. This could be either a wildcard certificate (if the situation is domain1.example.com and domain2.example.com, get a certificate for *.example.com), or you could try to get an SSL certificate with a Subject of "domain1.org", but a Subject Alternate Name of "domain2.org".

In either case you'd need to do the redirection in the main Apache config files - if it's in a .htaccess file in domain2.org's DocumentRoot, then requests that use domain1.org's VirtualHost will go to a different DocumentRoot directory, and won't ever see the file.