如何在Linux名称空间中执行chroot?


14

在阅读了有关Linux名称空间的信息后,我感到它们是chroot的替代品,其中包括许多其他功能。例如,在本文中

[...]命名空间的其他用途包括将进程的chroot()样式隔离到单个目录层次结构的一部分。

但是,当我克隆装载名称空间时,例如使用以下命令,我仍然可以看到整个原始根树。

unshare --mount -- /bin/bash

我知道我现在可以在新的名称空间中执行与原始名称空间不共享的其他挂载,因此可以提供隔离,但是它仍然是相同的根,例如/etc,两个名称空间仍然相同。我仍然需要chroot更改根目录还是有替代方法?

我原以为这个问题会提供答案,但是答案仅chroot再次使用。

编辑#1

现在有提到的已删除评论pivot_root。由于这实际上是的一部分linux/fs/namespace.c,因此实际上是名称空间实现的一部分。这表明只能使用unshare和更改根目录mount是不可能的,但是名称空间提供了自己的-更聪明的版本chrootchroot即使在阅读了源代码之后(例如在安全性或更好的隔离性的意义上),我仍然没有获得使这种方法与根本上有所不同的这种方法的主要思想。

编辑#2

这不是这个问题的重复。执行完答案中的所有命令后,我有单独的/tmp/tmp.vyM9IwnKuY(或类似的文件),但是根目录仍然相同!


对于之间的区别pivot_rootchroot:我看了一下泊坞窗来源,发现如果失败执行pivot_root,它回落到chroot,即这些机制被认为是至少在集装箱的目的的功能类似。
Danila Kiver

Answers:


13

在设置之前输入安装名称空间chroot,可以避免使用其他安装(例如)使主机名称空间混乱/proc。您可以chroot在安装命名空间内部使用它作为一种不错的简单方法。

我认为理解有很多好处pivot_root,但是它有一些学习曲线。尽管其中有一个使用示例man 8 pivot_root(用于shell命令),但文档并没有完全解释所有内容。 man 2 pivot_root(对于系统调用)是否做得更清楚,并包含示例C程序。

如何使用pivot_root

输入挂载名称空间后,您也需要立即进行mount --make-rslave /等效操作。否则,您所有的安装更改都将传播到原始名称空间中的安装,包括pivot_root。你不想要那:)。

如果使用了该unshare --mount命令,请注意该文件mount --make-rprivate默认情况下适用。AFAICS,这是一个错误的默认设置,您不希望在生产代码中使用它。例如,此时,它将停止eject处理主机名称空间中已安装的DVD或USB。DVD或USB仍将挂载在专用挂载树中,并且内核不允许您弹出DVD。

完成此操作后,您可以挂载/proc要使用的目录。您将使用相同的方法chroot

与使用时不同chroot,它pivot_root要求新的根文件系统是安装点。如果还不是,则可以通过简单地应用bind mount:来满足此要求mount --rbind new_root new_root

使用pivot_root-,然后umount使用旧的根文件系统,并带有-l/ MNT_DETACH选项。(您不需要umount -R,这可能需要更长的时间。

从技术上讲,使用pivot_root通常还需要包括使用chroot;不是“非此即彼”。

按照man 2 pivot_root,它仅定义为交换mount名称空间的根。未定义更改进程根指向的物理目录。或当前的工作目录(/proc/self/cwd)。碰巧确实这样做了,但这是处理内核线程的一种方法。手册页说,将来可能会改变。

通常,您需要以下顺序:

chdir(new_root);            // cd new_root
pivot_root(".", put_old);   // pivot_root . put_old
chroot(".");                // chroot .

的的postition chroot这个顺序又是一个微妙的细节。尽管重点pivot_root是重新安排安装命名空间,但是内核代码似乎通过查看按进程设置的根来找到要移动的根文件系统chroot

为什么要使用pivot_root

原则上,将其pivot_root用于安全性和隔离是有意义的。我喜欢考虑基于能力的安全性理论。您传入所需的特定资源的列表,该过程将无法访问其他资源。在这种情况下,我们正在讨论传递到安装名称空间的文件系统。这个想法通常适用于Linux的“命名空间”功能,尽管我可能不太清楚。

chroot仅设置进程根,但进程仍引用完整的安装名称空间。如果进程保留执行的特权chroot,则它可以遍历备份文件系统名称空间。如中所述man 2 chroot,“超级用户可以通过...逃离'chroot监狱'”。

撤销的另一种发人深省的方法chrootnsenter --mount=/proc/self/ns/mnt。对于该原则,这也许是一个更有力的论据。 nsenter/ setns()必定会从mount名称空间的根目录中重新加载进程根目录 ...尽管当两者引用不同的物理目录时这有效,这可能被认为是内核错误。(技术说明:在根目录上可能有多个文件系统彼此并排安装;setns()使用顶部的,最近安装的文件系统)。

这说明了将安装名称空间与“ PID名称空间”组合在一起的一个优点。位于PID名称空间中将阻止您输入未限制进程的安装名称空间。它还会阻止您输入无限制进程(/proc/$PID/root)的根。当然,PID名称空间还可以防止您杀死它之外的任何进程:-)。


这已经很有帮助。不过,我不确定“名称空间顶部的安装”是什么意思。有办法改变吗?
koalo

1
@koalo编辑了:-)。PS:我不知道为什么您需要为“ make-rslave” /“ make-rprivate”使用fstab。systemd的switch-root.c只是这样做mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)
sourcejedi

1
@koalo,然后Linux内核开发人员在命名第四件事时使用了“ rootfs” :-P。unix.stackexchange.com/questions/152029/...
sourcejedi

1
这个答案和@sourcejedi的其他答案非常有用,我会问“ pivot_root:不能把put_old设置为忙碌”,但答案已经在这里了,因为强制不起作用而变得懒惰umount -l ./oldroot
earcam '18

1
最近,对pivot_root(2)手册页进行了更新,其中进行了一些澄清,现在包括一个示例程序。您可能想更新您的答案以反映这一点?手册页现在还说明了一个不错的pivot_root(".", ".")技巧,它实际上是pivot_root在大多数情况下(chroot不需要)使用的最简单方法。
菲利普·温德勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.