12

我希望能够检测浏览器是否支持SNI-Server Name Indication。我希望将不合规的客户重定向到不同的地址。

我正在考虑通过 SSL 加载一些内容并确保它被安全传输。否则浏览器不支持 SNI。这可以做到吗?

4

4 回答 4

4

您可以设置一个支持 SNI 的服务器,提供两个主机名,在您需要 SNI 的地方和一个作为后备解决方案的地方,都提供他们托管的名称。

类似于以下内容:

  • https://www.example.com/name返回一个表示说I'm www.example.com
  • https://www.example.net/name返回I'm www.example.net(并且需要 SNI)。

如果您发出 XHR 请求https://www.example.net/name并返回www.example.com,则浏览器不支持 SNI。

于 2012-07-28T15:15:09.390 回答
1

不确定这是否是想要的,但有这个

  RewriteEngine on

  # 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]

如果旧浏览器尝试使用需要 SNI 的站点,则它将被重定向(在这种情况下返回 http 并且页面显示浏览器太旧)。但是你总是会得到一个错误。这是无法避免的。浏览器说你好 IP....,而 apache 回复你好,这里是我的证书。如果浏览器在 hello apache 中不提供 SNI,则只发送默认(即错误)证书。浏览器然后抱怨。

如果您想在切换到 https 之前从 http 获取它,那么您可以在 htaccess 中放置类似的内容

  #Set $_SERVER['SSL_TLS_SNI'] for php = %{SSL:SSL_TLS_SNI} or value
  SetEnv SSL_TLS_SNI %{SSL:SSL_TLS_SNI}

然后在您的页面中从默认域执行 https 获取(默认因此浏览器不会说存在安全错误)。如果 SNI 正在工作,则 php $_SERVER['SSL_TLS_SNI'] 将具有域名,否则它将具有 %{SSL:SSL_TLS_SNI}。这段代码可以改进,但你明白了。

于 2014-10-10T15:58:31.767 回答
1

您只能在需要之前测试 SNI 支持。也就是说,您不能强制用户使用 SNI HTTPS,然后如果他们不支持它就回退,因为他们将收到这样的错误(来自 Windows XP 上的 Chrome)而无法继续。

因此(不幸的是)用户实际上必须从不安全的 HTTP 连接开始,然后只有在他们支持 SNI 时才进行升级。

您可以通过以下方式检测 SNI 支持:

  1. 远程脚本
    从您的纯 HTTP 页面,<script>从您的目标 SNI HTTPS 服务器加载一个,如果脚本加载并正确运行,您就知道浏览器支持 SNI。

  2. 跨域 AJAX (CORS)
    与选项 1 类似,您可以尝试执行从 HTTP 页面到 HTTPS 的跨域 AJAX 请求,但请注意 CORS仅支持有限的浏览器

  3. 嗅探用户代理
    这可能是最不可靠的方法,您需要决定是拥有一个已知不支持它的浏览器(和操作系统)的黑名单,还是一个已知支持它的系统的白名单。

    我们知道 Windows XP 及以下所有版本的 IE、Chrome 和 Opera 都不支持 SNI。有关支持的浏览器的完整列表,请参阅CanIUse.com

于 2016-09-06T05:28:52.653 回答
0

自从 commercerack 为所有站点升级到 SNI 以来,我们遇到了同样的问题。(用户开始结帐并遇到令人讨厌的 SSL 问题)。

随意将此作为起点。随着浏览器列表的增长,我会更新,但它现在在 XP + Android 2.0-2.2 上运行 IE。

https://github.com/brianhorakh/html-sni-useragent-sniffer-warning

于 2014-03-28T19:20:19.120 回答