使用带有SNI的cURL(服务器名称指示)

时间:2012-10-17 19:16:50

标签: php ssl curl sni

我正在尝试使用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);

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

2 个答案:

答案 0 :(得分:45)

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

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

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

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

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

答案 1 :(得分:6)

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

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