在阅读了有关Linux名称空间的文章后,我的印象是,在许多其他特性中,它们是chroot的替代品。例如,在这篇文章中:
其他用途包括chroot()-style将进程隔离到单个目录层次结构的一部分。
但是,当我克隆挂载命名空间时(例如,使用下面的命令),我仍然可以看到整个原始根树。
unshare --mount -- /bin/bash我了解到,我现在能够在新命名空间中执行与原始命名空间不共享的附加挂载,从而提供隔离,但它仍然是相同的根,例如,对于两个命名空间,/etc仍然是相同的。我是否仍然需要chroot来更改根,还是有其他选择?
我原以为这个问题会提供一个答案,但答案还是只使用了chroot。
有一条现在删除的评论提到了pivot_root。因为这实际上是linux/fs/namespace.c的一部分,所以它实际上是名称空间实现的一部分。这表明只使用unshare和mount更改根目录是不可能的,但是名称空间提供了自己的--更聪明的-- chroot版本。不过,即使在阅读了源代码(例如安全性或更好的隔离性)之后,我仍然没有理解这种方法的主要思想,这使得它与chroot有根本的不同。
这不是这个问题的复制。在执行了答案中的所有命令之后,我有单独的/tmp/tmp.vyM9IwnKuY (或类似的),但是根目录仍然是相同的!
发布于 2018-07-17 14:25:58
在设置chroot之前输入挂载名称空间,可以避免将主机名称空间与附加挂载(例如/proc )混淆。您可以在挂载命名空间中使用chroot作为一个很好的简单的黑客。
我认为理解pivot_root是有好处的,但它有一点学习曲线。文件并不能解释一切..。尽管在man 8 pivot_root中有一个使用示例(用于shell命令)。如果man 2 pivot_root (用于系统调用)执行同样的操作,它可能会更清楚,并包含了一个示例C程序。
输入挂载命名空间后,您还需要mount --make-rslave /或等效名称空间。否则,所有挂载更改都会传播到原始命名空间中的挂载,包括pivot_root。你不会想要那样的:)。
如果使用unshare --mount命令,请注意默认情况下应用mount --make-rprivate是有文档记录的。AFAICS --这是一个糟糕的默认情况,您不希望在生产代码中这样做。在这一点上,它将阻止eject在主机命名空间中处理安装的DVD或USB。DVD或USB将继续安装在私有挂载树中,内核不会让您弹出DVD。
一旦您这样做了,您就可以挂载例如您将要使用的/proc目录。就像你对chroot一样。
与使用chroot不同,pivot_root要求新的根文件系统是一个挂载点。如果它还不是一个,您可以通过简单地应用绑定挂载:mount --rbind new_root new_root来满足这一点。
使用pivot_root -然后使用-l / MNT_DETACH选项,使用旧的根文件系统。(你不需要umount -R,这可能需要更长的时间。)。
从技术上讲,使用pivot_root通常也需要使用chroot;它既不是“也不是”。
根据man 2 pivot_root,它只定义为交换挂载命名空间的根。它不被定义为更改进程根指向的物理目录。或当前工作目录(/proc/self/cwd)。它确实是这样做的,但是这是一个处理内核线程的黑客。该组织表示,这种情况可能会在未来发生变化。
通常你想要这个序列:
chdir(new_root); // cd new_root
pivot_root(".", put_old); // pivot_root . put_old
chroot("."); // chroot .的假设chroot在这个序列中还有另一个微妙的细节。尽管pivot_root的目的是重新排列挂载命名空间,但是内核代码似乎通过查看每个进程的根文件系统来找到要移动的根文件系统,这是chroot设置的。
原则上,使用pivot_root进行安全和隔离是有意义的。我喜欢思考基于能力的安全的理论。您传递所需特定资源的列表,流程不能访问其他资源。在本例中,我们讨论的是传递给挂载命名空间的文件系统。这个想法通常适用于Linux的“名称空间”特性,尽管我的表达可能不是很好。
chroot只设置进程根,但进程仍然引用完整的挂载命名空间。如果一个进程保留了执行chroot的特权,那么它可以遍历文件系统命名空间。正如man 2 chroot中详细介绍的,“超级用户可以通过.逃离'chroot监狱‘”。
撤销chroot的另一种发人深省的方法是nsenter --mount=/proc/self/ns/mnt。这也许是对这一原则的一个更有力的论据。nsenter/setns()必须从挂载命名空间的根重新加载进程根。...虽然这两者引用不同的物理目录时起作用,但可能被认为是内核错误。(技术注意:可以在根目录上安装多个文件系统;setns()使用顶部,最近安装的文件系统)。
这说明了将挂载命名空间与"PID命名空间“相结合的一个优点。在PID命名空间中将阻止您进入无约束进程的挂载命名空间。它还防止您进入无约束进程(/proc/$PID/root)的根。当然,PID命名空间还可以阻止您杀死它之外的任何进程:-)。
https://unix.stackexchange.com/questions/456620
复制相似问题