file_get_contents(): SSL operation failed に対処した


APIで月次データを取得しているPHPプログラムがエラーを吐くようになりました。

ログ
file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed {"exception":"[object] (ErrorException(code: 0): file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed at /var/www/html/xxx.php:35)

エラーはfile_get_contents()でAPIを叩いている箇所で起こっています。

PHP
$json = file_get_contents("https://example.com/api/v1/get/$code", false, $context);

同じことをcurlで行うと成功するので、API提供元の不具合では無さそうです。

curl -s https://example.com/api/v1/get/999

以下のようにして、サーバ証明書の検証をしないことで回避できそうですが、これは最後の手段としたいです。

PHP
$context = stream_context_create([
    'ssl' => [
        'verify_peer'      => false,
        'verify_peer_name' => false
    ]
]);
$json = file_get_contents("https://example.com/api/v1/get/$code", false, $context);

まず疑うべきは証明書の有効期限切れです。
API提供元は Let's Encrypt を使っています。
そういえば、Let's Encrypt が使用しているルート証明書が9月30日に期限切れになっていたことを思い出しました。
このAPIは月末近くに発動するので、今回その影響を受けた可能性が高いです。

そこでca-certificatesパッケージを最新にしたところ、解消されました!

CentOS7
yum -y update ca-certificates