次のコマンドでsni対応サーバーに対してcurlを実行しています
curl --cacert CustomCA.crt -H "Host: example.com" https://1.2.3.4/foo
ただし、共通名(CN)がexample.comとして設定されているため、正しい証明書を取得できません(そのため、証明書の検証に失敗しました)。 Webブラウザからアクセスすると正しい証明書が配信されるので、SNI構成が正しく行われていることがわかります。念のため、私の現在の環境は
> curl --version
curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3
Protocols: dict file ftp ftps Gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
> lsb_release -a
LSB Version: core-2.0-AMD64:core-2.0-noarch:core-3.0-AMD64:core-3.0-noarch:core-3.1-AMD64:core-3.1-noarch:core-3.2-AMD64:core-3.2-noarch:core-4.0-AMD64:core-4.0-noarch:core-4.1-AMD64:core-4.1-noarch:security-4.0-AMD64:security-4.0-noarch:security-4.1-AMD64:security-4.1-noarch
Distributor ID: Ubuntu
Description: Ubuntu 14.04.1 LTS
Release: 14.04
Codename: trusty
編集:example.comを1.2.3.4にマップするDNSエントリがないことを言及するのを忘れていました。これは実際には私の作業の一部であり、Rubyで次のように実行しました。
context = OpenSSL::SSL::SSLContext.new
context.ca_file = 'CustomCA.crt'
context.verify_mode = OpenSSL::SSL::VERIFY_PEER
tcp_client = TCPSocket.new('1.2.3.4', 443)
ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client, context)
ssl_client.hostname = 'example.com'
ssl_client.connect
cert = OpenSSL::X509::Certificate.new(ssl_client.peer_cert)
cert_ca = OpenSSL::X509::Certificate.new(File.read(ca_path))
ssl_client.sysclose
tcp_client.close
Curlを使用してこのようなものを再作成する方法を考えているところです。
そして.../etc/hostsの自分のコピーを編集することで、コマンドは適切に動作します
1.2.3.4 example.com
何故ですか?
編集2:opensslを介してそれを行う
openssl s_client -connect 1.2.3.4:443 -servername example.com
HostヘッダーはSNIとは関係ありません。 SNIを使用するには、URLでホスト名を使用する必要があります。つまり、_https://example.com/
_ではなく_http://1.2.3.4/
_を使用します(もちろん、http://ではなくhttps://を使用します)。
詳細:SNIはTLSハンドシェイク(ClientHello)内でホスト名を送信します。次に、サーバーはこの情報に基づいて正しい証明書を選択します。 TLS接続が正常に確立された後にのみ、指定したホストヘッダーを含むHTTP要求が送信されます。
編集/コメントについて:
/etc/hosts
_に追加すると、curlで_https://example.com
_にアクセスするときに機能します。SNIのホスト名とTCP =接続。this を参照した後、最後に答えが見つかりました。
curl --cacert CustomCA.crt --resolve example.com:443:1.2.3.4 https://example.com/foo