说,我有一个使用Apache Httpd托管的网站mywebsite.com
。现在我想要的是,无论何时任何用户键入mywebsite.com
或www.mywebsite.com
,如果浏览器支持SNI,那么它应该重定向到https://www.mywebsite.com
,否则重定向到http://www.mywebsite.com
。
那么,实现它的最有效方法是什么?
答案 0 :(得分:2)
以下代码应该有效
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]
这里我们忽略了大多数不支持SNI的浏览器,因此只会加载http版本。
答案 1 :(得分:1)
更好的解决方案是
#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]
这忽略了MSIE 5-8,它排除了XP上的所有IE,加上一些可用的VISTA。但允许XP使用chrome,firefox,opera,所有这些都支持XP上的SNI。这至少允许XP用户使用https。同样,它假设所有的symbian,blackbery都没有sni。而且知识产权3确实如此(据我所知,平板电脑需要4个)。
对于其他解决方案,您可以
#Could use this to set $_SERVER['SSL_TLS_SNI'] for php
SetEnv SSL_TLS_SNI %{SSL:SSL_TLS_SNI}
这会将$ _SERVER [' SSL_TLS_SNI']设置为%{SSL:SSL_TLS_SNI}(可能是更好的代码)或域名。如果您知道apache返回的默认证书是什么,并且可以访问该域,那么在其他域中您可以让php对默认域执行测试https,然后检查$ _SERVER [' SSL_TLS_SNI']在进入https之前测试SNI。
注意如果非sni浏览器对需要sni的站点进行https,则无法避免出现错误消息。你能做的最好的就是
# 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]
用户需要接受浏览器错误并继续访问网站,之后他会被重定向到http和错误页面。
答案 2 :(得分:1)
这是我根据上述答案使用的。
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]
如果未列出useragent,则首先重写为http,然后重写为https。 我不知道这是不是有两次重写,但我相信谷歌和其他相关的机器人更喜欢索引https。这种方式实现了(我想:):
我的向后做法但它似乎有效。我相信你会更好地将黑名单列入黑名单,并将它们导航到HTTP而不是白名单浏览器,因为要添加的内容太多了。
每个站点都不同,根据安全性,上述可能是一种选择。
请让我知道你的想法。
答案 3 :(得分:0)
您可以设置第二个只能与SNI一起使用的服务器,并使第一个站点上的页面向它发出Ajax请求(如果需要,可能带有一些标识符)。
如果客户端不支持SNI,则服务器将显示所请求主机名的无效证书。因此,Ajax请求不起作用。您可以让初始页面对该失败做出反应,这表明SNI不受支持。
当然,这并不完美,但这可能比依赖明确的用户代理列表(取决于您的约束)更好。这将更直接地测试客户端功能。