脚本添加到sudoers.d不作为根执行

在一个xubuntu框中,我有下面的脚本来让我的用户拥有PHP创build目录:

<?php if(!isset($_REQUEST['path'])) die('No path specified'); $path = $_REQUEST['path']; $res1 = shell_exec("sudo mkdir -p $path"); $res2 = shell_exec("sudo chown -R majid:majid $path"); var_dump($res1, $res2); ?> 

该脚本位于/var/www/path/to/mkdir.php

我还将这个文件添加到/etc/sudoers.d/grantmkdir ,内容如下:

 www-data ALL=(ALL:ALL) NOPASSWD: /var/www/path/to/mkdir.php 

我有chmod编辑文件到0440以及。 从浏览器访问mkdir.php,var dumps的输出是NULL NULL ,没有创build目录。 我究竟做错了什么?

你的设置有点困惑。

当你从浏览器访问这个脚本时,apache用www-data用户启动它。

Sudo没有执行。 你不能让apache通过sudo来调用你的脚本。 你必须把你的敏感脚本包装成一个sudo电话。

例如这样:

创建两个脚本。 第一个将由apache调用,第二个将由第一个通过sudo调用。

first.php:

 <?php if(!isset($_REQUEST['path'])) die('No path specified'); $path = $_REQUEST['path']; // By the way here you should verify the path! Otherwise malicious users can make your system execute whatever they want... shell_exec("sudo /var/www/path/to/second.php " . $path); ?> 

second.php

 #!/usr/bin/php <?php shell_exec("sudo mkdir -p " . $argv[1]); shell_exec("sudo chown -R majid:majid " . $argv[1]); ?> 

并通过sudo使second.php可执行:

/etc/sudoers.d/second

 www-data ALL=(ALL:ALL) NOPASSWD: /var/www/path/to/second.php 

这样apache将启动first.php,它将使用sudo启动second.php。

您可以测试sudo设置是否正常工作,并登录到服务器,切换到www-data(su www-data)。 并手动运行脚本。

一些附注:

  • 检查错误日志可能是有用的。 (tail / var / log / apache / error_log或者stg类似)
  • 不要忘记验证你的输入,否则你的系统将变得脆弱。 这个问题的详细信息和解决方案: http : //php.net/escapeshellarg
  • NULL NULL可以是正常的。 详细信息: http : //php.net/shell_exec

注意:

 This function can return NULL both when an error occurs or the program produces no output. It is not possible to detect execution 

使用此功能失败。 当需要访问程序退出代码时,应使用exec()。