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

问题描述:

我希望能够检测浏览器是否支持SNI - Server Name Indication。我希望将不符合要求的客户端重定向到不同的地址。在javascript中检测SNI(服务器名称指示)浏览器支持

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

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

东西沿着线:

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

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

+0

您需要确保在没有SNI的情况下,服务器将报告www.example.com。如果我没有记错,Apache在没有SNI时提供它装载的**第一个**证书。 – Andreas 2012-07-28 15:21:57

+0

是的,这就是我所说的回退解决方案的意思:默认值。如果需要,你可以连接到两者并比较你得到的结果。 – Bruno 2012-07-28 15:23:10

+0

这听起来像个好主意。我要测试它,这对我很有用。 – 2012-07-28 15:53:23

由于commercerack已升级到所有网站的SNI,所以我们遇到了同样的问题。 (用户开始签出并获得令人讨厌的SSL问题)。

欢迎以此为出发点。 随着浏览器列表的增长,我会更新,但它现在在XP + Android 2.0-2.2上执行IE。

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

+0

第83行的错误? if(/Android\s2\.[012]+/){browserSNICompatibility = 0; } ...没有看到一个字符串var使用正则表达式? – 2017-11-16 22:02:57

不知道这是什么希望,但有这个

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中没有提供SNI,apache只会发送默认(即错误的)证书。浏览器然后抱怨。

如果你想交换到HTTPS,那么你可以把这样的事情在htaccess的

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

然后在你的页面做一个HTTPS从默认域取(默认设置,以便浏览器之前,从http挑这件事并不是说有安全错误)。如果SNI正在运行,那么在php $ _SERVER ['SSL_TLS_SNI']中将具有域名,否则它将具有%{SSL:SSL_TLS_SNI}。这一点代码可以改进,但你明白了。

+0

如果SSL握手失败,我不认为浏览器会看到重定向,所以我不认为基于SSL_TLS_SNI变量的重定向会起作用。 – 2016-09-06 04:58:03

您只能测试SNI支持之前需要它。也就是说,您不能强制用户使用SNI HTTPS,如果他们不支持,则会退后,因为他们会收到类似的错误(从Windows XP上的Chrome),无法继续。

所以(不幸)的用户实际开始通过不安全的HTTP连接,然后只有当他们支持SNI进行升级。

您可以检测通过SNI支持:

  1. 远程脚本
    从您的普通HTTP页面,加载从您的目的地SNI HTTPS服务器<script>,如果脚本加载和运行正确,你就知道该浏览器支持SNI。

  2. 跨域Ajax(CORS)
    选项1类似,您可以尝试执行从HTTP网页到HTTPS跨域AJAX请求,但是要知道,CORS具有only limited browser support

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

    我们知道所有版本的IE,Chrome &Windows XP及以下版本的Opera不支持SNI。见CanIUse.com for full list of supported browsers