Такой же скрипт cURL работает в dev. Не могу понять, почему не в производстве

Это сценарий, работающий на моей машине dev:

$certPath = SITE_ROOT.'/certs/GoDaddyRootCertificateAuthority-G2.crt'; $options = [ CURLOPT_POST => 1, CURLOPT_URL => 'https://uat.dwolla.com/oauth/rest/offsitegateway/checkouts', CURLOPT_RETURNTRANSFER => 1, CURLOPT_POSTFIELDS => json_encode(['name'=>'value']), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_SSL_VERIFYPEER => true, CURLOPT_CAINFO => $certPath, ]; $ch = curl_init(); curl_setopt_array($ch, $options); if( ! $result = curl_exec($ch)) $err = curl_error($ch); curl_close($ch); if(!$result) echo $err; else print_r(json_decode($result,true)); echo '<br/><br/>'; readfile($certPath); //output cert on screen echo '<br/><br/>'; 

Без вопросов. Как только я переведу его в свою производственную среду, cURL-соединение завершится с ошибкой:

Ошибка сертификата SSL: невозможно получить сертификат локального эмитента

  • То же .crt содержимое .crt напечатано, поэтому я знаю, что путь к сертификату не является проблемой.
  • Обе среды используют PHP 5.6.23 на Apache 2.4
  • Dev машина Win 7 x64 , prod машина Linux CentOS 7

Я не знаю, с чего начать искать причину. Почему сценарий не работает в производстве?

ОБНОВЛЕНИЕ. Благодаря замечанию @ blackpen в комментариях, я узнал о параметре CURLOPT_VERBOSE используемом для создания журнала соединения. Вот результат в сломанной производственной среде:

  • Имя хоста не было найдено в кеше DNS
  • Попытка 104.20.47.245 …
  • Подключен к uat.dwolla.com (104.20.47.245) порт 443 (# 0)
  • успешно установите места для проверки сертификатов:
  • CAfile: /path/to/GoDaddyRootCertificateAuthority-G2.crt CApath: none
  • Ошибка сертификата SSL: невозможно получить сертификат локального эмитента
  • Закрывающее соединение 0

Вот журнал из того же скрипта, но из рабочей среды разработки:

  • Имя хоста в кэше DNS было устаревшим, zapped
  • Попытка 104.20.48.245 …
  • Подключен к uat.dwolla.com (104.20.48.245) порт 443 (# 0)
  • Cipher selection: ALL:! EXPORT:! EXPORT40:! EXPORT56:! ANULL:! LOW:! RC4: @STRENGTH
  • успешно установите места для проверки сертификатов:
  • CAfile: /path/to/GoDaddyRootCertificateAuthority-G2.crt
    CApath: none
  • NPN, согласованный HTTP1.1
  • SSL-соединение с использованием TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
  • Сертификат сервера:
  • … (информация о сертификате)
  • SSL-сертификат подтвердите.
  • … (подробнее о POST)

Я смог заставить скрипт работать в обеих средах, заменив .crt который работал только в средах dev, с файлом cacert.pem взятым здесь

Я все еще не знаю, что именно происходит, но я подозреваю, что это может иметь какое-то отношение к форматированию сертификата. Возможно, PHP на Windows может иметь дело с .crt , но PHP на Linux не смог. Я получил идею от самого высокого рейтинга ответа на другой вопрос.