0

我已经看过这两个:

但是,我的问题似乎有所不同。


我已经构建了一个用于调用 Linux CLI 工具的扩展库。它是围绕proc_open,它是家庭和POSIX

我正在使用它成功执行所有(直到我遇到这个mount/umount错误)CLI 工具。

现在,我正在构建一个 RAID 设置例程,其中涉及partprobe, parted-rm , mklabel , mkpart , -stop , zero - superblock , create ,和最终/ 。mdadmddmkfsmountumount

实际上有两种优雅的例程,一种用于组装RAID,另一种用于拆卸。

正如标题所说,问题在于mountumount。上面列出的其他工具及其命令成功执行。

环境

Arch Linux - Linux stone 3.11.6-1-ARCH #1 SMP PREEMPT Fri Oct 18 23:22:36 CEST 2013 x86_64 GNU/Linux.

拱门正在运行systemd- 可能是以某种方式影响安装。

运行 mod_php(最新)的 Apache Web 服务器(最新)。Apache 以http:http.

httpwheel组中,并且wheels是 sudoers - %wheel ALL=(ALL) NOPASSWD: ALL
请不要开始讨论webserver完整的根功能- 该单元是 NAS,它运行自定义 WebOS,并且仅用于 Intranet。即使有黑客攻击 - 这些很可能会破坏整个系统,这对客户来说是不健康的。NAS 是Mobotix IP 摄像机的存储,它运行大量相关服务,并且这些单元已经部署在 30 多个对象中,没有任何问题。简而言之,webserver它不是服务于网络,而是服务于操作系统。

在写作之前,为了快速测试,我http明确地向 sudoers 添加了 - http ALL=(ALL) NOPASSWD: ALL- 没有用。

问题

在 RAID 组装过程中运行的最后一个命令是mount /dev/md/stone\:supershare /mnt/supershare,它返回退出代码为0.

执行后续挂载会导致:

mount: /dev/md127 is already mounted or /mnt/supershare busy
/dev/md127 is already mounted on /mnt/supershare

退出代码为32. 因此,阵列安装在某处。

执行umount /dev/md/stone\:supershare上述操作后mount,返回退出代码为0。执行后续umount结果:

umount: /dev/md/stone:supershare: not mounted

上面的命令是使用 sudo 自动运行的。

因此,它已成功安装并已成功卸载,但是...我root以 TTY0 身份登录,lsblk在执行mount操作后运行,但是,我没有看到mountpoint

NAME      MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda         8:0    0  55.9G  0 disk
├─sda1      8:1    0     1M  0 part
├─sda2      8:2    0     1G  0 part  [SWAP]
├─sda3      8:3    0    12G  0 part  /
└─sda4      8:4    0  16.6G  0 part  /home
sdb         8:16   0 931.5G  0 disk
└─sdb1      8:17   0   899M  0 part
  └─md127   9:127  0   1.8G  0 raid0
sdc         8:32   0 931.5G  0 disk
└─sdc1      8:33   0   899M  0 part
  └─md127   9:127  0   1.8G  0 raid0

从 TTY0尝试相同的mount命令会成功挂载它(之后显示 lsblk)。


如果我mount使用我的 CLI 工具,然后运行mount -llsblk使用 CLI 工具,安装点是可见的。

以 root 身份从 TTY0 立即运行这两个命令,不显示挂载点。


重新启动,重置所有挂载(不是自动挂载),然后从 TTY0 挂载并lsblk从 TTY0 运行显示挂载点。

然后,lsblk使用 CLI 工具运行,显示挂载点。

然后,umount使用 CLI 工具运行,退出代码0- 卸载。

再次使用 CLI 工具运行lsblk,不显示挂载点。

从 TTY0运行lsblk,仍然显示挂载点。


看来,当mount/umount使用我的 CLI 工具运行时,它会私下为sudo会话运行器执行命令。

umount在 TTY0 安装后,确实卸载它,但再次 - 私下。


从 TTY0 登录http并在从 CLI 工具挂载 RAID 后运行lsblk,挂载点不显示。这种否定“为sudo会话运行者私下执行”。


