php - 相同的 cURL 脚本可以在 dev 中运行。不明白为什么没有投入生产

标签 php ssl curl

这是在我的开发机器上运行的脚本:

$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 certificate problem: unable to get local issuer certificate

  • 打印了相同的 .crt 内容,因此我知道证书的路径不是问题。
  • 两个环境均在 Apache 2.4 上使用 PHP 5.6.23
  • 开发计算机是 Win 7 x64,生产计算机是 Linux CentOS 7

我不知道从哪里开始寻找原因。为什么脚本在生产环境中不起作用?

更新: 感谢 @blackpen 在评论中的精彩提示,我了解了用于生成连接日志的 CURLOPT_VERBOSE 选项。以下是损坏的生产环境中的输出:

  • Hostname was NOT found in DNS cache
  • Trying 104.20.47.245...
  • Connected to uat.dwolla.com (104.20.47.245) port 443 (#0)
  • successfully set certificate verify locations:
  • CAfile: /path/to/GoDaddyRootCertificateAuthority-G2.crt CApath: none
  • SSL certificate problem: unable to get local issuer certificate
  • Closing connection 0

这是来自同一脚本的日志,但来自工作开发环境:

  • Hostname in DNS cache was stale, zapped
  • Trying 104.20.48.245...
  • Connected to uat.dwolla.com (104.20.48.245) port 443 (#0)
  • Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
  • successfully set certificate verify locations:
  • CAfile: /path/to/GoDaddyRootCertificateAuthority-G2.crt
    CApath: none
  • NPN, negotiated HTTP1.1
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
  • Server certificate:
  • ...(cert details)
  • SSL certificate verify ok.
  • ... (more POST details)

最佳答案

通过将仅在开发环境中有效的 .crt 替换为名为 cacert.pem taken from here

我仍然不知道到底发生了什么,但我怀疑这可能与证书的格式有关。也许 Windows 上的 PHP 可以处理 .crt,但 Linux 上的 PHP 却不能。我从评分最高的答案 on another question. 中得到了这个想法

关于php - 相同的 cURL 脚本可以在 dev 中运行。不明白为什么没有投入生产,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39175600/

相关文章:

java - Android Studio/Intellij,Gradle 错误 :Cause: peer not authenticated

google-chrome - httpd-2.4.18 mod_http2 适用于 curl 和 nghttp 但不适用于浏览器

javascript - 在点击文本或图片时显示谷歌饼图?

java - 为 SSL 通信创建证书

php - 如何将这些数据添加到我的临时表中?

ssl - 如何判断一个网站使用的是CA证书还是SSL证书?

java - 将 cURL 转换为 Java 以进行 SOAP 调用

php - 屏幕抓取时我应该使用 Keep-Alive 吗?

PHP 最佳实践跟踪登录用户

php - 使用 PHP 远程 SSL 连接到 AWS( key 对)