使用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。
如果要使用libcurl,请将'CURLOPT_SSLVERSION'设置为'1'(相当于命令行中的'-1')。 – Bruno
对我而言,它安装的是cURL的旧版本。更新它修复了它。 – Justin
顺便说一句,关于SO的一个很好的答案很好的例子。谢谢 –