OSX 10.10 Curl POST для HTTPS URL дает ошибку SSLRead ()

70

Недавно я обновился до OSX 10.10. Yosemite и я с момента обновления не могу больше использовать Curl POST для SSL-url.

Сначала я использовал вызов wordpress wp_remote_request, а также попытался использовать curl в php. Оба (как и ожидалось) дают одно и то же сообщение об ошибке:

Номер ошибки: 56

Строка ошибки: ошибка возврата SSLRead() -9806

Примечание: когда я скручиваю POST на HTTP, он работает нормально. Я считаю, что это настройка в PHP.ini или в моем apache (после обновления я потерял свой оригинальный файл HTTPD.conf...).

Может ли кто-нибудь помочь мне?

  • 5
    почему проголосовали ??? Это реальная проблема, с которой я сталкиваюсь и не могу найти хорошего решения в Google.
  • 0
    Чтобы уточнить: я скручиваю POST с моего локального МБ на внешний HTTPS APi
Показать ещё 5 комментариев
Теги:
curl
macos

3 ответа

148
Лучший ответ

Я видел, что эта ошибка возникает, когда php скомпилирован с версией cURL, которая использует Apple Secure Transport под Yosemite и целью Запрос URL-адреса не поддерживает SSLv3 (который, вероятно, был отключен из-за уязвимости POODLE). Каков результат этой команды?

$ php -i | grep "SSL Version"

Я подозреваю, что вы увидите следующее:

SSL Version => SecureTransport

Вы можете преодолеть это, установив версию php, которая использует версию cURL, которая использует OpenSSL вместо SecureTransport. Это проще всего сделать с homebrew. Поэтому сначала установите это, если у вас его еще нет. Если homebrew установлен, но вы не запустили brew update с момента обновления до Yosemite, сделайте это первым. Также убедитесь, что вы установили XCode >= 6.1 и новейшие инструменты командной строки XCode. brew doctor расскажет вам, сделали ли вы все правильно.

Добавьте метки Homebrew ниже, которые вам понадобятся, чтобы установить пивоваренный php. Пропустите этот шаг, если эти репозитории уже прослушиваются. Если вы не уверены, что эти репозитории уже используются, просто запустите приведенные ниже команды. В худшем случае вы получите безобидный Warning: Already tapped!

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

Затем установите curl с помощью openssl:

$ brew install --with-openssl 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, следуйте инструкциям caveat для начала 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 должно исчезнуть.

  • 2
    Привет Асаф, Да, у меня есть версия SSL => SecureTransport. У меня есть Brew, просто интересно, переустановит ли Brew мой текущий php, или он добавит еще одну версию PHP вместе с тем, чтобы мне пришлось отключить стоковую версию? Также спасибо за ваш тщательный ответ. Я бы сам не выяснил, к конкретной проблеме
  • 0
    это информация openssl, которую я получил: New, TLSv1/SSLv3, Cipher is RC4-MD5 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : RC4-MD5 Session-ID: 0B220000E93AF2E279F784D25D6FC08675E63F983424A4296BEBE59AF89F3E7C Session-ID-ctx: Master-Key: 4B0BFE2ECC5624D0E3A2AD44FF6DC30F25E0C4889C6CA5EF0D0E90C1469D70C9D6B5321A4B2C1A084355A79A013C4420 Key-Arg : None Start Time: 1414123290 Timeout : 300 (sec) Verify return code: 0 (ok)
Показать ещё 24 комментария
4

Эта ошибка SSL (код OSStatus: 9806) означает, что ваше соединение завершается сервером из-за ошибки при установлении соединения (например, при некорректной команде). Это происходит только в случаях, когда соединение SSL с удаленным хостом находится между ними.

Это плохо документировано руководством SSL (SSL_get_error), однако это сообщение об ошибке приходит из libcurl, построенного, которое используется с помощью защищенного сервера SecureTransport/Darwinssl TLS (вы можете найти его заголовок OSStatus в SecureTransport.h):

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

Из моего опыта это обычно происходит, когда вы находитесь за прокси-сервером или подключаетесь к ограниченной сети, использующей механизм аутентификации.

Итак, убедитесь, что вы подключены к правильной сети (через WiFi), а другой HTTPS работает правильно. Если нет, проверьте, нужно ли указывать учетные данные прокси-сервера, или ваш интернет-провайдер переопределяет цепочку сертификатов и требует какой-либо проверки подлинности или в основном блокирует доступ к определенным сайтам в своем брандмауэре.

1

У меня была аналогичная проблема с ошибкой 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_setopt для документации.

Это сработало для меня, и мне не нужно ничего менять с помощью cURL или PHP. Но это решение одного из многих случаев, когда появляется error -9806.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню