Как выключить Ubuntu с помощью exec PHP - PullRequest
0 голосов
/ 08 марта 2011

Мне действительно нужно завершить работу Ubuntu с помощью PHP exec. Но у меня, вероятно, есть некоторые проблемы с разрешением.

echo exec('whoami')

вернуть 'никто';

Поэтому я положил в консоль

adduser nobody admin

и попробовал

exec("shutdown -h now");

Но это не работает; (

Ответы [ 5 ]

10 голосов
/ 08 марта 2011

Предоставление пользователю PHP запускается с правами root очень опасно .Это не очень хорошая идея, потому что вы открываете весь свой сервер, если эксплуатируется уязвимость в PHP-скрипте.На производственном сервере это абсолютно неприемлемо.

Единственный известный мне безопасный способ сделать это - задание cron запускать скрипт оболочки от имени пользователя root каждую минуту или около того.Сценарий оболочки проверяет наличие файла типа shutdown_now.txt.Если файл существует, скрипт запускает процедуру завершения работы.Сценарий PHP создает файл завершения работы, если так указано.

Я недостаточно хорошо разбираюсь в сценариях оболочки, чтобы предоставить пример, но я уверен, что кто-то может, если это необходимо.

9 голосов
/ 08 марта 2011

На самом деле Пекка дал тебе хороший совет. В вашем php файле создайте файл, который будет принудительно перезагружаться, что-то простое, как

  $file = fopen('.reboot-server',"w");
  fwrite($file, 'reboot');
  close($file);

Создайте bash-скрипт, который будет проверять этот файл

#!/bin/bash
if [ -f /var/www/html/.reboot-server ]; then
  rm -f /var/www/html/.reboot-server
if [ -f /var/www/html/.reboot-server ]; then
   echo "Can't remove file .reboot-server"
else
  /sbin/shutdown -r now
fi
fi

И добавить его под cronjob

*/1 * * * * root /home/scripts/reboot.sh
3 голосов
/ 19 августа 2017

Как насчет предоставления пользователю, который запускает apache, разрешения на завершение работы с правами sudo?

Откройте файл sudoers с помощью

sudo visudo

Добавить строку

www-data ALL=NOPASSWD:/sbin/shutdown

( www-data должен быть пользователь, который запускает apache. Вы можете проверить это с помощью ps aux | egrep '(apache|httpd)' и предполагая, что бинарный файл отключения находится в / sbin )

Сохранить с помощью Ctrl-O

Теперь это должно работать в php:

system("sudo shutdown 0");
3 голосов
/ 08 марта 2011

Этот ответ является иллюстративным только . не на самом деле сделать это.

  • Сделайте копию /sbin/shutdown (от имени root) в место, где пользователь PHP может получить к нему доступ.
  • Установите бит SUID копии, чтобы она могла запускаться от имени пользователя root. chmod 4755 /copy/of/shutdown

Когда PHP выполняет копию завершения работы, shutdown будет работать с привилегиями root. Это исключает задачу cron и возможность того, что устаревший файл shutdown_now.txt заставит систему снова остановиться вскоре после включения питания.

Опять же, массовое использование бита setuid опасно 1019 *. Каждый раз, когда вы используете его, подумайте тщательно о том, что программа может сделать, если злоупотреблять. В этом случае дыра в вашем приложении может привести к удаленному останову системы злоумышленником. Но злоумышленник может сделать это независимо от того, каким методом вы разговариваете с shutdown. Это зависит от вас, если это приемлемый риск.

Кроме того, если вы собираетесь это сделать, не запускайте PHP как анонимный системный пользователь, вам действительно нужен suexec. Просто сделайте уверенным нет способа передать что-либо произвольное команде, которую вы отправляете. Не позволяйте кому-либо получить && do_evil_deed в конце или в начале.

A намного Более безопасный способ сделать это - использовать любой из доступных SSH-классов для PHP, подключившись как пользователь, заключенный в chroot, с правами sudo только к программе выключения. Или, в принципе, любое раз, когда PHP нужно что-то делать с ОС, представьте наименьшую поверхность, которую вы можете себе представить, чтобы сделать это, а затем попытайтесь сделать ее еще меньше.

0 голосов
/ 08 марта 2011

Попробуйте запустить exec следующим образом

exec( 'shutdown -h now', $output, $return_val );

print_r( $output );
echo "\n";
echo 'Error: '. $return_val ."\n";

И посмотрите на ошибки, я просто попытался запустить скрипт php с пользователем root, и он работал на моей машине.

Если это такне работает, подумайте о том, чтобы cronjob работал с правами root, который периодически проверяет, должно ли оно запускаться на компьютере Macin.

...