BeetleJuice BeetleJuice - 9 months ago 42
PHP Question

Same cURL script works in dev. Can't figure out why not in production

This is the script, working on my dev machine:

$certPath = SITE_ROOT.'/certs/GoDaddyRootCertificateAuthority-G2.crt';
$options = [
CURLOPT_POSTFIELDS => json_encode(['name'=>'value']),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_CAINFO => $certPath,
$ch = curl_init();

curl_setopt_array($ch, $options);
if( ! $result = curl_exec($ch)) $err = curl_error($ch);

if(!$result) echo $err;
else print_r(json_decode($result,true));

echo '<br/><br/>';
readfile($certPath); //output cert on screen
echo '<br/><br/>';

No issues. Once I move it to my production environment, the cURL connection fails with this error:

SSL certificate problem: unable to get local issuer certificate

  • The same
    contents are printed, so I know the path to the certificate is not the problem.

  • Both environments use
    PHP 5.6.23
    Apache 2.4

  • Dev machine is
    Win 7 x64
    , prod machine is
    Linux CentOS 7

I don't know where to start looking for the cause. Why is the script not working in production?

Thanks to @blackpen's great tip in comments, I learned about the
option used to generate a log of the connection. Here is the output in the broken production environment:

  • Hostname was NOT found in DNS cache

  • Trying

  • Connected to ( 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

Here is the log from the same script, but from the working development environment:

  • Hostname in DNS cache was stale, zapped

  • Trying

  • Connected to ( 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)

Answer Source

I was able to get the script to work in both environments by replacing the .crt that worked only in the dev environments with a file named cacert.pem taken from here

I still don't know what exactly was going on but I suspect that it may have something to do with the formatting of the certificate. Perhaps PHP on Windows could deal with the .crt, but PHP on Linux couldn't. I got the idea from the highest rated answer on another question.