Разрешить PHP выполнять скрипт bash с правами root

как разрешить скрипту PHP выполнять скрипт bash с правами root?

Предположим, есть PHP-скрипт …

<?php // location: /var/www/script.php exec("bash /var/scripts/test.sh"); // "sudo bash ..." does not work ?> 

и скрипт bash …

 #!/bin/bash # location: /var/scripts/test.sh sudo mkdir /test 

Конечно, PHP и Apache не должны запускаться от имени root, и в лучшем случае только сценарий может выполняться с правами root. Есть идеи?

С наилучшими пожеланиями, Джимбо

Любое решение на базе PHP, которое дает права root в какой-либо точке цепи, опасно: злоумышленник, имеющий доступ к пользователю PHP, может получить доступ к пользователю root, что неприемлемо с точки зрения безопасности.

Я никогда не реализовывал это сам, но я предлагаю то, что я предложил здесь : иметь задание сценария / cron с правами root часто просматривает какое-то место для знака из скрипта PHP, что должно выполняться задание – например, файл с определенным именем или записью в базе данных заданий.

Если этот файл существует, корневой скрипт выполняет свою работу и снова удаляет файл.

Если ваш PHP-скрипт не нуждается в прямом ответе от корневого скрипта, я думаю, что это был бы лучший способ. (Ответ может также быть облегчен корневым скриптом, который, естественно, записывает сообщение о статусе в файл).

Пока вы строго ограничиваете, какие задания PHP могут писать для корневого сценария, это водонепроницаемое решение, так как оно не приводит пользователя root в бизнес PHP.

Если вы не хотите ждать cron, вот простая обертка в C, что вы вызовете из php.

 #include <unistd.h> #include <errno.h> #define WEBUID 500 main( int argc, char ** argv, char ** envp ) { if( getuid() != WEBUID ) exit(1); /* some more security checks */ if( setuid(geteuid()) ) perror( "setuid error" ); envp = 0; /* don't want environment - security problem */ system( "/hardcoded/path/to/script.bash", argv, envp ); } 

Эта скомпилированная обертка должна принадлежать как root, group «www» и должна иметь «s-бит».
chwon root.www wrapper; chmod 4440 wrapper chwon root.www wrapper; chmod 4440 wrapper , поэтому

  • когда выполняется его эффективный UID будет root
  • выполнить его может только группа www (группа веб-сервера)
  • и когда UID вызывающего абонента не является веб-сервером, выйдет

Вам нужно взглянуть на incron (cron для событий файловой системы). Попросите php записать в файл и установить incron для запуска вашего скрипта при закрытии записанного файла (incron очень специфичен). Вероятно, ваш скрипт также будет дезинфицировать входной файл для предотвращения ввода кода и использовать команду lockfile, чтобы предотвратить любые условия гонки между несколькими веб-пользователями.

У меня есть мини-веб-интерфейс, где можно включить анонимный FTP или другие службы в течение 1 часа с паролем. www работает с обычными привилегиями, как и www-data (пользователь php), но incron вызывает сценарий обработки ввода как root.

Майк

Вам может не понадобиться PHP или Apache для запуска от имени root. Если у вас есть контроль над вашим сервером, вы можете использовать модуль Apache, называемый suPHP, и указать пользователя, который вы хотите запустить Apache, как для ваших php-скриптов в конфиге. Вы можете сделать это на сайте по базе сайта, поэтому вам нужно всего лишь запустить suPHP для скриптов в определенном домене. Мне не хватает опыта, чтобы посоветовать вам, как его установить, но у меня была выделенная серверная компания для меня, чтобы я позволил github post-receive hook вызвать сценарий на моем dev-сервере, чтобы вызвать git pull на dev-сервер любой время кто-то подталкивает к репозиториям github. Я не смог заставить его работать каким-либо другим способом, поскольку Apache должен работать как владелец локальных репозиториев для его работы.

Я просто подумал о другом возможном решении, основанном на других комментариях здесь, – вы могли бы написать простой скрипт php, чтобы получить запрос от github hook и записать произвольную информацию в файл в каталоге с 777 правами или дб. Затем выполните задание cron, которое проверяет этот файл или db каждую минуту, чтобы увидеть, изменилось ли оно, и если это так, выпустите запрос git pull напрямую, поскольку cron обычно запускается с правами root. Вы даже можете увидеть, изменилась ли временная метка файла, чтобы определить, нужно ли делать git pull. Вы могли бы использовать ваш cron-скрипт для любого пользователя, которому принадлежит репозиторий, и затем выпустить git pull. Не настоящее решение в реальном времени, но если скрипт cron очень прост, он бы не повредил вашу систему, чтобы называть ее каждую минуту или две. Надеюсь, это поможет.

Используйте демон, выполняемый как root (возможно, написанный на C), который запускает сценарии оболочки для вас. Чтобы запустить выполнение сценария оболочки из сценария PHP, просто используйте IPC (очереди сообщений).

Взгляните сюда, чтобы понять, о чем я говорю: http://php.net/manual/en/function.msg-send.php#114831

Недавно я опубликовал проект, который позволяет PHP получать и взаимодействовать с реальной оболочкой Bash (по запросу root), она решает ограничения exec () и shell_exec (). Получить его здесь: https://github.com/merlinthemagic/MTS

После загрузки вы просто используете следующий код:

 $shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true); $return1 = $shell->exeCmd('/my/bash/script.sh'); //the return will be a string containing the return of the command echo $return1; 

С точки зрения безопасности это намного лучше, чем запуск apache как root. Но позволить PHP где-нибудь рядом с корнем всегда сложно.

Проект, который я построил, обеспечивает корневую оболочку bash одним из двух способов:

1) Вы разрешаете apache право sudo python.

ИЛИ

2) Вы передаете корневые учетные данные объекту каждый раз, когда вам нужна оболочка с корневой установкой.

Выбрать свой яд. 🙂 Прочитайте документацию.