如何模拟非SNI浏览器(没有SNI支持)?

时间:2015-02-03 10:05:06

标签: ssl client sni

我正在为具有多个不同SSL证书的Apache设置Apache,这些证书位于同一服务器上(从而共享相同的IP地址)。

使用Qualys SSL Test我发现有些客户端(即BingBot as of december 2013)不支持SNI扩展。

所以我正在考虑制作一个可以收集此类客户请求的特殊默认Web应用程序,但我该如何模拟这些客户端呢?

我在Windows 8上,如果重要的话,无法访问Linux机箱。

6 个答案:

答案 0 :(得分:17)

您可以使用最常用的SSL库OpenSSL。 Windows二进制文件可供下载。

openssl s_client -connect domain.com:443命令非常适合从客户端测试SSL连接。它默认不支持SNI。您可以附加-servername domain.com参数以启用SNI。

答案 1 :(得分:3)

与openssl类似,s_client是gnutls-cli

gnutls-cli --disable-sni www.google.com

答案 2 :(得分:2)

使用特殊默认Web应用程序的方法根本行不通。

你不能这样做,因为所说的有限客户不仅打开不同的页面,而且完全失败。

  1. 假设您有一个“默认”虚拟主机,非SNI客户端可以正常打开。

  2. 您还有一个额外的虚拟主机应该由支持SNI的客户端打开。

  3. 显然,这两个必须有不同的主机名(比如default.example.comwww.example.com),否则Apache或者nginx不会知道要向哪个连接客户端显示哪个站点。

  4. 现在,如果非SNI客户端尝试打开https://www.example.com,他将会收到来自default.example.com的证书,这会给他一个证书错误。这是一个重要的警告。

    此错误的修复是制作包含www.example.comdefault.example.com的SAN(多域)证书。然后,如果非SNI客户端尝试打开https://www.example.com,他将会看到有效的证书,但即便如此,他的Host:标题仍会指向www.example.com,并且他的请求将被路由到default.example.com但不到www.example.com

    如您所见,您要么完全阻止非SNI客户端,要么将它们转发到预期的vhost。 默认的网络应用程序没有明智的选择。

答案 3 :(得分:2)

如果您使用的是OpenSSL 1.1.0或更早版本,请使用openssl s_client -connect $ip:$port,而OpenSSL将无法启用SNI扩展

如果您使用的是OpenSSL 1.1.1,则需要将-noservername标记添加到openssl s_client

答案 4 :(得分:1)

您可以安装Strawberry Perl,然后使用以下脚本模拟不支持SNI的客户端:

use strict;
use warnings;
use LWP::UserAgent;

my $ua = LWP::UserAgent->new(ssl_opts => {
    # this disables SNI
    SSL_hostname => '', 
    # These disable certificate verification, so that we get a connection even
    # if the certificate does not match the requested host or is invalid.
    # Do not use in production code !!!
    SSL_verify_mode => 0,
    verify_hostname => 0,
});

# request some data
my $res = $ua->get('https://example.com');

# show headers
# pseudo header Client-SSL-Cert-Subject gives information about the
# peers certificate
print $res->headers_as_string;

# show response including header
# print $res->as_string;

通过将SSL_hostname设置为空字符串,您可以禁用SNI,禁用此行会再次启用SNI。

答案 5 :(得分:0)

使用Java HTTP客户端,您可以通过设置系统属性jsse.enableSNIExtension=false来禁用SNI扩展。

更多内容:Java TLS: Disable SNI on client handshake