
exec()関数を使用して次のコマンドを呼び出すPHPスクリプトをいくつか開発したい。
service network restart
crontab -u root /xyz/abc/fjs/crontab
等
問題は、ApacheがホイールにApacheを追加したかどうかに関係なく、Apacheユーザーとしてスクリプトを実行することです(私はCentOS 5を使用しています)。善行、悪行、醜行 グループの割り当てではコマンドは実行されません (前述のとおり)。
私の設定は次のとおりです。
私の /etc/sudoers
root ALL=(ALL) ALL
apache ALL=(ALL) NOPASSWD: ALL
%wheel ALL=(ALL) ALL
%wheel ALL=(ALL) NOPASSWD: ALL
sudoer と httpd.conf の組み合わせをいくつか試してみたところ、最近の httpd.conf は次のようになります。
私のhttpd.conf
User apache
Group wheel
私のPHPスクリプト
exec("service network start", $a);
print_r($a);
exec("sudo -u root service network start", $a);
print_r($a);
出力
Array
(
[0] => Bringing up loopback interface: [FAILED]
[1] => Bringing up interface eth0: [FAILED]
[2] => Bringing up interface eth0_1: [FAILED]
[3] => Bringing up interface eth1: [FAILED]
)
Array
(
[0] => Bringing up loopback interface: [FAILED]
[1] => Bringing up interface eth0: [FAILED]
[2] => Bringing up interface eth0_1: [FAILED]
[3] => Bringing up interface eth1: [FAILED]
)
驚くことではありませんが、Apache などの類似ユーザーを使用して、SSH 経由でネットワーク サービスの再起動を呼び出すと、コマンドは正常に実行されます。これはすべて、HTTP プロトコル経由でこのようなコマンドにアクセスすることです。cPanel/Plesk のようなソフトウェアは sudoer などを使用しているはずで、私がやろうとしていることは基本的に可能です。しかし、どの部分が欠けているのかを理解するには、あなたの助けが必要です。
どうもありがとう!
答え1
troyengel の解決策を採用して、ルート cron テーブルにエントリを追加し、それを少し変更すると、実行可能な解決策になる可能性があります。
インターフェースの再起動を通知するために Apache を絶対に使用する必要がある場合は、PHP でフラグとして機能するファイルを作成し、1 分ごとに (または任意の間隔で) 実行されるルート cronjob でそのフラグの存在をチェックしてみてはいかがでしょうか。フラグが存在する場合は、インターフェースを再起動します。存在しない場合は終了します (インターフェースの再起動に成功したら、cronjob でフラグを削除することを忘れないでください)。
これにより、目標 (apache/php からトリガーされたインターフェイスの再起動) が達成され、Web/スクリプト サービスのルート レベル アクセスの付与に関連する可能性のあるすべての問題が回避されます。
答え2
これらを PHP コマンドライン駆動ツールとして記述し (yum 経由で php-cli パッケージがインストールされていることを確認してください)、通常のユーザーとしてではなく、ルート crontab で直接実行する必要があります。exec() 経由でコマンドを実行するだけであれば、php を使用するのはやりすぎなので、基本的な bash (シェル) スクリプトでも記述することをお勧めします。
答え3
-- を使用して別のユーザーとして実行する必要があるコマンドを呼び出しsudo
、sudoers
PHP スクリプトを実行するユーザーが他のユーザーとしてスクリプトを実行できるように構成ファイルを適切に設定する必要があります。sudosudoers
の使用に関する (5) および以前の 12 件の質問を参照してください。
答え4
スティッキー ビットを使用して、シェル スクリプトを root として実行することもできます。ただし、これを行うには少し複雑です。
ただし、シェル スクリプトに setuid を設定するだけでは不十分です。シェル スクリプトのようにインタープリターを呼び出さない、たとえば C/C++ などの通常の実行可能ファイルを作成し、そのファイルでシェル スクリプトを実行する必要があります。