7

So my SSL certificate only applies to https://example.com - not https://www.example.com (can't complain, it was free).

After venturing into mod_rewrite and a lot of reading (mostly from stackoverflow) I have an .htaccess file that does most of what I need, here is that file (with domain redacted of course).

<IfModule mod_rewrite.c>
    RewriteEngine On

    #First rewrite any request to the wrong domain to use the correct one
    RewriteCond %{HTTP_HOST} !^subdomain\.
    RewriteCond %{HTTP_HOST} ^(www|ftp|mail)\.example\.com [NC]
    RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

    #Redirect these subdomains to a subfolder
    RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$ 
    RewriteCond %1 !^(www|ftp|mail)$ [NC]
    RewriteRule (.+)$ "http://example.com/%1" [L,P]

    #Now, rewrite to HTTPS:
    RewriteCond %{HTTPS} off
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

The script contains comments as to what it does (I need them more than you think). And there is an additional .htaccess file on the folder for the subdomain that is being redirected (a subfolder in the root web folder, with matching subdomain name) and the accompanying dns entry on my dns server. The .htaccess on that folder simply redirects http (port 80) to https.

At the moment, it does what I need but I'm looking for simpler ways to write this. And by simpler it could also mean more global (if it makes it faster than hardcoding domains) and if there are any speed improvements to gain from said rewrite.

As previously mentioned, my certificate is only for a non-www example.com domain so this brings me to the second (but my main) question.

Traffic that is routed like so: https://www.example.com will see the error before any routing, rewrite, etc is ever done. This is because a connection to the web server has not even happened at this point, correct? This is essentially your server handing your certificate over and the browser saying: wait a minute!

Is there a way to prevent traffic to hit your server the improper way (https://www) before the browser gives out a certificate error?

This does not have to be restricted to just the .htaccess method.

Is there a way to do this - at all? And what is that way?

Edit:

I was having a few issues with my conditions and rewrites hitting queries it should not. I was also having a few redirect loops so headed over to apache.org to research that; so just as a way to keep track of said changes here is the .htaccess file now:

<IfModule mod_rewrite.c>
    RewriteEngine On

    # First rewrite any request to the wrong domain to use the correct one
    RewriteCond %{HTTP_HOST} ^(www|ftp|mail)\.example\.com$ [NC]
    RewriteRule ^(.*)$ http://example.com/$1

    # Redirect these subdomains to a subfolder
    RewriteCond %{HTTP_HOST} ^([^/.]+)\.example\.com$
    RewriteCond %{REQUEST_URI} !^([^/.]+)/([^/.]+)
    RewriteCond %1 !^(www|ftp|mail)$ [NC]
    RewriteRule ^(.*)$ http://example.com/%1$1 [L,NC,QSA]

    #Now, rewrite to HTTPS:
    RewriteCond %{HTTPS} off
    RewriteCond %{HTTP_HOST} !^$
    RewriteCond %{HTTP_HOST} ^http://example\.com/$ [NC]
    RewriteRule ^/?(.*) https://%{HTTP_HOST}/$1 [L,R,NE]
</IfModule>
avluis
  • 317
  • 5
  • 18

1 Answers1

12

Is there a way to prevent traffic to hit your server the improper way (https:// www) before the browser gives out a certificate error?

No, there's nothing you can do, your assessment is correct that the browser looks at the server certificate and sees that the host doesn't match and displays the error. The error isn't generated by the server, and this happens before a request is even sent to the server. This happens during the SSL handshake. The only things you can do are prevent any http://www links from existing, or buy a new certificate that includes "www".

As for your rules, there's really no way to simplify it since you have multiple conditions for each rule.

Jon Lin
  • 142,182
  • 29
  • 220
  • 220
  • Thank you! This confirms my doubts. I believe I can request a certificate that includes both domains (www and non-www) as well (not sure of the name). – avluis Dec 28 '14 at 02:05
  • 1
    @avluis most issuers include the "www" in front of the domain as an option, then you can pay more for additional subdomains or a wildcard cert (all subdomains) – Jon Lin Dec 28 '14 at 02:13
  • @JonLin Maybe a solution? The problem is that https://www is serving a certificate and this make the handshake occur BEFORE the htacces redirect. Suppose we would have a way to DISABLE the SSL on the www version of the website? This way there is NO handshake and the directe is executed – snh_nl Feb 06 '15 at 10:49
  • 1
    @snh_nl can't disable the SSL if someone goes to `https://www.`, unless you want to run a non-SSL version no port 443 which would probably cause a different error on the browser. The additional problem with this is then port 443 can't serve SSL and the main site (without the www) can't be hosted on that socket. – Jon Lin Feb 06 '15 at 14:49