Say, I have a website mywebsite.com
, hosted using Apache Httpd. Now what I want is that whenever any user types mywebsite.com
or www.mywebsite.com
and if the browser supports SNI then it should redirect to https://www.mywebsite.com
else redirect to http://www.mywebsite.com
.
So, what is the most efficient way to achieve it ?
The below code should work
Options -Indexes +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^mywebsite.com$
RewriteCond %{HTTPS} (on|off)
RewriteRule ^(.*)$ http://www.mywebsite.com/$1 [R=302,L]
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_USER_AGENT} !MSIE\s6
RewriteCond %{HTTP_USER_AGENT} !Windows\sNT\s5
RewriteCond %{HTTP_USER_AGENT} !^(.*.symbian.*) [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.blackberry.*) [NC]
RewriteRule ^(.*)$ https://www.mywebsite.com/$1 [R=302,L]
Here we are neglecting most of the browsers which does not support SNI and hence for them only the http version would be loaded.
A better solution would be
#Test if new browser and if so redirect to https
#new browser is not MSIE 5-8, not Android 0-3,
#not any symbian and not any blackbery
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_USER_AGENT} !MSIE\ [5-8] [NC]
RewriteCond %{HTTP_USER_AGENT} !Android.*(Mobile)?\ [0-3] [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.symbian.*) [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.blackberry.*) [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
This ignores MSIE 5-8 which excludes all IE on XP, plus some on VISTA that would work. But allows XP with chrome, firefox, opera, all of which support SNI on XP. That at least allows XP users to use https. Likewise it assumes all symbian, blackbery don't have sni. And that android 3 does (which tablets do I'm told, phones need 4).
For a different solution you could have
#Could use this to set $_SERVER['SSL_TLS_SNI'] for php
SetEnv SSL_TLS_SNI %{SSL:SSL_TLS_SNI}
This would set $_SERVER['SSL_TLS_SNI'] to either %{SSL:SSL_TLS_SNI} (yeah could be better code), or the domain name. If you know what is the default cert that apache returns and have access to that domain then in the other domains you could get php to do a test https to the default domain and then check $_SERVER['SSL_TLS_SNI'] to test for SNI before going to https.
Note there is no way to avoid an error message if a non-sni browser does https to a site which needs sni. The best you can do is
# Test if SNI will work and if not redirect to too old browser page
RewriteCond %{HTTPS} on
RewriteCond %{SSL:SSL_TLS_SNI} =""
RewriteRule ^ http://www.example.com/too-old-browser [L,R=307]
The user needs to accept the browser error and continue to website, after which he gets redirected to http and the error page.
This is what I used based on the answers above.
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=302]
RewriteCond %{HTTP_USER_AGENT} !MSIE\s7
RewriteCond %{HTTP_USER_AGENT} !Windows\sNT\s5
RewriteCond %{HTTP_USER_AGENT} !Android.*(Mobile)?\ [0-3] [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.symbian.*) [NC]
RewriteCond %{HTTP_USER_AGENT} !^(.*.blackberry.*) [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
This rewrites to http first and then rewrites to https if useragent is not listed. I dont know if this is bad having two rewrites but I am sure google and other relevant bots prefer indexing https. This way achieves that (I Think :)
My backwards way of doing it but it seems to work. I am sure your better blacklisting browsers and navigating them to HTTP rather than whitelisting browsers as there is way too many to add.
Every site is different and depending on security the above could be an option.
Please let me know your thoughts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With