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

问题描述:

我想用cURL发布到刚刚开始使用SNI的API(以便他们可以在1个IP地址上托管多个ssl证书)。使用cURL与SNI(服务器名称指示)

由于此举迁移至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); 

所以我的问题是,我该如何使用卷曲符合SNI,仍然验证SSL(没有使用-k)。 PHP中是否有另一个设置或我可以设置的卷曲选项来解决此问题?

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

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

需要注意的是卷曲的调试代码(-v)只显示主版本号(主要的SSLv2和SSLv3的+消息类型之间的区别,见ssl_tls_trace),所以当你使用TLS 1.0它仍然会显示“的SSLv3”或以上(因为它们实际上是SSL v3.1或更高版本,3是相同的主要版本号)。

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

我不知道该SSL/TLS版本默认情况下使用(取决于你的编译选项)当您使用curl没有-1(用于TLS 1.0)或-3(用于在SSLv3),但你可以尝试强制-1在你的命令上,因为它无论如何都不能用于SSLv3。

+0

如果要使用libcurl,请将'CURLOPT_SSLVERSION'设置为'1'(相当于命令行中的'-1')。 – Bruno

+0

对我而言,它安装的是cURL的旧版本。更新它修复了它。 – Justin

+3

顺便说一句,关于SO的一个很好的答案很好的例子。谢谢 –