7

说,我有一个网站mywebsite.com,使用 Apache Httpd 托管。现在我想要的是,只要有任何用户类型mywebsite.com,或者www.mywebsite.com如果浏览器支持 SNI,那么它应该重定向到https://www.mywebsite.comelse 重定向到http://www.mywebsite.com.

那么,实现它的最有效方法是什么?

4

4 回答 4

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 版本。

于 2014-06-01T17:56:57.810 回答
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 上可以工作的一些 IE。但允许 XP 与 chrome、firefox、opera,所有这些都支持 XP 上的 SNI。这至少允许 XP 用户使用 https。同样,它假设所有 symbian、blackbery 都没有 sni。那个android 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'] 以测试 SNI去https。

请注意,如果非 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 和错误页面。

于 2014-10-10T16:33:09.083 回答
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 而不是将浏览器列入白名单,因为要添加的浏览器太多了。

每个站点都不同,根据安全性,上述可能是一种选择。

请让我知道你的想法。

于 2016-02-10T21:11:30.360 回答
0

您可以设置第二个服务器,该服务器只能与 SNI 一起使用,并使您的第一个站点上的页面向它发出 Ajax 请求(如果需要,可能带有一些标识符)。

如果客户端不支持 SNI,则服务器将为请求的主机名提供无效证书。因此,该 Ajax 请求将不起作用。您可以让您的初始页面对该故障做出反应,作为不支持 SNI 的指示。

当然,这并不完美,但这可能比必须依赖于明确的用户代理列表(取决于您拥有的约束)更好。这将更像是直接测试客户端功能。

于 2014-06-02T01:07:42.310 回答