Как запустить PHP exec() от имени пользователя root?
Я пытаюсь построить менеджер брандмауэра в PHP, но когда я выполняю, <?php exec('iptables -L'); ?>
, массив результатов пуст.
Я пытался, <?php echo exec('whoami'); ?>
и ответ www-data
(пользователь, который использует Apache). Что я могу сделать, чтобы выполнить функцию exec от имени пользователя root? (Желательно без изменения пользователя Apache.)
9 ответов
Не делай этого! Вы будете широко открыты для всевозможных злонамеренных хакерских атак.
Посмотрите на документацию "sudo".
Вы должны быть в состоянии настроить все необходимые вам команды в качестве сценариев "sudo". Гораздо лучше писать конкретные сценарии с ограниченными функциями, чем выставлять основную привилегированную команду.
Как в:
exec ('sudo getIpTables.ksh')
Я знаю, что это старый вопрос
добавьте пользователя php, запущенного в группу sudo, если он еще не назначен
используйте sudo -S, чтобы вы могли передать пароль через echo
$exec = "echo your_passwd | /usr/bin/sudo -S your command";
exec($exec,$out,$rcode);
если у вас проблемы с путями - используйте
"bash -lc 'echo your_passwd | /usr/bin/sudo -S your command'"
так что вы получите новый bash, который действует как оболочка входа в систему и имеет установленные пути
проверьте страницы руководства sudo
Вы можете запустить sudo через phpseclib, чистую реализацию PHP SSH:
<?php
include('Net/SSH2.php');
$ssh = new Net_SSH2('www.domain.tld');
$ssh->login('username', 'password');
$ssh->read('[prompt]');
$ssh->write("sudo command\n");
$ssh->read('Password:');
$ssh->write("Password\n");
echo $ssh->read('[prompt]');
?>
Вы можете поместить необходимые команды в отдельный скрипт / исполняемый файл (sh, PHP, настоящий исполняемый файл, не имеет значения), изменить его владельца на root и применить к нему "setuid".
Это позволит всем и каждому запускать этот сценарий от имени пользователя root, поэтому вам нужно убедиться, что он имеет свои собственные правила безопасности, чтобы узнать, разрешено ли это, и очень ограничен в том, что он делает.
Если вы не используете suphp и не настроите его для запуска с правами root, вы не сможете запускать любой скрипт PHP от имени любого другого пользователя системы, кроме того, кто запускает PHP.
Редактировать:
Просто маленькая идея. Как-нибудь добавить процесс очереди и запустить процесс cron в crontab корня.
Пожалуйста, будьте очень осторожны с этим. Любая инъекция может буквально разрушить систему.
Это очень небезопасно и плохая идея. Переосмыслите свой дизайн. Если вы действительно хотите сделать это, используйте sudo, как советовали. Альтернативное решение может состоять в том, чтобы идти вперед и работать от имени пользователя root, но делать это внутри chroot или образа vm (оба из которых могут быть разбиты, но все же).
Или лучше всего запустить sudo внутри chroot!
Недавно я опубликовал проект, который позволяет PHP получать и взаимодействовать с реальной оболочкой Bash. Получите это здесь: https://github.com/merlinthemagic/MTS
После загрузки вы просто используете следующий код:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('iptables -L');
//the return will be a string containing the return of the command
echo $return1;
Вам не нужно запускать root!
Я знаю, что это старый пост, но его много ищут, поэтому, пожалуйста, посмотрите мой ответ ниже, который не требует, чтобы вы давали права root для www-data.
Потерпите меня, но это работает (проверено на сервере Ubuntu 20.04 LTS, август 2021 г.)
Начнем:
Создайте текстовые файлы «sudocmds.txt» и «results.txt» вне корневого веб-пути, т.е.
Если ваш корневой каталог / var / www / html /, поместите свои текстовые файлы в / var / www / cmds /
Установите права доступа к файлам на www-data:
sudo chown www-data /var/www/cmds/sudocmds.txt
sudo chown www-data /var/www/cmds/results.txt
Я воспользуюсь вашим примером, чтобы показать "iptables -L" нажатием кнопки:
Создайте форму:
<form method="post">
<input type="hidden" name="cmd"> <br>
<input type="submit" name="cmd" value="CMD";">
</form>
Используйте код PHP, чтобы записать «1» в файл sudocmds.txt при нажатии кнопки CMD:
<?php
if(isset($_POST['cmd']))
{
$data=$_POST['cmd'];
file_put_contents("../cmds/sudocmds.txt", "1");
sleep(1);
echo nl2br( file_get_contents('../cmds/results.txt') );
}
?>
Теперь создайте службу для запуска на вашем хосте, которая будет отслеживать файл и искать его, а затем выполнять команду.
Для этого я буду использовать в качестве примера inotify-tools:
sudo apt install inotify-tools -y
Создайте скрипт:
sudo nano /opt/cmd-watcher.sh
#!/bin/bash
inotifywait -mqr -e close_write "/var/www/cmds/sudocmds.txt" | while read line
do
if grep -q 1 "/var/www/cmds/sudocmds.txt"; then
sudo iptables -L > /var/www/cmds/results.txt
fi
done
Сделайте скрипт исполняемым
sudo chmod +x /opt/cmd-watcher.sh
Запускаем скрипт в фоновом режиме
sudo sh /opt/cmd-watcher.sh &
Теперь перейдите на свою веб-страницу, обновите ее и нажмите кнопку, вы увидите, что результаты команды появятся через 1 секунду :)
Надеюсь, это поможет любому, кто ищет что-то подобное, если да, пожалуйста, проголосуйте за, спасибо.
Я знаю, что это немного сложный процесс, но это означает, что вы не должны подвергаться риску безопасности, выполняя команды от имени пользователя root с www-данными.
Просто предположение - это веб-приложение PHP, которое будет делать это? Это звучит не слишком безопасно. Приложение, которому нужен root - не могли бы вы создать его отдельно, а затем вызвать его из PHP? Если нет, может быть, вы можете sudo процесс, чтобы он мог запускаться как root.