Запустить команду оболочки как другой пользователь, вызванный PHP
У меня есть PHP-скрипт, который вызывается по HTTP, а не как скрипт командной строки. Этот сценарий должен вызывать команду оболочки как другой пользователь, а не текущий пользователь www-data веб-сервера.
Пример:
<?php
echo shell_exec('sudo -u myusername -S /usr/bin/whoami'); // returns nothing :(
echo shell_exec('whoami'); // returns www-data
При вызове этой 2 команды sudo -u myusername -S /usr/bin/whoami
а также whoami
непосредственно в командной строке они возвращаются
myusername
www-data
Также нет результата по этому вопросу:
<?php
echo shell_exec('echo "mypass" | sudo -u myusername -S /usr/bin/whoami');
Мне кажется, что sudo вообще не работает вместе с PHP shell_exec().
3 ответа
Во-первых, я не понимаю команду sudo, которую вы запускаете. sudo -u username
Предполагается, что вы, как пользователь один, можете выполнить команду sudo как пользователь два, сказав (как пользователь один, в этом примере, выполнить команду ls):
sudo -u usertwo ls
Я прошу прощения, если вы пытались дезинфицировать ваши команды выше, подставив username
для реального имени пользователя, но я не могу быть уверен, что вы сделали, поэтому мне нужно сначала поднять этот вопрос.
Во-вторых, необходимо настроить sudo, чтобы пользователь мог выполнять ряд команд как другой пользователь. Давайте начнем с того, что позволим www-данным использовать команду ls как пользователь fribble; Вы можете проверить это, поставив
www-data ALL = (fribble) NOPASSWD: ls
в вашем файле sudoers (подставляя реального пользователя как fribble). Затем попробуйте сделать, скажем, ls -la /tmp
изнутри вашего скрипта PHP и посмотреть, если вы получите список каталогов.
Я согласен с Джеймсом Лоури в том, что не стоит разрешать пользователю www-данных без разрешения вводить произвольные команды, как произвольные пользователи, но если вы поясните, какие команды вы пытаетесь заставить запустить www-данные, это может быть разумный способ сделать это.
Редактировать:
вы пробовали с помощью ls в файле sudoers и sudo -u user2 ls -al /tmp
в сценарии PHP, и вы получите список каталогов, который настоятельно рекомендует, чтобы sudo прекрасно работал с PHP.
Конечно, вы могли бы позволить /bin/touch
в файле sudoers поместите sudo -u user2 touch /tmp/TESTFILE
в сценарии PHP, а затем выполнить это? Если файл /tmp/TESTFILE
По-видимому, принадлежит user2, мы можем быть уверены, что sudo и PHP отлично работают вместе.
Я должен признаться, что если бы я знал, что вы пытались сделать sudo java, я бы никогда не ответил на исходный вопрос, потому что я думаю, что java - это гигантский непредсказуемый мешок с дерьмом, который ведет себя как полноценный ребенок, если не получает окружающей среды это требует (и sudo довольно строго дезинфицирует окружающую среду). Но, по крайней мере, приведенный выше тест должен помочь вам быть уверенным, что, какова бы ни была проблема, это не проблема с PHP и sudo, которые не очень хорошо играют вместе.
Не разрешайте пользователю sudo доступ к веб-серверу, вы просто напрашиваетесь на неприятности. Взгляните на бит setuid:chmod u+s some_file_that_needs_executing_as_another_user.pl
Каждый раз, когда этот файл выполняется, он будет эффективно выполняться пользователем, который его создал.
Кстати, я почти уверен, что вы не можете передать пароль в sudo или passwd.
Если вы хотите дать специальные разрешения процессу веб-сервера, работающему как пользователь www-data, вы можете сделать одно из следующих действий:
1- Добавьте данные www в файл sudoers, чтобы он мог выполнить требуемую команду / скрипт без запроса пароля.
2- Включите модуль Apache suexec. Это позволяет вам сменить пользователя с www-data на другого привилегированного пользователя для каждого виртуального хоста. Таким образом, вам не нужно менять пользователя для всего сервера.