我还在IBM中找到了一份材料:

mount 命令使用真实用户 ID 而非有效用户 ID来确定用户是否具有适当的访问权限。系统组成员可以发出设备挂载,前提是他们对挂载点和 /etc/file systems 文件中指定的那些挂载具有写访问权。具有 root 用户权限的用户可以发出任何挂载命令


我希望我已经解释得足够好并且不会太混乱,我也希望你们能够在这里帮助我解决这个问题。


更新 (2013-10-28)

我尝试在 Web 上下文之外使用 CLI 工具进行测试,这是一个简单的 PHP 文件,我使用它root和自定义用户执行。

在这两种情况下,安装和卸载都是成功的。因此,它必须与 Apache 执行命令有关,但是,我不明白为什么其他命令会起作用。

问题

是什么导致了这个问题,我该如何克服它?

4

3 回答 3

3

总之,麻烦已经解决了

有指令的是 Apache 的相应systemd服务。PrivateTmp=true显然,该指令使用新的文件系统命名空间执行进程。


这个问题在尝试调试和解决问题时在互联网上产生了许多其他帖子。

  1. https://unix.stackexchange.com/questions/97897/sudo-mount-from-webserver-apache-by-mod-php-result-not-visible-by-root
  2. https://bbs.archlinux.org/viewtopic.php?id=172072
  3. https://unix.stackexchange.com/questions/98182/a-process-run-as-root-when-performing-mount-is-mounting-for-self-how-to-ma/98191#98191

每一个都来自我在这个过程中学到的东西。

我开始获取有关mountEUID. 很快,我发现我的简单sudo调用实际上并没有使用EUID 0. 这导致我对如何做到这一点进行了多次查询,这反过来又产生了类似的命令语法sudo -i 'su' -c 'mount /dev/sdb1 /mnt/firstone'和其他派生词。

解决方案没有成功,我进一步看了看。

我开始考虑尝试将条目添加到/etc/fstab,这导致我遇到大量权限问题。此外,sudo我的 CLI 工具被证明是不完整的任务。让我们带上大武器——让我们编译 Apache -DBIG_SECURITY_HOLE,也称为,给 Apache 以root.

让我们将条目附加到tab,让我们尝试挂载...并且...失败!

经过无数次的测试、查询等等,我偶然发现了per process mount它把我带到了这里并向我打开了维度namespaces

好的,这解释了一切——检查/proc/<pid>/mounts验证它,现在,让我们更深入地了解它,看看如何克服它。

同样,在多次尝试但没有成功后,我开始根据我对命名空间的新知识发布问题。缩小问题范围并变得更具技术性(至少我认为我做到了),最终导致一位用户 hiciu为我指明systemd方向,特别是 Apaches 服务 - PrivateTmp

瞧!...显然systemd可以强制执行新的命名空间。

于 2013-10-30T12:54:32.413 回答
0

我有同样奇怪的 apache 行为,花了 3 多天没有任何工作解决方案。然后幸运的是我找到了这篇文章,正如你所描述的 PrivateTmp 导致了这个问题。就我而言,我尝试从 php 挂载驱动器:

<?php
...
exec("sudo mount /dev/sda1 /mnt/drive", $output, $ret);
...
?>

当我从 Web 浏览器运行上述代码时,exec 函数返回 0(成功),我什至可以在代码中列出映射驱动器:

exec("ls /mnt/drive", $o, $r);
foreach ($o as $line){
  echo $line.'<BR>';
}

但是当我尝试从 cli 搜索映射驱动器时,我看不到它。我尝试了一切,包括更改权限、更改 php.ini 等。没有任何帮助。直到现在,改变

PrivateTmp=false

/lib/systemd/system/apache2.service

成功了。非常感谢您的分享!

于 2019-07-16T18:56:57.820 回答
0

它正在搜索这个,看起来这个行为是通过 chroot 从 php 中实现和检测到的:

 system('ischroot;echo $?');

在设置 PrivateTmp=true 时给出 0(说“你在 chroot 中”),在 PrivateTemp=false 时给出 1。

于 2019-11-21T20:57:56.203 回答