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

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

ただいまの
回答率

90.51%

  • PHP

    24056questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Apache

    2108questions

    Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

PHPよりfopen('/path/to/file', 'ab'); が失敗する(Permission denied)

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 4,123

kyapiy

score 10

こちらの環境は、Apache2.4, PHP5.4 です。
お名前.comで借りたVPSサーバを利用し、PHPを利用しサーバ内のmysqlを利用したrssリーダーを作成していました。
管理上、csvファイルにRSSフィードを保存し、web上のフォームよりPHPを利用して新規登録を行う仕組みを作っています。
そこで、apache上のPHPからfopen関数を利用し追記モードでファイルを開こうとしたのですが、失敗します。
/var/httpd/error_logにはpermission deniedと書いてありました。

当該ファイルまでの、ディレクトリの権限は以下です。
root:root 775        / 
root:root 1715      /var
root:apache 1770 /var/www
root:apache 1770 /var/www/html 

追記したいファイル(/var/www/html/test.csv)の権限は root:apache 1660となっています。
httpd.confファイルのUser/Group設定も apache/apacheとなっています。
また、<Directory></Directory>設定もRequire all grantedとなっております。(ルートディレクトリのみRequire all denied)

また、sshを用いてmacより当該のサーバにrootユーザでログインし、そちらでsu apacheとしてからphp opencsvTest.phpでphpを実行した場合は書き込みできます。

ソースコードと実行結果は以下でございます。
#opencsvTest.php#
<?php
    ini_set('display_errors', 1);
    // $usr = posix_getpwuid(posix_geteuid())['name'];
    exec('whoami', $usr);
    exec('groups', $grps);
    $lgnusr = posix_getlogin();
    echo '実行ユーザ=' . implode(', ', $usr) . '<br>所属グループ=' . implode(', ', $grps) . "<br>login=" . $lgnusr;
    $args = array('/var', '/var/www', '/var/www/html');
    echo '<br>書き込み権限チェック開始...<br><br>';

    foreach ($args as $value) {
        if(is_writable($value)) {
            echo "{$value}は書き込み出来ます。<br>";
            $fp = fopen("{$value}/test.csv", 'ab');
            $val = array('this', 'is', 'test', 'file');
            fputcsv($fp, $val);
            fclose($fp);
        }
        else {
            echo "{$value}は書き込みできません。<br>";
        }
    }
?>

実行結果1(ssh root@hoge.com → su apache → php opencsvTest.php)

実行ユーザ=apache<br>
所属グループ=apache<br>
login=root<br>
書き込み権限チェック開始...<br>
<br>
/varは書き込みできません。<br>
/var/wwwは書き込み出来ます。<br>
/var/www/htmlは書き込み出来ます。<br>

実行結果2(webブラウザよりhoge.com/opencsvTest.phpを実行した場合)
実行ユーザ=apache<br>
所属グループ=apache<br>
login=<br>
書き込み権限チェック開始...<br>
<br>
/varは書き込みできません。<br>
/var/wwwは書き込みできません。<br>
/var/www/htmlは書き込みできません。<br>


しばらくweb上を検索して調べてみましたが解決法が見つからないのでこちらで質問させて頂きます。
当該ファイルを追記モードで開く方法、もしくは上の仕様を満たす妥協案などございましたらご教授願います。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

check解決した方法

+1

結局最終的にパーミッションは合っていましたが、書き込みが出来ませんでした。
しかし、更にweb上を徘徊していた所SELinuxについての記述を見つけました。
こちらの設定を変更する事で問題は解決しました!

#semanage fcontext -a -t httpd_sys_rw_content_t /var/www/***/+++/dir
#restorecon -R /var/www/html/***/+++

semanage, restorecon コマンドにつきましては導入されていない環境もありますので探してインストールして頂ければ良いと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

曖昧な回答で恐縮ですが、、

問題のディレクトリ・ファイルのユーザー・グループがroot:apache であることが気になります。
これを
chown -R apache:apache /var/www
として、apache:apacheに変更したら、結果が変わるかもしれません。

また、「実行結果1」の手順を
ssh root@hoge.com → su apache → php opencsvTest.php
から
ssh root@hoge.com → su - apache → php opencsvTest.php
  ※suコマンドにオプション-を追加
とすると、「実行結果2」と同様に失敗できる(w)かも知れません。
http://www.obenri.com/_command/su01.html

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/11/30 23:24

    回答ありがとうございます!

    権限はそのままで、su - apacheからのphp opencsvTest.phpを実行してみた所、見事に失敗しました!w
    また、ディレクトリの所有者についても試してみた所、ssh root@hoge.com → su - apache → php opencsvTest.phpは期待した権限設定通り書き込む事が出来ました。
    しかし、同環境にてブラウザよりhoge.com/opencsvTest.phpを実行した場合は質問文の実行結果2と同様の結果となりました。

    回答に質問で返して申し訳ないのですが、所有者をapacheに変えたとしてapacheの脆弱性を突かれて鯖に侵入されてしまった場合、apache:apacheのファイルorディレクトリがすべて消されるかもしれないというのはいらぬ気遣いでしょうか?
    結局鯖に入られた時点でrootも取られると考えるのが良いんでしょうか?

    キャンセル

  • 2015/12/01 00:10 編集

    kyapiy様、返信ありがとうございます。

    > 同環境にてブラウザよりhoge.com/opencsvTest.phpを実行した場合は質問文の実行結果2と同様の結果となりました。
    ブラウザから実行した場合はドキュメントルートが仮想のルートディレクトリとなるので、
    /var/www/html/var/www/html/
    とったディレクトリの書き込み可否を判定してしまっているはずです。
    https://httpd.apache.org/docs/2.4/mod/core.html#documentroot

    > 所有者をapacheに変えたとしてapacheの脆弱性を突かれて鯖に侵入されてしまった場合...
    そのリスクは確かにありますが、ファイル・ディレクトリの権限で
     正当なapacheユーザー => 書き込みを許可
     不正なapacheユーザー => 書き込みを拒否
    という制御はできません。
    OSは、あるディレクトリにアクセスしようとしているユーザーが正当な手段でログインしているか否かを判断することができないからです。

    セキュリティ対策は、別途、講じる必要があると思います。

    > 鯖に入られた時点でrootも取られると考えるのが良いんでしょうか?
    これはサーバーの設定と、どのような手段で侵入したかによるので、一概には言えないと思います。

    キャンセル

  • 2015/12/01 00:53

    KiyoshiMotoki様、またまたお早い返信感謝の限りです!m(_ _)m

    >ブラウザから実行した場合はドキュメントルートが仮想のルートディレクトリとなるので、
    >/var/www/html/var/www/html/
    >とったディレクトリの書き込み可否を判定してしまっているはずです。
    これです!私はこの答えを待ちわびていました!!!

    なるほど、という事はブラウザから実行する場合にはローカル上で/var/www/html/inc/test.csvでも、
    ブラウザ上で実行する時にはtest.csvをis_writable('/inc/test.csv')と参照するのがpathとして正しいという事ですね。

    ありがとうございます!これで解決しそうです!

    キャンセル

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

  • PHP

    24056questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • Apache

    2108questions

    Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。