Скрипт, добавленный в sudoers.d, не выполняется от имени пользователя root
На коробке 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 NULL
для вар дампов и никакой каталог не создается. Что я делаю неправильно?
1 ответ
Ваша настройка немного запуталась.
Когда вы получаете доступ к этому скрипту из вашего браузера, apache запускает его с пользователем www-data.
Судо не выполняется. Вы не можете заставить 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]);
?>
И сделать second.php исполняемым через sudo:
/etc/sudoers.d/second
www-data ALL=(ALL:ALL) NOPASSWD: /var/www/path/to/second.php
Таким образом, apache запустит first.php, который запустит second.php с помощью sudo.
Вы можете проверить, хорошо ли работают настройки 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() следует использовать, когда требуется доступ к коду завершения программы.