Как имитировать не-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
Подход к использованию специального веб-приложения по умолчанию просто не сработает.
Вы не можете этого сделать, потому что ограниченные клиенты не просто открывают другую страницу, но полностью терпят неудачу.
-
Учтите, что у вас есть "по умолчанию" vhost, который клиент не-SNI откроет просто отлично.
-
У вас также есть дополнительный призрак, который должен быть открыт клиентом, поддерживающим SNI.
-
Очевидно, что эти два должны иметь разные имена хостов (скажем, 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
.