Как имитировать не-SNI-браузеры (без поддержки SNI)?

Я настраиваю Apache с несколькими отдельными сертификатами SSL для разных доменов, которые находятся на одном сервере (и, таким образом, используют один и тот же IP-адрес).

С Qualys SSL Test я обнаружил, что есть клиенты (т.е. BingBot по состоянию на декабрь 2013 года), которые не поддерживают расширение SNI.

Поэтому я подумываю о создании специального веб-приложения по умолчанию, которое может собирать запросы таких клиентов, но как имитировать эти клиенты?

Я в Windows 8, без доступа к ящикам Linux, если это имеет значение.

Ответ 1

Вы можете использовать наиболее часто используемую библиотеку SSL, OpenSSL. Для загрузки доступны двоичные файлы Windows.

openssl s_client -connect domain.com:443 очень хорошо проверяет SSL-соединение с клиентской стороны. По умолчанию он не поддерживает SNI. Вы можете добавить аргумент -servername domain.com чтобы включить SNI.

Ответ 2

Подход к использованию специального веб-приложения по умолчанию просто не сработает.

Вы не можете этого сделать, потому что ограниченные клиенты не просто открывают другую страницу, но полностью терпят неудачу.

  1. Учтите, что у вас есть "по умолчанию" vhost, который клиент не-SNI откроет просто отлично.

  2. У вас также есть дополнительный призрак, который должен быть открыт клиентом, поддерживающим SNI.

  3. Очевидно, что эти два должны иметь разные имена хостов (скажем, default.example.com и www.example.com), иначе Apache или nginx не знали бы, какой сайт будет показывать, к кому подключается клиент.

Теперь, если клиент, не являющийся SNI, пытается открыть https://www.example.com, ему будет представлен сертификат с default.example.com, который даст ему ошибку сертификата. Это серьезное предостережение.

Исправление этой ошибки заключается в создании SAN (многодоменного) сертификата, который будет включать в себя как www.example.com и default.example.com. Затем, если клиент, не являющийся SNI, пытается открыть https://www.example.com, ему будет предъявлен действительный сертификат, но даже тогда его заголовок Host: все равно www.example.com на www.example.com, а его запрос будет перенаправлен не на default.example.com а на www.example.com.

Как вы можете видеть, вы либо полностью блокируете клиентов, не являющихся SNI, либо пересылаете их ожидаемому vhost. Там нет разумного варианта для веб-приложения по умолчанию.

Ответ 3

Вы можете установить 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.

Ответ 4

Подобно openssl s_client - gnutls-cli

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

Ответ 5

Если вы используете OpenSSL 1.1.0 или более раннюю версию, используйте openssl s_client -connect $ip:$port, а OpenSSL не включит расширение SNI

Если вы используете OpenSSL 1.1.1, вам нужно добавить флаг -noservername в openssl s_client.