大変お世話になっております。
GitHubの以下リンクにある、example_usage.php、PaypalIPN.php、certを利用して、paypalのsandboxにpaypalipnというシステムを実装しようとしております。
https://github.com/paypal/ipn-code-samples/tree/master/php
そのシステムは当方のサイトからpaypalに決済情報が送信されると、paypalから折り返し、paypalipnというメッセージを当方のサイトに返信するシステムでございますが、その際に以下のエラーがログに表示されます。
[Wed Jun 19 03:51:17 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: PHP Fatal error: Uncaught exception 'Exception' with message 'cURL error: [77] Problem with the SSL CA cert (path? access rights?)' in /var/www/vhosts/xxxxxx.com/httpdocs/PaypalIPN.php:114
[Wed Jun 19 03:51:17 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: Stack trace:
[Wed Jun 19 03:51:17 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: #0 /var/www/vhosts/xxxxxx.com/httpdocs/example_usage.php(7): PaypalIPN->verifyIPN()
[Wed Jun 19 03:51:17 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: #1 {main}
[Wed Jun 19 03:51:17 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: thrown in /var/www/vhosts/xxxxxx.com/httpdocs/PaypalIPN.php on line 114
上記のエラーのPaypalIPN.php on line 114とはGitHubのサイトの当該ファイルの以下の行です。
throw new Exception("cURL error: [$errno] $errstr");
同様の事例がかなりあり、エラーの内容から、SSL CAのパス、またはそのアクセス権に問題があるということらしいので、いろいろと試しておりますが、問題の原因が分かりません。
本件は当方ウェブサーバー側でのSSL証明書の設定に関する問題であると考えておりますが、本件の様なエラーが表示される場合、具体的に何を調べ、そして何を修正、あるいは新たに設定しなければならないか等をご教授頂けませんでしょうか?
以下は試した結果です。
[root@server-xxxxxxx-x ~]# yum reinstall openssl
Installed:
openssl.x86_64 0:1.0.1e-57.el6
Complete!
[root@server-xxxxxxx-x ~]# yum reinstall ca-certificates
Installed:
ca-certificates.noarch 0:2018.2.22-65.1.el6
Complete!
[root@server-xxxxxxx-x ~]# service nginx restart
Starting nginx: [ OK ]
[root@server-xxxxxxx-x ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
[root@server-xxxxxxx-x ~]# service php-fpm restart
Stopping php-fpm: [ OK ]
Starting php-fpm: [ OK ]
Plesk バージョン: 17.0.17
構成名: Plesk 12 Web Admin for Linux
PHP: 5.3.3
OS: CentOS 6.9
MySQL:5.1.73
apache 2
追記1:
・サーバー直下にcertというフォルダを作成し、GitHubとは別のルートから取得したcacert.pemを当初より配置しておりました。(上記リンクのGitHubから取得したcacert.pemはCApath: noneというエラーが出ていた為。配置ディレクトリ:/httpdocs/cert/cacert.pem) そして、この/httpdocs/cert/cacert.pemは、PaypalIPN.phpによって読まれております。
・サーバーには他にetc/pki/tls/certs/ca-bundle.crtという認証ファイルがあり、(php curl に組み込まれたcerts)用に、PaypalIPN.php内の記述をprivate $use_local_certs = false;に設定し、そのca-bundle.crtを読ませようと試みましたが、エラーは全くなりましたが、期待通りの受信結果を得られず、よってこのPaypalIPN.phpのフローの中で、この試みは機能しないと思われます。
・いろいろと試した結果、エラーが以下に変わりました。
[Thu Jun 20 01:38:05 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: PHP Fatal error: Uncaught exception 'Exception' with message 'cURL error: [60] SSL certificate problem: unable to get local issuer certificate' in /var/www/vhosts/xxxxxx.com/httpdocs/PaypalIPN.php:114
[Thu Jun 20 01:38:05 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: Stack trace:
[Thu Jun 20 01:38:05 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: #0 /var/www/vhosts/xxxxxx.com/httpdocs/example_usage.php(7): PaypalIPN->verifyIPN()
[Thu Jun 20 01:38:05 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: #1 {main}
[Thu Jun 20 01:38:05 2019] [warn] [client xx.x.xx.xxx] mod_fcgid: stderr: thrown in /var/www/vhosts/xxxxxx.com/httpdocs/PaypalIPN.php on line 114
・unable to get local issuer certificateとありますので、クライアントにc:\cert\cacert.pemを配置し、/etc/php.iniに以下を追記し、apacheサーバーを再起動し試しましたが、同じエラーが出ます(php.iniでの追記が機能していない様です。)。私の環境ではこのphp.iniで指定したディレクトリのファイルを読まない様です。php 5.3.3 バージョン依存の為と思われます。
[curl]
curl.cainfo=c:\cert\cacert.pem
追記2:
・今まで、Githubからダウンロードした証明書(cacert.pem)を利用しておりましたので、様々な情報をもとに自己証明書を作成し、その下のコマンドを試しました。
[root@server-xxxxxx-x ~]# cd /etc/pki/ca-trust/source/anchors/
[root@server-xxxxxx-x anchors]# update-ca-trust enable
[root@server-xxxxxx-x anchors]# update-ca-trust extract cacert.pem
[root@server-xxxxxx-x anchors]#
[root@server-xxxxxx-x ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: [ OK ]
・このcacert.pemをcacert.derファイルにして、pcクライアントにダウンロード、ダブルクリックして内容を見ると、その全般タブで証明書の情報:信頼された証明機関がこの証明書を証明できません。と表示されていますが、証明のパスタブでは証明書の状態:この証明書は問題ありません。と表示されています。
・php.iniを追記1のものから以下に変更しましたが、php5.3.3の為か、何の反応もありません。
[CA Certs]
curl.cainfo="/etc/pki/ca-trust/source/anchors/cacert.pem"
openssl.cafile="/etc/pki/ca-trust/source/anchors/cacert.pem"
・追記1でも記しましたが、PaypalIPN.phpの以下の行は本システム上読まれており、パス、あるいはファイル名を変更することによりエラー内容がことなります。そして以下の様にも試しましたが、同じエラーがでます(cURL error: [60] SSL certificate problem: unable to get local issuer certificate)。
curl_setopt($ch, CURLOPT_CAINFO, "/etc/pki/ca-trust/source/anchors/cacert.pem");
・PaypalIPN.php内の以下の$res = curl_exec($ch);の行でpaypalが当サーバーの証明書を読んだ時点で問題ありという上記のエラー(cURL error: [60])になると思います。
const SANDBOX_VERIFY_URI = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr';
~~~~~
$ch = curl_init($this->getPaypalUri());
~~~~~
$res = curl_exec($ch);
if ( ! ($res)) {
$errno = curl_errno($ch);
$errstr = curl_error($ch);
curl_close($ch);
throw new Exception("cURL error: [$errno] $errstr");
}