Как запустить 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.

Другие вопросы по тегам