opensslコマンドは、ホスト名の代わりにIPでNGINXを照会します。

opensslコマンドは、ホスト名の代わりにIPでNGINXを照会します。

これは私が理解するのが難しい状況です。以下のように、nginxに2つのホストブロックを設定しました。

server {
    server_name _;
    listen *:443 default_server deferred;
    return 444;
}
server {
    listen      443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.example.ca;

}

All-inclusiveには自己生成されたSSL証明書があり、私のアプリケーションのブロックには有効なSSL証明書があります。この設定はWebブラウザに適用されます。 Webブラウザがアクセスするhttps://www.example.comと私のアプリケーションにアクセスしますが、アクセスするとhtpps://123.123.123.123何も返しません。ところで今、私は非常に奇妙な状況に直面しています。 (スクリプトで)失敗したドメイン要求を受け取り、デバッグしようとしています。まずURLをカーリングしてみました。

$ curl https://www.example.ca
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none

すべてのブラウザが証明書が動作していることを示し、www.ssllabs.comが動作していることを示すので、これは奇妙だと思います。次に試したのは、コマンドラインでSSL証明書を表示することでした。

echo | openssl s_client -showcerts -connect www.example.ca:443

このコマンドは、実際にそのブロックのSSL証明書の代わりにすべてのサーバーブロックを表示しますexample.ca。 2番目のnginxブロックにIPアドレスを追加すると表示されますexample.ca。これでopensslとcurlが間違った証明書を受け取っているので、間違ったSSL証明書を受け取っていることがわかりますが、なぜですか?

私はopensslについてはよくわかりませんが、openssl / curlがホスト名をIPアドレスに誤って変換したり、正しいヘッダーを追加したりするのを忘れただけです。これはとても奇妙です。誰でももっと詳しく知っていればありがとうございます。

ベストアンサー1

複数の証明書(およびキー)を持つnginxなどの仮想ホストサーバーは、サーバー名表示(SNI)拡張を使用して正しい(仮想ホストと)証明書を選択しますが、SNIはデフォルトではopenssl s_client送信されません。これで基本証明書が作成されました。-servername $hostnameマニュアルページ-connectに記載されているように追加してください。他のスタックにはこのセクションの重複エントリがたくさんありますが、ここでは見つかりません。 (更新:2018年のOpenSSL 1.1.1はこの問題を解決します。指定しない限り、SNIはデフォルトです-noservername。)

OTOH curlSNIは、非常に古いバージョンのカール自体やカールで使用されるミドルウェアです(例:いいえ常にOpenSSLを使用してくださいcurl -V。追加して、-v実行中のタスクとインポートするタスクの詳細を確認し、不十分な場合は tcpdump/Wireshark/etc を使用して回線トレースをインポートします。

おすすめ記事