PHPのファイル関連関数でSSLを使った接続をしようとしたら接続できない 
2015/09/15 Tue.
PHP5.6で「file_get_contens」や「fopen」を使って「https://~」で始まるリモートファイルにアクセスしようとしたら、
とか
SSL operation failed
とかいうエラーを出して接続に失敗する。
なぜだ?
OpenSSLはインストールされている。もちろん、PHPのコンパイル時にも「configure」で組み込んでいる。
「phpinfo()」を確認。
●Registered PHP Streams
「https」が記載されている。
●allow_url_fopen
当然ながら、「On」だ。
うーむ。
あとやってないことと言えば・・・
「ふえぇぇぇぇ。PHPマニュアルちゃんと読んでなかったよぅ」
ということで今からバージョン変更時の注意書きを読みに行く
PHP 5.6.x における OpenSSL 関連の変更
書いてある。
Warning: fopen(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in Command line code on line 1
error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in Command line code on line 1
とか
SSL operation failed
とかいうエラーを出して接続に失敗する。
なぜだ?
OpenSSLはインストールされている。もちろん、PHPのコンパイル時にも「configure」で組み込んでいる。
「phpinfo()」を確認。
●Registered PHP Streams
「https」が記載されている。
●allow_url_fopen
当然ながら、「On」だ。
うーむ。
あとやってないことと言えば・・・
「ふえぇぇぇぇ。PHPマニュアルちゃんと読んでなかったよぅ」
ということで今からバージョン変更時の注意書きを読みに行く
PHP 5.6.x における OpenSSL 関連の変更
書いてある。
<抜粋開始>
暗号化されたすべてのクライアントストリームで、ピア検証がデフォルトで有効になりました。 デフォルトでは、OpenSSL のデフォルト CA バンドルを使ってピア証明書を検証します。 たいていの場合は、正しい SSL 証明書を持つサーバーと通信するならこれを変更する必要はありません。 OpenSSL が、よく知られた CA バンドルを使うように設定されているからです。
</抜粋終了>
ふむ。デフォルトで正当性を検証するようになった。しかし、通常特に何もしなくて良いようだ。
じゃあ、なんで?
var_dump(openssl_get_cert_locations());
で見てみる。
["default_cert_file"]=> string(27) "/usr/local/openssl/cert.pem"
ん?このようなファイルを見た記憶がないな。
どうすりゃいいんだ?
調べる。
以下のコマンドで取れるようだ。
$ curl -o cert.pem http://curl.haxx.se/ca/cacert.pem
が、
$ curl
「そんなコマンドありまへん」
いやん。
それならば、
# pkg install curl
おや?最後のメッセージに「cert.pem」が入ったようなことが書いてある。
# ls /usr/local/openssl
入ってるね。
これで問題なくSSL通信でファイルを取得できるようになりました。
ちなみにAPACHEの再起動は必要ありません。
なお、推奨されていませんが、
こういうやり方でもSSLエラーは回避できる。
が、全てのプログラムを修正するのは大変なので cert.pem を入れたほうが楽。
暗号化されたすべてのクライアントストリームで、ピア検証がデフォルトで有効になりました。 デフォルトでは、OpenSSL のデフォルト CA バンドルを使ってピア証明書を検証します。 たいていの場合は、正しい SSL 証明書を持つサーバーと通信するならこれを変更する必要はありません。 OpenSSL が、よく知られた CA バンドルを使うように設定されているからです。
</抜粋終了>
ふむ。デフォルトで正当性を検証するようになった。しかし、通常特に何もしなくて良いようだ。
じゃあ、なんで?
var_dump(openssl_get_cert_locations());
で見てみる。
["default_cert_file"]=> string(27) "/usr/local/openssl/cert.pem"
ん?このようなファイルを見た記憶がないな。
どうすりゃいいんだ?
調べる。
以下のコマンドで取れるようだ。
$ curl -o cert.pem http://curl.haxx.se/ca/cacert.pem
が、
$ curl
「そんなコマンドありまへん」
いやん。
それならば、
# pkg install curl
おや?最後のメッセージに「cert.pem」が入ったようなことが書いてある。
# ls /usr/local/openssl
入ってるね。
これで問題なくSSL通信でファイルを取得できるようになりました。
ちなみにAPACHEの再起動は必要ありません。
なお、推奨されていませんが、
$context = stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
)
));
file_get_contents('https://xxx.xxx.xxx', false, $context);
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
)
));
file_get_contents('https://xxx.xxx.xxx', false, $context);
こういうやり方でもSSLエラーは回避できる。
が、全てのプログラムを修正するのは大変なので cert.pem を入れたほうが楽。
- 関連記事
category: PHP
この記事へのコメント
コメントの投稿
コメントは全て管理人が内容を確認してから表示されます(非公開コメント除く)。
内容によっては表示されない場合がありますことご了承願います。
内容によっては表示されない場合がありますことご了承願います。