質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.57%

Laravel内のcurlでSSL利用できない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,616

yamayamak

score 106

Laravel 5.5.19を利用しています。

以下のコードで、Laravel内のcurlでSSL利用(HTTPS)できません。
HTTP-Codeは0(ゼロ)になります。
HTTPのSSLでないサイトの場合(HTTP)は同じコードで正常に取得できます。
(HTTP-Codeは200でHTTPコードが取得できます。)

関係ないかもしれませんが、最近になって取得できなくなった気もしていますので、バージョンを記載させて頂きます。

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "https://www.google.com" );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
curl_setopt( $ch, CURLOPT_TIMEOUT, 5 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$result = curl_exec( $ch );
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close( $ch );
\Log::debug("CurlTest:" . $httpCode );

また、同じAWS-Linux上において、curlコマンドを実行したらSSL利用(HTTPS)しても問題なくHTTPコードが取得できて動作しています。

uname -a
Linux ip-172-31-18-75 4.14.62-65.117.amzn1.x86_64 #1 SMP Fri Aug 10 20:03:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

curl -V
curl 7.53.1 (x86_64-redhat-linux-gnu) libcurl/7.53.1 NSS/3.28.4 zlib/1.2.8 libidn2/0.16 libpsl/0.6.2 (+libicu/50.1.2) libssh2/1.4.2 nghttp2/1.21.1
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz HTTP2 UnixSockets HTTPS-proxy PSL

curl "https://www.google.com"
問題なく動作します。


SSL証明書CheckはOFFにしているし同じサーバのCurlコマンドで取得できているので、SSL証明書の設定ではないと考えています。

問題などあればご教授をお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

おそらく証明書の検証で失敗しているはずですので、
エラー内容を表示してみてください。

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "https://www.google.com" );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
curl_setopt( $ch, CURLOPT_TIMEOUT, 5 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
if( ! $result = curl_exec($ch)) {
  \Log::debug("CurlError:" . curl_error($ch));
}

$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close( $ch );
\Log::debug("CurlTest:" . $httpCode );

 以下追記

CA証明書がないエラーが発生する場合がある時の対応
一旦試してもらえますか?

composer require composer/ca-bundle
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, "https://www.google.com" );

$caPathOrFile = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath();
if (is_dir($caPathOrFile) || (is_link($caPathOrFile) && is_dir(readlink($caPathOrFile)))) {
    curl_setopt($curl, CURLOPT_CAPATH, $caPathOrFile);
} else {
    curl_setopt($curl, CURLOPT_CAINFO, $caPathOrFile);
}

curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
curl_setopt( $ch, CURLOPT_TIMEOUT, 5 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
if( ! $result = curl_exec($ch)) {
  \Log::debug("CurlError:" . curl_error($ch));
}

$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close( $ch );
\Log::debug("CurlTest:" . $httpCode );

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/17 10:22

    curl_error($ch)は確認していたのですが何も表示されないです。
    コードを上記の通り実行しましたが、以下のようになります。
    [2018-11-17 10:19:33] testing.DEBUG: CurlError:

    特にエラー内容が表示されていませんが、実行には失敗しているようです。
    これはSSL証明書のエラーでしょうか?
    php.iniの設定でcurl.cainfoを設定していませんが、コマンドで取得できていますので関係ないかと考えていました。
    よろしくお願いします。

    キャンセル

  • 2018/11/17 10:27

    コマンドとLaravelで参照している証明書ストアが異なると想定しています。
    私の環境ではそのPHPコードをそのまま実行したら `200` が返ってきました。

    キャンセル

  • 2018/11/17 10:37

    ありがとうございます。確かに、同じサーバ環境でPHPスクリプトにして実行したら200が返ってきてます。
    LaravelのSSL設定を確認していますが違いになりそうなところがわからないです。継続して調査しますが何かわかればご教授をお願いします。

    キャンセル

  • 2018/11/17 12:07 編集

    大変ありがとうございます。
    ただ、すみませんが、あまり環境を変更したくないため、Composerで追加したくなので、

    //curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($curl, CURLOPT_SSLCERT, '/var/www/html/laravel/ssl/ssl.pem');
    curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);

    の部分を追記修正して試してみましたがNGでした。
    pemファイルは読み込みエラーが出なくなったので読み込めてると思いますが、
    curl_errorは何もなく、curl_getinfo($ch, CURLINFO_HTTP_CODE)は0(ゼロ)で全く同じ状態でした。

    現状では原因がわからず、Laravel上でもコマンドで実行すれば正常に動作するので、以下のコードを追記し失敗時にコマンドで実行(exec)するようにしようと考えてます。

    if ( $httpCode != 200 ) {
    \Log::info("CurlError doCommand" . $httpCode );
    $cmd = "curl \"$url\"";
    exec($cmd, $arr, $res);
    if ($res === 0) {
    $httpCode = 201;
    } else {
    $httpCode = 999;
    }
    }
    return $httpCode;

    のような感じで修正するように考えています。

    キャンセル

check解決した方法

0

原因がわからないので失敗した場合はコマンドを実行するように、
以下のコードを追加しました。

if ( $httpCode != 200 ) {
    \Log::info("CurlError doCommand" . $httpCode );
    $cmd = "curl \"$url\"";
    exec($cmd, $arr, $res);
    if ($res === 0) {
        $httpCode = 201;
    } else {
        $httpCode = 999;
    }
}
return $httpCode;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/12 22:34

    LaravelからのCurlプログラムを実行した場合のみエラーが発生していました。
    最終的には、sudo yum updateでAWSを最新化したら回復しました。
    (反映にはsudo service httpd restartで再起動が必要)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る