Osx 10.10 Curl POST to HTTPS url 给出 SSLRead()错误

我最近升级到了 OSX 10.10 Yosemite,自从升级之后,我再也不能使用 Curl POST 到 SSL 地址了。

我首先使用 wordpress 的 wp_remote_request调用,并尝试在 php 中使用 curl。 两者(正如预期的那样)都给出了相同的错误消息:

错误编号: 56

错误字符串: SSLRead ()返回错误 -9806

注意: 当我卷起 POST 到 HTTP 时,它工作得很好。 我估计它是 PHP.ini 或 Apache 中的一个设置(升级后我丢失了原来的 HTTPD.conf 文件...)。

有人能帮帮我吗?

37621 次浏览

当 php 使用在 Yosemite 下使用 苹果的安全运输的 cURL 版本进行编译时,URL 请求的目标不支持 SSLv3(可能由于 贵宾犬漏洞而禁用了 SSLv3) ,我看到了这个错误。这个命令的输出是什么?

$ php -i | grep "SSL Version"

我想你会看到这个:

SSL Version => SecureTransport

您可以通过安装一个使用 cURL 的 php 版本来克服这个问题,该版本使用 OpenSSL 而不是 SecureTransport。这是最容易做到与 自酿的。所以,如果你还没有安装的话,请先安装它。如果你已经安装了自制程序,但是自从升级到约塞米蒂之后你还没有运行过 brew update,那么你应该先做这件事。还要确保安装了 XCode > = 6.1和最新的 XCode 命令行工具。brew doctor会告诉你你是否做得很好。

在下面添加你需要的 Homebrewps 按钮,这样你就可以安装你自己酿造的 php 了。如果这些回购协议已被触发,请跳过此步骤。如果你不确定这些回购协议是否已经被触发,只需运行下面的命令。最坏的情况,你会得到一个无害的 Warning: Already tapped!

$ brew tap homebrew/dupes
$ brew tap homebrew/versions
$ brew tap homebrew/php

然后用 openssl 安装 curl:

$ brew install --with-openssl curl

然后使用您刚刚安装并酿造的 curl 安装 php openssl:

$ brew install --with-homebrew-curl --with-httpd24 php55
  • 如果使用 apache,请确保将 LoadModule php5_module /usr/local/opt/php55/libexec/apache2/libphp5.so添加到 /etc/apache2/httpd.conf并重新启动 apache。

  • 如果不使用 apache 2.4,可以从上面的命令中删除 --with-httpd24

  • 如果使用 nginx,请遵循启动 fpm 的说明:

    启动时启动 php-fpm:

    mkdir -p ~/Library/LaunchAgents
    cp /usr/local/opt/php55/homebrew.mxcl.php55.plist ~/Library/LaunchAgents/
    launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.php55.plist
    

安装任何你需要的 php 扩展,例如 mcrypt

$ brew install php55-mcrypt

完成后,再运行一次:

$ php -i | grep "SSL Version"

你应该看到:

SSL Version => OpenSSL/1.0.2h

现在,重新测试您的应用程序,SSLRead() return error -9806应该会消失。

这个 SSL 错误(OSStatus 代码: 9806)意味着您的连接由于建立连接时的错误而被服务器终止(例如在一些无效命令上)。这种情况似乎只有在与远程主机的 SSL 连接中断的情况下才会发生。

SSL 手册(SSL_get_error)没有很好地记录这一点,但是这个错误消息来自于 SecureTransport/Darwinssl TLS 后端使用的构建的 libcurl(你可以在 SecureTransport.h头文件中找到它的 OSStatus) :

errSSLClosedAbort           = -9806,    /* connection closed via error */

根据我的经验,这通常发生在代理后面或连接到使用身份验证机制的有限网络时。

因此,请确认您连接到正确的网络(通过 WiFi)和您的其他 HTTPS 正常工作。如果没有,请检查是否需要指定代理凭据,或者您的 ISP 正在覆盖证书链,并且需要某种身份验证,或者它基本上阻止了对防火墙中某些站点的访问。

我有一个类似的问题与 SSLRead() return error -9806错误,我也有 SSL Version => SecureTransport

但对我来说,问题在于我设置了 curl CURLOPT_HTTP_VERSION选项:

$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);

如果删除该选项,cURL 将决定默认使用哪个版本。

这对我来说很有用,我不需要用 cURL 或 PHP 修改任何东西。但这只是 error -9806出现的众多情况之一的解决方案。