将 cURL 与 SNI(服务器名称指示)一起使用

2022-08-30 12:34:55

我正在尝试使用cURL发布到刚刚开始使用SNI的API(因此他们可以在1个IP地址上托管多个SSL证书)。

由于迁移到SNI,我的cURL停止工作。他们解释说,这是因为cURL正在恢复*.domain-a.com 而不是*.domain-b.com 所以SSL失败了。

这似乎是 cURL 中的一个错误,因为从浏览器访问 API URL 时没有错误。

使用此代码,它确实有效:

exec('curl -k -d "parameters=here", https://urlhere.com/', $output);
print_r($output);

但是,使用 -k 是不好的,因为它不会验证 SSL 证书。

使用此代码不起作用:

exec('curl -d "parameters=here", https://urlhere.com/', $output);
print_r($output);

所以我的问题是,我如何将curl与SNI一起使用,同时仍然验证SSL(不必使用-k)。PHP 中是否有其他设置或我可以设置的 cURL 选项来解决此问题?


答案 1

为了能够使用 SNI,需要满足三个条件:

  • 根据更改日志,使用支持它的 Curl 版本,至少为 7.18.1。
  • 使用针对支持SNI的库编译的Curl版本,例如OpenSSL 0.9.8j(取决于一些旧版本的编译选项)。
  • 至少使用 TLS 1.0(不是 SSLv3)。

请注意,Curl 的调试代码 () 仅显示主要版本号(主要是为了区分 SSLv2 和 SSLv3+ 类型的消息,请参阅ssl_tls_trace),因此当您使用 TLS 1.0 或更高版本时,它仍然会显示“SSLv3”(因为它们实际上是 SSL v3.1 或更高版本,3 是相同的主要版本号)。-v

您可以检查您安装的 curl 版本是否可以通过 Wireshark 使用 SNI。如果使用 建立连接,如果展开“客户端问候”消息,则应该能够看到“”扩展名。curl -1 https://somethingserver_name

我不确定当您不使用(对于TLS 1.0)或(对于SSLv3)时,默认情况下使用哪个SSL / TLS版本(取决于您的编译选项),但是您可以尝试强制使用命令,因为它无论如何都不适用于SSLv3。curl-1-3-1


答案 2

与所需的库和 Curl 版本一起,请求应使用 resolve 在 curl 中发送 SNI:

curl -vik --resolve example.com:443:198.18.110.10 https://example.com/

推荐