我正在使用以下命令对启用了 sni 的服务器运行 curl
curl --cacert CustomCA.crt -H "Host: example.com" https://1.2.3.4/foo
Run Code Online (Sandbox Code Playgroud)
但是,我没有得到正确的证书,其中通用名称 (CN) 设置为 example.com(因此证书验证失败)。我知道 SNI 配置是正确完成的,因为我看到在通过 Web 浏览器访问时提供了正确的证书。以防万一,我目前的环境是
> 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
Run Code Online (Sandbox Code Playgroud)
编辑:我忘了提到没有将 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
Run Code Online (Sandbox Code Playgroud)
我只是想知道如何通过使用 curl 来重新创建这样的东西。
而且...通过编辑我自己的 /etc/hosts 副本,该命令将正常工作
1.2.3.4 example.com
Run Code Online (Sandbox Code Playgroud)
这是为什么?
编辑 2:通过 openssl 进行
openssl s_client -connect 1.2.3.4:443 -servername example.com
Run Code Online (Sandbox Code Playgroud)
Jef*_*y04 24
参考this后终于找到了答案。
curl --cacert CustomCA.crt --resolve example.com:443:1.2.3.4 https://example.com/foo
Run Code Online (Sandbox Code Playgroud)
主机头与 SNI 无关。要使用 SNI,您必须在 URL 中使用主机名,即使用https://example.com/而不是http://1.2.3.4/(当然使用 https:// 而不是 http://)。
更多细节:SNI 在 TLS 握手 (ClientHello) 中发送主机名。然后服务器根据此信息选择正确的证书。只有在 TLS 连接成功建立后,它才会发送 HTTP-Request,其中包含您指定的 Host 标头。
关于您的编辑/评论:
/etc/hosts它,则在使用https://example.comcurl访问时将起作用,因为您知道您拥有 SNI 的主机名和 TCP 连接的匹配 IP。| 归档时间: |
|
| 查看次数: |
21184 次 |
| 最近记录: |