Мне действительно нужно закрыть ubuntu с помощью PHP exec. Но у меня, вероятно, есть некоторые проблемы с разрешением.
echo exec('whoami')
вернуть «никто»;
Поэтому я поставил консоль
adduser nobody admin
и попробовал
exec("shutdown -h now");
Но это не работает;
Предоставление пользователю PHP работает с правами root очень опасно . Это не очень хорошая идея, потому что вы открываете весь свой сервер, если уязвимость в скрипте PHP будет использована. На производственном сервере это абсолютно неприемлемо.
Единственный способ сделать это безопасно, что я знаю о том, что у меня задание cron запускает скрипт оболочки как root каждый час или около того. Скрипт оболочки проверяет наличие файла, такого как shutdown_now.txt
. Если файл существует, скрипт запускает процедуру завершения работы. Сценарий PHP создает файл завершения, если это указано.
Я недостаточно разбираюсь в сценариях оболочки, чтобы привести пример, но я уверен, что кто-то может при необходимости.
На самом деле Пекка дал вам хороший совет. В вашем 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
Этот ответ только иллюстративен. На самом деле не делайте этого.
/sbin/shutdown
(с правами root) в место, где пользователь PHP может получить к нему доступ. chmod 4755 /copy/of/shutdown
Когда PHP выполнит копию завершения работы, shutdown
будет выполняться с привилегиями root. Это устраняет задание cron и возможность того, что устаревший «shutdown_now.txt» заставит систему снова прекратиться вскоре после включения питания.
Опять же, опциональное использование бита setuid опасно . Каждый раз, когда вы его используете, тщательно подумайте о том, что программа могла бы сделать, если бы злоупотребляла. В этом случае дыра в вашем приложении может заставить злоумышленника удаленно остановить систему. Но злоумышленник мог это сделать независимо от того, какой метод вы используете, чтобы поговорить с shutdown
. Это зависит от вас, если это приемлемый риск.
Кроме того, если вы собираетесь это сделать, не запускайте PHP как анонимного пользователя системы, вы действительно хотите suexec. Просто убедитесь , что вы не можете передать ничего произвольного команде, которую вы отправляете. Не позволяйте кому-либо получить && do_evil_deed
в конце или начале его.
Более безопасный способ сделать это будет через использование любого из доступных SSH-классов для PHP, подключающихся как пользователь, заключенный в тюрьму в chroot, с правами sudo только для программы выключения. Или, в принципе, в любое время, когда PHP должен что-то делать с ОС, представьте себе наименьшую поверхность, о которой вы можете думать, чтобы сделать это, а затем попытайтесь сделать ее еще меньше.
Попробуйте запустить exec как это
exec( 'shutdown -h now', $output, $return_val ); print_r( $output ); echo "\n"; echo 'Error: '. $return_val ."\n";
И посмотрите на ошибки, я просто попробовал запустить php-скрипт с пользователем root, и он работал на моей машине.
Если это не сработает, подумайте о том, что cronjob работает под привилегиями root, который периодически проверяет, должен ли он запускать shutdown на macine.
Как насчет предоставления пользователю, который запускает apache, разрешение на запуск shutdown с правами sudo?
Откройте файл sudoers с помощью
sudo visudo
Добавить строку
www-data ALL=NOPASSWD:/sbin/shutdown
( www-data должен быть пользователем, который запускает apache. Вы можете проверить это с помощью ps aux | egrep '(apache|httpd)'
и предположить, что двоичный файл shutdown находится в / sbin )
Сохранить с помощью ctrl-O
Теперь это должно работать в php:
system("sudo shutdown 0");