web-dev-qa-db-ja.com

PHP経由でルートコマンドを実行する

CentOS 5.7 Linuxサーバーを使用しており、php5.3.xを使用しています。

PfSenseシステムでは、php Webページを使用してルート権限が必要なサービスを再起動できます。

同様のことをしようとしています。シェルコマンドを実行するためのphpコードをいくつか作成しました。たとえば、sshdサービスを再起動するには:

<?php
exec('/sbin/service sshd restart');
?>

exec関数を介してそのコマンドを実行しようとしましたが、root権限が必要ですが、Apacheユーザー権限があります。

私はいくつかの解決策に出くわしました:

  1. 「rootユーザーでApacheを実行する」は本当に危険です。私はそれをしたくありません。
  2. 「Apache ALL = NOPASSWD:/ sbin/service to/etc/sudoers」試しましたが、まだ問題があります。

他のソリューションはありますか?答えてくれてありがとう。


今..それは面白いです。 @refp postを試してみましたが、ローカルのUbuntuサーバーで動作しました。しかし、私がcenOS vpsサーバーで同じことを試みたとき。それは機能していません。それはApacheのエラーログ「rm: `/ var/lock/subsys/vsftpd 'を削除できません:許可が拒否されました」

50
Mehmet INCE

試してみる前にこの記事全体を読んでください、選択があります。


バイナリラッパーを使用したソリューション(suidビット付き)

1) rootとして実行したいものを含むスクリプト(できれば_.sh_)を作成します。

_# cat > php_Shell.sh <<CONTENT
  #!/bin/sh
  /sbin/service sshd restart
CONTENT
_

2)このファイルはrootが所有する必要があり、後でroot権限で実行されるため、rootのみがファイルへの書き込み権限を持っていることを確認してください。

_# chown root php_Shell.sh
# chmod u=rwx,go=xr php_Shell.sh
_

スクリプトを実行するユーザーに関係なくスクリプトをルートとして実行するには、バイナリラッパーが必要です。 _php_Shell.sh_を実行するものを作成します。

_# cat > wrapper.c <<CONTENT
  #include <stdlib.h>
  #include <sys/types.h>
  #include <unistd.h>

  int
  main (int argc, char *argv[])
  {
     setuid (0);

     /* WARNING: Only use an absolute path to the script to execute,
      *          a malicious user might fool the binary and execute
      *          arbitary commands if not.
      * */

     system ("/bin/sh /path/to/php_Shell.sh");

     return 0;
   }
CONTENT
_

4) suidビットを含む適切な許可をコンパイルして設定します(root権限で実行する必要があると言います):

_# gcc wrapper.c -o php_root
# chown root php_root
# chmod u=rwx,go=xr,+s php_root
_

_php_root_はroot権限で実行され、_php_Shell.sh_で指定されたコマンドを実行します。


実行するコマンドを簡単に変更するオプションが必要ない場合は、ステップ4で_wrapper.c_にコマンドを直接記述することをお勧めします。その場合、問題のコマンドを実行する外部スクリプトを実行するバイナリを持つ必要はありません。

_wrapper.c_で、system ("your Shell command here");を使用して、実行するコマンドを指定します。

88

PHP Sudoコマンドを実行する必要はありません。トラブルのように聞こえますが、代わりに2つの個別のシステムを作成します。

PHP(Web層)の最初のシステムは、ユーザーリクエストを処理します。Sudoコマンドを必要とするリクエストが作成されると、このリクエストをキューに配置します。これはデータベースである可能性がありますZeroMQなどの何らかのミドルウェア。

2番目のシステム(ビジネス層)は、このキューからメッセージを読み取りまたは受信し、Sudoコマンドを実行できますが、Webサーバープロセスの範囲内にはありません。

これは少しあいまいであり、さまざまなテクノロジーを使用してさまざまな方法で解決できることはわかっていますが、これが最善かつ最も安全な方法だと思います。

22
Luke

パスワードなしでprogram1およびprogram2を実行するために、www-dataユーザーの実行を許可します。

Sudo visudo

Sudoersファイルの内容に追加します。

User_Alias WWW_USER = www-data
Cmnd_Alias WWW_COMMANDS = /sbin/program1, /sbin/program2
WWW_USER ALL = (ALL) NOPASSWD: WWW_COMMANDS

セーブ。

from https://askubuntu.com/questions/76920/call-a-Shell-script-from-php-run-as-root

8
harrrrrrry

バイナリラッパーを使用したソリューション(suidビット付き)FilipRoséen-refp postの一部の変更。

コマンドを変更したwrapper.cを実行するには

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int main (int argc, char  **argv)
{
 setuid (0);
 char cmd[100] = "";
 int i;
 char *p;
 for(i=0; i < argc; i++) {
    if(i != 0){
   strcat(cmd, *(argv+i));
   strcat(cmd, " ");
    }
 }

 system (cmd);

 return 0;
 }

適切な権限をコンパイルして設定します。

  gcc wrapper.c -o php_root     # php_root can be any name.
  chown root php_root
  chmod u=rwx,go=xr,+s php_root

次に、PHPから呼び出します。コマンドを実行します。

 Shell_exec('./php_root '.$cmd);//execute from wrapper
2
sharif143

私は最近、PHPが実際のBashシェルを取得して対話できるようにするプロジェクトを公開しました。これにより、rootとしてログインしたシェルが簡単に得られます。次に、スクリプトにバンドルします。この方法で、リターンを処理することもできます。 https://github.com/merlinthemagic/MTS

ダウンロード後、次のコードを使用するだけです。

$Shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $Shell->exeCmd('service sshd restart');

echo $return1;

//On CentOS 7 output would be like: 
//Redirecting to /bin/systemctl restart  sshd.service

//On CentOS 6 and lower output would be like:
//Stopping sshd:                                             [  OK  ]
//Starting sshd:                                             [  OK  ]
2
MerlinTheMagic