Запустите корневой скрипт от пользователя www-data

Вопрос или проблема

У меня проблема с выполнением команды, которая требует привилегий root через PHP на сервере Apache

  1. Я добавил команду в sudoers, чтобы она не требовала пароля для пользователя

visudo:

#
# Этот файл ДОЛЖЕН редактироваться с помощью команды 'visudo' от имени root.
#
# Пожалуйста, рассмотрите возможность добавления локального содержимого в /etc/sudoers.d/ вместо
# прямого изменения этого файла.
#
# Смотрите страницу man для получения подробной информации о том, как написать файл sudoers.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Спецификация псевдонима хоста

# Спецификация псевдонима пользователя
# Спецификация псевдонима команды

# Спецификация привилегий пользователя
root ALL = (ALL: ALL) ALL

# Позволить членам группы sudo выполнять любую команду
%sudo ALL = (ALL: ALL) ALL

# Смотрите sudoers (5) для получения дополнительной информации о директивах "#include":

#includedir /etc/sudoers.d

www-data ALL = NOPASSWD: /sbin/iw
  1. PHP скрипт, который я пытаюсь выполнить, я также проверяю ошибку, которая возвращается
<? php
echo '<pre>';
$last_line = system('sudo /sbin/iw wlan0 scan 2>&1', $retval);
// Печать дополнительной информации
echo '
</pre>
<hr /> Последняя строка вывода: '. $last_line. '
<hr /> Возвратное значение: '. $retval;
?>

PHP скрипт возвращает

sh: 1: sudo: not found

Последняя строка вывода: sh: 1: sudo: not found Возвратное значение: 127

sudо установлен и работает нормально, когда я выполняю его от другого пользователя

whoami возвращает “www-data”, так что пользователь в порядке

www-data принадлежит к

группе sudo

groups www-data
www-data: www-data sudo

Во-первых, эта строка совершенно неправильная:

www-data ALL = NOPASSWD: /sbin/iw

Если бы вы использовали visudo для редактирования файла sudoers, вы бы получили предупреждение вроде этого (для номера строки XXX):

>>> /etc/sudoers: syntax error near line XXX <<<

Это говорит вам о том, что синтаксис неправильный. На самом деле, должно быть так:

www-data ALL = NOPASSWD: /sbin/iw

Однако, отклоняя синтаксис, идея иметь веб-приложение с полным и неограниченным доступом к iw не кажется хорошей. Обычно подход заключается в том, чтобы написать вспомогательный скрипт, который выполняет одно или два действия, ожидаемых от вызывающего, и ничего больше. Например, если вас интересует только сканирование, не позволяйте скрипту делать что-либо, кроме сканирования. Учетной записи www-data будут предоставлены права root на этот скрипт, а не на iw, чтобы даже если кто-то сумеет пробиться через ваше веб-приложение, они могли бы делать только то, что может делать веб-сервер.

Во-вторых, эта строка также неправильная:

last_line = system('sudo /sbin/iw wlan0 scan 2>&1', $retval);

Я не уверен, почему вы считаете, что /sbin/iw — это содержательная команда, и выполнение этого вызывает ошибку:

sudo /sbin/iw wlan0 scan 2>&1
-bash: syntax error near unexpected token `&'

Используйте правильный синтаксис:

sudo /sbin/iw wlan0 scan 2>&1

В-третьих, вы не говорите, на каком хосте это выполняется, но ваша учетная запись www-data может не иметь прав доступа к /usr/bin/sudo. Это сложнее диагностировать без дополнительной информации.

Ответ или решение

Для успешного выполнения скрипта PHP, который требует повышения привилегий до уровня root, необходимо внимательно рассмотреть несколько аспектов работы с sudo, а также настройки конфигурации вашего сервера и скрипта. Давайте рассмотрим ключевые шаги для решения вашей проблемы.

1. Правильная настройка sudoers

Сначала исправим ошибку в конфигурации файла sudoers. Ваша текущая запись:

www-data ALL = NOPASSWD: / sbin / iw

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

www-data ALL = NOPASSWD: /sbin/iw

Кроме того, важно учитывать, что предоставление команде iw прав root без ограничения — это потенциально уязвимо. Вместо этого рекомендуется создать вспомогательный скрипт, который будет выполнять только те команды, которые действительно нужны, оставляя место для контроля.

2. Создание вспомогательного скрипта

Рассмотрим создание скрипта, который будет выполнять специфические команды. Создайте файл /usr/local/bin/iwscan.sh и предоставьте необходимые права:

sudo touch /usr/local/bin/iwscan.sh
sudo chmod 755 /usr/local/bin/iwscan.sh

Отредактируйте скрипт:

#!/bin/bash
/sbin/iw wlan0 scan

Теперь внесите изменения в sudoers, чтобы предоставить доступ только к этому скрипту:

www-data ALL = NOPASSWD: /usr/local/bin/iwscan.sh

3. Обновление PHP скрипта

Теперь нужно изменить ваш PHP-скрипт, чтобы он вызывал этот вспомогательный скрипт. Вот как будет выглядеть обновленный код:

<?php
echo '<pre>';
$last_line = system('sudo /usr/local/bin/iwscan.sh 2>&1', $retval);
// Печать дополнительной информации
echo '</pre><hr />Последняя строка вывода: ' . $last_line . '<hr />Возвращаемое значение: ' . $retval;
?>

4. Проверка прав доступа

Также убедитесь, что пользователь www-data действительно имеет доступ к sudo и к командному интерпретатору. Проверьте это, выполнив:

sudo -l -U www-data

Это должно показать вам, что www-data может выполнять /usr/local/bin/iwscan.sh без ввода пароля.

5. Другие причины ошибок

Если все вышеперечисленное правильно настроено, а ошибка sh: 1: sudo: not found все равно возникает, возможно, существует ошибка в пути sudo. Обычно sudo находится в /usr/bin/sudo. Убедитесь, что этот путь доступен для пользователя www-data, выполняя:

which sudo

Заключение

Следуя вышеперечисленным шагам, вы сможете запустить iw с правами root через PHP, одновременно соблюдая меры безопасности. Лучше всего ограничить сеть привилегий только тем действиям, которые необходимы, и избегать запуска опасных команд от веб-пользователей. Убедитесь, что тестируете все изменения на вашем сервере, чтобы выявить и исправить любые дополнительные проблемы.

Оцените материал
Добавить комментарий

Капча загружается...