在JavaScript中检测SNI(服务器名称指示)浏览器支持

12

我希望能够检测浏览器是否支持SNI - 服务器名称指示。我希望将不兼容的客户端重定向到另一个地址。

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

4个回答

4
您可以设置一个支持SNI的服务器,为需要SNI的两个主机名提供服务,并设置一个备用解决方案,两者都提供它们托管的名称。
例如:
- `https://www.example.com/name` 返回一个表示说“我是www.example.com”。 - `https://www.example.net/name` 返回“我是www.example.net”(并且需要SNI)。
如果您向 `https://www.example.net/name` 发送XHR请求并返回 `www.example.com`,那么浏览器就不支持SNI。

是的,我所说的备用方案就是默认值。如果需要的话,您可以连接到两个并比较您得到的结果。 - Bruno
那听起来是个好主意。我会测试一下,这对我很有用。 - Andres Olarte

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并显示浏览器太旧的页面)。但是您将始终收到错误。无法避免。浏览器说hello IP ...,apache回复hello,这是我的证书。如果浏览器在hello中没有提供SNI,则apache仅发送默认(即错误)证书。然后浏览器会抱怨。
如果您想从http开始,然后再切换到https,那么可以在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}。这段代码可以改进,但您已经了解了大致意思。

我不认为如果 SSL 握手失败,浏览器会看到重定向,因此我认为基于 SSL_TLS_SNI 变量的重定向不起作用。 - Simon East

1

在需要使用SNI之前,您只能测试是否支持它。也就是说,您不能强制用户使用SNI HTTPS,然后在不支持时回退,因为他们将收到类似于以下错误(来自Windows XP上的Chrome),没有继续的方法。

很遗憾,用户必须从不安全的HTTP连接开始,只有在支持SNI时才能升级。
您可以通过以下方式检测SNI支持:
  1. 远程脚本
    从您的普通HTTP页面加载一个来自目标SNI HTTPS服务器的<script>,如果脚本正确加载和运行,您就知道浏览器支持SNI。

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

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

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


0

自从commercerack为所有站点升级到SNI后,我们遇到了同样的问题。(用户开始结账并遇到严重的SSL问题)。

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

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


第83行有错误吗?如果(/Android\s2.[012]+/){ browserSNICompatibility = 0; } ...看不到要在正则表达式上使用的字符串变量? - Kevin_Kinsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接