我可以检测SSL客户端是否不支持服务器名称指示,并在这种情况下提供标准的HTTP网站吗?


8

我将需要使用SSL SNI,但是不幸的是,根据最近的Cloudflare博客文章,只有90%的网络支持它。我如何(例如使用nginx)检测客户端是否支持SNI并提供/重定向到网站的HTTP版本?这可能吗?使用SNI怎么能不丢失10%的流量?假设我没有有效的证书就无法将HTTPS流量重定向到HTTP,这样的请求是不可能的,这是否正确?

谢谢。


在这里提出了一个密切相关的问题:仅当浏览器支持SNI时,才重定向到SSL
Simon East

Answers:


10

如果要从一开始就提供HTTPS,则必须从一开始就提供客户端接受的证书。因为否则客户端将不接受SSL连接,并且您将无法将客户端重定向到其他站点或仅HTTP版本。这意味着要支持这种情况,您

  • 两者都需要拥有包含您所有域的单个证书,以便可以为非SNI客户端提供适当的证书。但是在这种情况下,您根本不需要SNI。
  • 否则您必须安装一些与您的大多数姓名都不匹配的默认证书。在这种情况下,您只能为客户端提供不同的页面,或者如果客户端接受此错误证书,则将其重定向。

如果您不需要从头开始使用HTTPS,也就是说,如果客户端通常首先使用纯HTTP连接,则可以尝试检测SNI支持,以便以后可以重定向客户端。这可以通过在HTTPS站点中包含图像,一些JavaScript或类似内容来完成,如果加载成功,则您知道客户端支持SNI或忽略证书错误。

当然,这一切都会使中间人受到攻击,因为中间人所要做的就是提供一些不同的证书或使HTTPS根本不可用,因为在这种情况下,您将永远不会尝试将连接升级到HTTPS。另外,如果中间人代替,它可以用来使其看起来像客户端支持SNI。而且不仅非SNI客户端会受到此影响,而且具有SNI功能的客户端也只能被拦截。因此,尽管从理论上讲这是可能的,但不建议您这样做,因为您可以将一切简单地摆在中间,从而使使用HTTPS的重点成为现实。


0

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

因此(不幸的是)用户必须实际上从不安全的HTTP连接开始,然后仅在支持SNI的情况下进行升级。

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

  1. 远程脚本
    在纯HTTP页面上,<script>从目标SNI HTTPS服务器加载a ,如果脚本加载并正确运行,则说明浏览器支持SNI。

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.