4

在 xubuntu 机器上,我有以下脚本让 PHP 创建我的用户拥有的目录:

<?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,输出是NULL NULLvar 转储,并且没有创建目录。我究竟做错了什么?

4

1 回答 1

1

你的设置有点混乱。

当您从浏览器访问此脚本时,apache 使用 www-data 用户启动它。

Sudo 没有被执行。你不能让 apache 通过 sudo 调用你的脚本。您必须将敏感脚本包装到 sudo 调用中。

例如这种方式:

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

第一个.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);
?>

第二个.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)。并手动运行脚本。

一些旁注:

  • 检查错误日志可能会很有用。(尾 /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()。

于 2014-12-18T09:04:34.783 回答