Перемонтируйте root файловую систему через PHP, и apache2 не работает перед выполнением монтирования через оболочку - PullRequest
0 голосов
/ 27 марта 2020

Я создал систему только для чтения на Raspberry Pi с Debian Buster для встроенного приложения. На нем работает сервер apache2 с веб-страницей конфигурации для нужного мне приложения. Мне нужно перемонтировать файловую систему в режиме чтения-записи для редактирования системного файла, и я добавил кнопку на панели инструментов на странице php, которая вызывает функцию оболочки.

Это код для конкретной кнопки:

<p><label>Remount Read-Write</label>
<button type="submit" name="rw">Remount</button>
</p>
<p><label>Remount Read-Only</label>
<button type="submit" name="ro">Remount</button>
</p>
<?php
    if(isset($_POST['rw'])){
        $cmd='sudo /home/pi/mount.sh --rw';
        shell_exec($cmd);
    }
    else if(isset($_POST['ro'])){
        $cmd='sudo /home/pi/mount.sh --ro';
        shell_exec($cmd);
    }
?>

Внутри сценария оболочки есть строка кода для монтирования пути root в режиме rw с опцией '--rw', в частности команда:

/bin/mount -o remount,rw /

и то же самое с '--ro', но с опцией ro.

Я также добавил файл suoders в /etc/sudoers.d со следующей строкой:

www-data ALL=(ALL) NOPASSWD: /home/pi/mount.sh

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

p@localhost# sudo mount -o remount,rw /

php shell_exe c начинает работать, и я могу смонтировать и перемонтировать на странице php.

Я не могу понять, почему страница php начинает работать только после того, как я выполню перемонтирование через оболочку.

Edit

Этот сценарий называется:

#!/bin/bash
# Remount filesystem
# Options:
#           --rw:       remount read-write filesystem
#           --ro:       remount read-only filesystem

if [ "$#" == 1 ]; then
  if [ $1 == "--rw" ]; then
    sudo /bin/mount -o remount,rw /
    echo -e "Filesystem remounted in read-write mode"
  elif [ $1 == "--ro" ]; then
    sudo /bin/mount -o remount,ro /
    echo -e "Filesystem remounted in read-only mode"
  elif [ $1 == "--help" ] || [ $1 == "-h" ]; then
    echo -e "Remount Filesystem tool"
    echo "use remount.sh [OPTION]"
    echo ""
    echo -e "--rw         \tremount read-write filesystem"
    echo -e "--ro         \tremount read-only Filesystem"
    echo -e "--help (-h)  \tprint help"
  else
    echo "use -h or --help to see options"
  fi
else
    echo "use -h or --help to see options"
fi

решено

Я нашел решение проблемы.

Основная проблема была связана с опцией systemcl в apache2.service. По умолчанию у сервиса есть опция PrivateTemp=true. Изменение в PrivateTemp=false решило проблему.

Как я понял, PrivateTemp имеет значение true для создания пространства имен файловой системы, которое не используется совместно. По умолчанию apache2 создает отдельное пространство имен для доступа к безопасности временных файлов.

Вот пара ссылок, на которые я посмотрел для решения проблемы:

(U) Монтирование через "exe" c "с" sudo ". Пользователь "sudoer" с NOPASSWD

https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateTmp =

1 Ответ

0 голосов
/ 28 марта 2020

Произошла ошибка в присвоении вашего кода PHP выше. Назначения в PHP не такие, как в BASH.

Заменить cmd= на $cmd= в двух местах.

Если вы этого не сделаете, вы передадите пустой строке функцию shell_exec.

Так что попробуйте:

<p><label>Remount Read-Write</label>
<button type="submit" name="rw">Remount</button>
</p>
<p><label>Remount Read-Only</label>
<button type="submit" name="ro">Remount</button>
</p>
<?php
    if(isset($_POST['rw'])){
        $cmd='sudo /home/pi/mount.sh --rw';
        shell_exec($cmd);
    }
    else if(isset($_POST['ro'])){
        $cmd='sudo /home/pi/mount.sh --ro';
        shell_exec($cmd);
    }
?>
...