同じサーバー上にある(したがって同じIPアドレスを共有している)異なるドメインに対して、いくつかの異なるSSL証明書を使用してApacheをセットアップしています。
Qualys SSL Test で、SNI拡張機能をサポートしていないクライアント(つまり、 2013年12月現在のBingBot )があることを発見しました。
そのようなクライアントの要求を収集できる特別なデフォルトのWebアプリケーションを作成することを考えていますが、どうすればそれらのクライアントをシミュレートできますか?
私はWindows8を使用しており、Linuxボックスにアクセスできません。
最も一般的に使用されているSSLライブラリであるOpenSSLを使用できます。 Windowsバイナリをダウンロードできます。
openssl s_client -connect domain.com:443
コマンドは、クライアント側からのSSL接続をテストするのに非常に役立ちます。デフォルトではSNIをサポートしていません。 -servername domain.com
引数を追加して、SNIを有効にすることができます。
Openssls_clientと同様にgnutls-cliです
gnutls-cli --disable-sni www.google.com
特別なデフォルトのWebアプリケーションを使用するアプローチは単に機能しません。
限られたクライアントが別のページを開くだけでなく、完全に失敗するため、これを行うことはできません。
非SNIクライアントが問題なく開く「デフォルト」の仮想ホストがあると考えてください。
また、SNIをサポートするクライアントによって開かれることになっている追加の仮想ホストがあります。
明らかに、これら2つは異なるホスト名(たとえば、default.example.com
とwww.example.com
)を持っている必要があります。そうでない場合、Apacheまたはnginxは、どの接続クライアントにどのサイトを表示するかを知りません。
これで、SNI以外のクライアントがhttps://www.example.com
を開こうとすると、default.example.com
からの証明書が提示され、証明書エラーが発生します。これは大きな注意点です。
このエラーの修正は、www.example.com
とdefault.example.com
の両方を含むSAN(マルチドメイン)証明書を作成することです。その後、非SNIクライアントがhttps://www.example.com
を開こうとすると、次のようになります。有効な証明書が提示されますが、それでも彼のHost:
ヘッダーはwww.example.com
を指し、彼のリクエストはdefault.example.com
ではなくwww.example.com
にルーティングされます。
ご覧のとおり、SNI以外のクライアントを完全にブロックするか、予期される仮想ホストに転送します。 デフォルトのWebアプリケーションには賢明なオプションはありません。
OpenSSL 1.1.0以前のバージョンを使用している場合は、openssl s_client -connect $ip:$port
を使用すると、OpenSSLはSNI拡張機能を有効にしません。
OpenSSL 1.1.1を使用している場合は、-noservername
フラグをopenssl s_client
に追加する必要があります。
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が再び有効になります。