Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么向sudoers文件添加PHP脚本不起作用?_Php_Bash_Nginx_Permissions_Ubuntu 18.04 - Fatal编程技术网

为什么向sudoers文件添加PHP脚本不起作用?

为什么向sudoers文件添加PHP脚本不起作用?,php,bash,nginx,permissions,ubuntu-18.04,Php,Bash,Nginx,Permissions,Ubuntu 18.04,向sudoers文件添加PHP脚本似乎没有效果,而添加bash脚本则允许您以root用户身份运行它。 为了证明这一点,假设我们有以下三个脚本: /var/www/literal.php exec('sudo whoami', $output, $return_var); var_dump($output, $return_var); exec('sudo /var/www/script.sh', $output, $return_var); var_dump($output, $return_

向sudoers文件添加PHP脚本似乎没有效果,而添加bash脚本则允许您以root用户身份运行它。
为了证明这一点,假设我们有以下三个脚本:

/var/www/literal.php

exec('sudo whoami', $output, $return_var);
var_dump($output, $return_var);
exec('sudo /var/www/script.sh', $output, $return_var);
var_dump($output, $return_var);
if (PHP_SAPI !== "cli") {
    exec('sudo /usr/bin/php /var/www/control.php param1 param2', $output, $return_var);
    echo '<pre>';
    var_dump(PHP_SAPI, $output, $return_var);
    exit();
}

exec('whoami', $output, $return_var);
var_dump(PHP_SAPI, $argv, $output, $return_var);
/var/www/indirect.php

exec('sudo whoami', $output, $return_var);
var_dump($output, $return_var);
exec('sudo /var/www/script.sh', $output, $return_var);
var_dump($output, $return_var);
if (PHP_SAPI !== "cli") {
    exec('sudo /usr/bin/php /var/www/control.php param1 param2', $output, $return_var);
    echo '<pre>';
    var_dump(PHP_SAPI, $output, $return_var);
    exit();
}

exec('whoami', $output, $return_var);
var_dump(PHP_SAPI, $argv, $output, $return_var);
/var/www/script.sh

#!/bin/bash
echo "$(whoami)"
还假设我们在sudoers文件中有以下行(当然是通过visudo添加的):

浏览到http://localhost/literal.php 我们得到:

array(0) { }   
int(1)
去http://localhost/indirect.php 然而,我们得到的是:

array(1) {
  [0]=> string(4) "root"
}
int(0)

显然,sudoer行适用于shell脚本,但不适用于PHP脚本。这是一个故意的,设计上的限制,还是我有希望让它工作?如果是这样,我应该在哪里查找原因?

在sudoers文件中指定要运行的精确命令。所以
/var/www/literal.php
至少应该有一个类似于
#的shebang/usr/bin/php
并按原样在shell中启动,方法是键入
/var/www/literal.php
,然后
输入
,以便由
sudo
运行

当您“通过浏览器”运行相同的脚本时,不会发生这种情况。相反,PHP-FPM进程正在解释脚本(NGINX将其文件名传递给PHP-FPM)。您可能会说(尽管这并不完全像这样),实际运行的命令或多或少是
/sbin/php fpm/var/www/literal.php
,这当然与sudoers文件中的命令不匹配

无论您希望通过PHP脚本以
sudo
的形式运行什么命令,您都需要在sudoers中放置前缀为
sudo
时运行的命令,例如

www-data ALL=NOPASSWD: /usr/bin/whoami
www-data ALL=NOPASSWD: /var/www/script.sh
然后:

exec('sudo/usr/bin/whoami',$output,$return\u var)

从浏览器访问脚本时将成功运行


这是一个离题,但您不应该以Web服务器用户的身份运行任何内容。
www-data
是NGINX/Apache用户。出于安全目的,脚本应在专用的“网站特定”用户下运行。更多信息。

根据@DanilaVershinin提供的解释,我认为递归方法可能有效。我试过了,成功了!这就是:

如果我们的PHP脚本检测到正在通过web服务器调用它,它将在CLI中调用自己:
/var/www/control.php

exec('sudo whoami', $output, $return_var);
var_dump($output, $return_var);
exec('sudo /var/www/script.sh', $output, $return_var);
var_dump($output, $return_var);
if (PHP_SAPI !== "cli") {
    exec('sudo /usr/bin/php /var/www/control.php param1 param2', $output, $return_var);
    echo '<pre>';
    var_dump(PHP_SAPI, $output, $return_var);
    exit();
}

exec('whoami', $output, $return_var);
var_dump(PHP_SAPI, $argv, $output, $return_var);
我们通过去http://localhost/control.php 显示调用用户是root用户,并且我们已收到参数(sudoers行末尾的
*
在我们有参数时仍然匹配。)


这方面的重要问题是安全风险。我将在Github上分享此版本,其中安全风险已得到缓解,并将在此处提供链接。

+1谢谢。我担心会是这样。我可以通过一个小测试来证实这一点:当我将shebang添加到literal.php并使用
chmod+x/var/www/literal.php
使文件可执行时,我通过在终端中使用
sudo/var/www/literal.php
调用它,确实获得了预期的输出。此外,像
sudo/var/www/script.sh
这样的调用可以工作;但是运行
sudobash/var/www/script.sh
时,会提示输入sudo密码。