• ベストアンサー

mod_phpで、rootしか実行できないコマンドを実行させたい。

セキュリティに対して危険だというのは承知の上なのですが、 どうしても実行させたいです。 この場合、どのようにするのが(セキュリティ対策を含めて)得策なのでしょうか? なお、レンタルサーバのVPSを利用していまして、 CentOS4、Apache2.0.52、MySQL4.1.20、PHP4.3.9です。 また、当方、PHPとPerlしか言語の知識はないため、 C言語をつかってハンドラ(でしたっけ?)をつくって、Apacheをカスタマイズ(?)というのはできません。 どうぞ、お助けください。 よろしくお願い申し上げます。

質問者が選んだベストアンサー

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

コマンド実行ならsudoを導入すればよいのでは?

daisuke_dm
質問者

お礼

ありがとうございます。 #1さんのお礼にも書いたように、 #セーフモードを使っているので、system/exec/passthru関数が使えないという問題があるのですが。。。 #セーフモードを一時的にOffにする方法はないのでしょうか? その問題をおいておいて・・・ おっしゃった方法は、具体的には以下の通りで問題ないでしょうか? //========================================================= visudo を使って、 /etc/sudoers の内容を、以下のように編集し、 root ALL=(ALL) ALL apache ALL=/bin/hoge,/var/www/php_cli/foo.php NOPASSWD (apacheはahacheの実行ユーザ) //======================================================== #chown root.root /bin/hoge #chmod 701 /bin/hoge とし、 //======================================================== <?php system("/usr/bin/sudo /bin/hoge") ?> のようにするということでしょうか? また、このようにsudoを使うことは、 セキュリティ的には問題ないでしょうか・・・? 以上、よろしくお願い申し上げます。

daisuke_dm
質問者

補足

補足させてください。 #1さんへの補足に似た内容なのですが・・・。 セーフモードがOnでも実現可能かもしれない方法を思いついたので・・・。 セーフモードがOnでも、 fopenは、 「fopen() 処理を行うディレクトリが実行するスクリプトと同じ UID を有しているかどうかを確認します」 だそうなので、それを同じにしておけば、 system("/foo/bar/hoge")としたい場合、 system関数でなく、fopenのwオプションで、 「$_SERVER["DOCUMENT_ROOT"] . '/../data/cron/」 に、ランダムなファイル名で、「/foo/bar/hoge」と書き込む。 (1ファイルだと衝突がおきるため) で、cronで毎分とかで、rootユーザによって、 これらのファイルの内容を読み込み、実行し、終わったらこれらのファイルを削除するような、シェルスクリプト(苦手ですが)かphp_cliを実行する。(ここではロックファイルをつくったほうがいいかな) というのはどうでしょう? シンプルで、問題発生時にも問題の切り分けができていいかなあと・・・。 よろしくお願い申し上げます。

その他の回答 (1)

回答No.1

実行したいコマンドをrootの所有に変更しsetuidビットをセットすれば良いです。

daisuke_dm
質問者

お礼

ありがとうございます。 1つ言い忘れましたが、セーフモードは有効です。すみません。 ini_set("safe_mode_exec_dir","/"); は危険ですよね・・・。 という問題・・・どうすれば回避できるでしょう。 //============================================= え、その問題をいったんおいといたとして・・・ ご回答の、 実現方法がよくわからなかったものの、 2種類、やり方を考えてみました。 必要十分でしょうか? あと、セキュリティ的にも・・・。 (1) 前もって #chown root.root /bin/hoge #chmod 700 /bin/hoge (<=不要?) #chmod u+s /bin/hoge としておいて、 <?php system("/bin/hoge"); ?> はどうでしょうか? //======================================== (2) <?php $ApacheUserUid = posix_getuid(); posix_setuid(0); //あくまで例 system("updatedb"); posix_setuid($ApacheUserUid); ?> はどうでしょうか? 以上、よろしくお願い申し上げます。

daisuke_dm
質問者

補足

補足させてください。 Setuidはセキュリティ的にあぶないという話を他のサイトでみたのですが、 system("/bin/hoge"); の代わりに、 system("/www/php_cli/hoge.php"); という、cliなphpを実行させて、 (前もって、hoge.phpに対しても、 #chown root.root /bin/hoge #chmod 700 /bin/hoge (<=不要?) #chmod u+s /bin/hoge と同様なことを前もっておこなっておく) で、その中でさらにsystem("/bin/hoge"); するというのはどうでしょう? また、php_cliにすれば、cli.iniというファイルで、 php_cli用の設定ファイルをつくれるらしいので、 そうすれば、php_cliなphpファイルの場合のみセーフモードを有効にできるかと。 どうでしょうか? よろしくお願い申し上げます。

関連するQ&A