ブラウザ経由のPHPスクリプトでcURLが実行されなかった


概要

PHPスクリプトからWeb APIを実行するためにcURLを使おうとしていたが、下記の現象が発生した。
- cURLをシェルで直接実行したら動作する
- シェルからPHPスクリプトを実行すると動作する
- ブラウザでPHPスクリプトにアクセスすると、スクリプトは実行されるが、cURLが動作しない

原因はSELinuxがhttpdからのネットワーク接続を遮断していたためであり、SELinuxの設定変更で解決できた。

現象

確認した環境

  • CentOS 8.1
  • Apache 2.4
  • PHP 7.2
  • cURL 7.61

確認用コード

test.php
<?php
$url=(送信先URL);
$data=(json_encodeされた送信したいデータ);

$ch=curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);

echo 'http_code:' . curl_getinfo($ch, CURLINFO_HTTP_CODE) . "\n";
echo 'curl_errno:' . curl_errno($ch)  . "\n";

curl_close($ch);
?>

実行結果

シェルでphp test.phpを実行すると…

http_code:200
curl_errno:0

APIも正常に実行された。

ブラウザからhttps://example.com/test.phpにアクセスすると…

http_code:0
curl_errno:7

原因

SELinuxのデフォルト設定で、httpdからのネットワーク接続が遮断されてしまっていたため。

解決方法

下記コマンドを実行するだけ!
sudo setsebool -P httpd_can_network_connect 1

参考

php - CURL permission denied via browser, works on ssh - Stack Overflow