Выполнение команд root через PHP
У меня есть сервер CentOS 5.7 linux и использовать php5.3.x.
в системе pfSense вы можете перезапустить службы, для которых требуются права root, используя веб-страницу php.
Я пытаюсь сделать что-то подобное, я написал некоторый php-код для выполнения команд оболочки. Например, чтобы перезапустить службу sshd:
<?php
exec('/sbin/service sshd restart');
?>
и я попытался выполнить эту команду через функцию exec, но ей нужно разрешение root, но у нас есть полномочия пользователя apache.
I наткнулся на несколько решений:
- " запустите apache с пользователем root" действительно небезопасно. Я не хочу этого делать.
- " apache ALL=NOPASSWD: / sbin / сервис для /etc / sudoers" Я пытался, но все еще есть проблема.
любые другие решения? Спасибо за ответы.
сейчас.. это интересно. я попробовал @ refp post, и он работал на моем локальном сервере ubuntu. Но когда я попробовал то же самое на моем сервере cenOS vps. Это не работает.и это журнал ошибок apache "rm: не удается удалить' /var / lock / subsys/vsftpd': отказано в разрешении"
5 ответов
прочитайте весь этот пост, прежде чем попробовать его, есть выбор, который нужно сделать.
решение с использованием двоичной оболочки (с битом suid)
1) создать скрипт (желательно .sh
), который содержит то, что вы хотите запустить как root.
# cat > php_shell.sh <<CONTENT
#!/bin/sh
/sbin/service sshd restart
CONTENT
2) этот файл должен принадлежать root, и поскольку он будет позже работать с правами root, убедитесь, что только root имеет разрешение на запись в файл.
# chown root php_shell.sh
# chmod u=rwx,go=xr php_shell.sh
3) чтобы запустить скрипт как root независимо от того, какой пользователь его выполняет, нам понадобится двоичная оболочка. Создайте тот, который выполнит наш php_shell.sh
.
# cat > wrapper.c <<CONTENT
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int
main (int argc, char *argv[])
{
setuid (0);
/* WARNING: Only use an absolute path to the script to execute,
* a malicious user might fool the binary and execute
* arbitary commands if not.
* */
system ("/bin/sh /path/to/php_shell.sh");
return 0;
}
CONTENT
4) скомпилируйте и установите правильные разрешения, включая бит suid (говоря ,что он должен работать с привилегиями root):
# gcc wrapper.c -o php_root
# chown root php_root
# chmod u=rwx,go=xr,+s php_root
php_root
теперь будет работать с правами root и выполнять команды, указанные в php_root.sh
.
Если вам не нужна опция, чтобы легко изменить, какие команды будут выполняться, я бы рекомендовал вам написать команды непосредственно в wrapper.c
под шаг 4. Тогда вам не нужно иметь двоичный файл, выполняющий внешний скрипт, выполняющий соответствующие команды.
на wrapper.c
используйте system ("your shell command here");
, чтобы указать, какие команды вы хотели бы выполнить.
Я бы не хотел, чтобы PHP выполнял какие-либо команды sudo. Для меня это звучит как напрашиваться на неприятности. Вместо этого я бы создал две отдельные системы.
первая система в PHP (веб-уровень) будет обрабатывать запросы пользователей. Когда запрос сделан, который нуждается в команде sudo, я бы разместил этот запрос в некоторой очереди. Это может быть какая-то база данных или среднее оборудование, такое как ZeroMQ.
вторая система (бизнес-уровень) будет читать или получать сообщения из этой очереди и будет иметь возможность выполнять команды sudo, но не будет в области вашего процесса веб-сервера.
Я знаю, что это немного расплывчато, и его можно решить по-разному с помощью различных технологий, но я думаю, что это лучший и безопасный способ пойти.
разрешить пользователю www-data запускать для запуска program1 и program2 без пароля:
sudo visudo
добавить в содержимое файла sudoers:
User_Alias WWW_USER = www-data
Cmnd_Alias WWW_COMMANDS = /sbin/program1, /sbin/program2
WWW_USER ALL = (ALL) NOPASSWD: WWW_COMMANDS
сохранить.
от https://askubuntu.com/questions/76920/call-a-shell-script-from-php-run-as-root
недавно я опубликовал проект, который позволяет PHP получать и взаимодействовать с реальной оболочкой Bash, он легко даст вам оболочку, зарегистрированную как root. Затем вы можете просто выполнить отдельные команды bash, а не связывать их в сценарий. Таким образом, вы также можете осуществить возврат. Получить его здесь: https://github.com/merlinthemagic/MTS
после загрузки вы просто используете следующий код:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('service sshd restart');
echo $return1;
//On CentOS 7 output would be like:
//Redirecting to /bin/systemctl restart sshd.service
//On CentOS 6 and lower output would be like:
//Stopping sshd: [ OK ]
//Starting sshd: [ OK ]
решение с использованием двоичной оболочки (с битом suid) Некоторая модификация Филип Roséen - refp пост.
для выполнения любой команды изменена оболочка.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main (int argc, char **argv)
{
setuid (0);
char cmd[100] = "";
int i;
char *p;
for(i=0; i < argc; i++) {
if(i != 0){
strcat(cmd, *(argv+i));
strcat(cmd, " ");
}
}
system (cmd);
return 0;
}
скомпилировать и установить соответствующие разрешения;
gcc wrapper.c -o php_root # php_root can be any name.
chown root php_root
chmod u=rwx,go=xr,+s php_root
Теперь звоните из PHP. Выполнить любую команду.
shell_exec('./php_root '.$cmd);//execute from wrapper