【问题标题】:Remount root file-system via PHP and apache2 doesn't work before execute mount via shell在通过 shell 执行挂载之前,通过 PHP 重新挂载根文件系统和 apache2 不起作用
【发布时间】:2020-07-08 03:02:57
【问题描述】:

我使用 Debian Buster 在 Raspberry Pi 上为嵌入式应用程序创建了一个只读系统。 apache2 服务器正在其上运行,并带有我需要的应用程序的配置网页。 我需要以读写模式重新挂载文件系统以编辑系统文件,并在调用 shell 函数的 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);
    }
?>

在 shell 脚本中,有一行代码用于在 rw 模式下使用选项“--rw”挂载根路径, 特别是命令是:

/bin/mount -o remount,rw /

与 '--ro' 相同,但使用 ro 选项。

我还在 /etc/sudoers.d 中添加了一个 suoders 文件,其中包含以下行:

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

问题是命令执行没有错误,但文件系统没有重新挂载。 如果我像这样通过 shell 执行命令:

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

php shell_exec 开始工作,我可以通过 php 页面挂载和重新挂载。

我不明白为什么 php 页面只有在我通过 shell 重新挂载后才开始工作。

编辑

这是被调用的脚本:

#!/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

已解决

我找到了问题的解决方案。

主要问题是由于 apache2.service 上的 systemcl 选项。 默认情况下,该服务具有PrivateTemp=true 选项。 改在PrivateTemp=false 解决了这个问题。

据我了解,PrivateTemp 设置为 true 用于创建不共享的文件系统命名空间。默认情况下,apache2 为临时文件的安全访问创建一个单独的命名空间。

我查看了几个链接来解决这个问题:

(U)Mounting through "exec" with "sudo". The user is a "sudoer" with NOPASSWD

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

【问题讨论】:

  • 请查看stackoverflow.com/questions/8532304/…,看看这是否能解决您的问题。
  • 我尝试了包装器,但结果相同。在我使用 shell 手动重新挂载之前,通过网页执行不会重新挂载。之后,php 上的按钮开始工作并通过包装器重新挂载文件系统。
  • 您能否编辑您的问题以显示用于重新挂载根文件系统的 shell 脚本的相关行?
  • 我用我通过 PHP 调用的整个 bash 脚本编辑了这篇文章

标签: php apache2 mount


【解决方案1】:

上面的 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);
    }
?>

【讨论】:

  • 对不起,在我的代码中,$cmd 一切正常。我在这里输入评论时出错了。 php 页面执行时没有错误,只有在我在 shell # sudo mount -o remount,rw / Than 按钮开始执行重新安装后,才能通过按钮重新安装。好像有什么东西是通过shell命令触发的,但我不知道。
  • 你知道你需要多久用shell再次触发这个行为吗?每次重启后?
  • 每次重启后只有一次,皮埃尔。
  • 有没有可能apache2运行在chroot隔离的环境中?会不会是从外壳重新安装系统会消除这种保护?我很困惑……
  • 感谢您最后的评论,皮埃尔,我解决了这个问题。 apache2 没有在 chrootted 环境中运行,但是这个输入帮助我找到了解决方案。这是 systemctl 问题,apache2 服务创建新的非共享文件系统命名空间。我在原始帖子上写了解决方案。谢谢你的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 2015-03-12
  • 2014-06-21
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
相关资源
最近更新 更多