在阅读了 Linux 命名空间之后,我的印象是,在许多其他功能中,它们是 chroot 的替代品。例如,在这篇文章中:
[名称空间] 的其他用途包括 [...] chroot() 式将进程隔离到单个目录层次结构的一部分。
但是,当我克隆 mount 命名空间时,例如使用以下命令,我仍然看到整个原始根树。
unshare --mount -- /bin/bash
Run Code Online (Sandbox Code Playgroud)
我知道我现在能够在不与原始命名空间共享的新命名空间中执行额外的挂载,因此这提供了隔离,但它仍然是同一个根,例如/etc
两个命名空间仍然相同。我还需要chroot
更改根目录还是有其他选择?
我期待这个问题会提供答案,但答案chroot
再次仅使用, 。
有一条现已删除的评论提到pivot_root
。由于这实际上是 的一部分linux/fs/namespace.c
,因此它实际上是名称空间实现的一部分。这表明仅使用unshare
和更改根目录mount
是不可能的,但命名空间提供了一个自己的——更聪明的—— chroot
. chroot
即使在阅读源代码之后(例如在安全性或更好的隔离的意义上),我仍然不明白这种方法的主要思想,这使得它与 根本不同。
这不是这个问题的重复。执行完答案中的所有命令后,我有单独的 /tmp/tmp.vyM9IwnKuY(或类似的),但根目录仍然相同!
sou*_*edi 18
在设置 之前输入挂载命名空间chroot
,可让您避免使用其他挂载(例如 for /proc
. 您可以chroot
在 mount 命名空间内使用作为一个不错的简单技巧。
我认为理解 有优势pivot_root
,但它有一点学习曲线。该文档并没有完全解释所有内容......尽管man 8 pivot_root
(对于shell命令)中有一个用法示例。 man 2 pivot_root
(对于系统调用)如果这样做的话可能会更清楚,并且包含一个示例 C 程序。
紧接着进入 mount 命名空间后,你还需要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
- 然后umount
是旧的根文件系统,带有-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 .
Run Code Online (Sandbox Code Playgroud)
的的postitionchroot
这个顺序又是一个微妙的细节。虽然重点pivot_root
是重新排列挂载命名空间,但内核代码似乎通过查看每个进程的根来找到要移动的根文件系统,这就是chroot
设置。
原则上,pivot_root
用于安全和隔离是有意义的。我喜欢思考基于能力的安全理论。您传入所需特定资源的列表,该进程无法访问其他资源。在这种情况下,我们讨论的是传递给挂载命名空间的文件系统。这个想法通常适用于 Linux 的“命名空间”功能,尽管我可能没有很好地表达它。
chroot
只设置进程根,但进程仍然引用完整的挂载命名空间。如果一个进程保留了执行权限chroot
,那么它可以遍历备份文件系统命名空间。如 中所述man 2 chroot
,“超级用户可以通过……从 'chroot jail' 中逃脱”。
另一种发人深省的撤消方式chroot
是nsenter --mount=/proc/self/ns/mnt
. 这也许是该原则的一个更有力的论据。 nsenter
/setns()
必须从挂载命名空间的根目录重新加载进程根目录......尽管当两者引用不同的物理目录时这有效,但可能被认为是内核错误。(技术说明:在根目录中可能有多个文件系统彼此重叠安装;setns()
使用顶部,最近安装的一个)。
这说明了将挂载命名空间与“PID 命名空间”相结合的一个优势。位于 PID 命名空间内会阻止您进入未受限进程的挂载命名空间。它还可以防止您进入不受限制的进程 ( /proc/$PID/root
)的根目录。当然,PID 命名空间还可以防止您杀死它之外的任何进程:-)。
归档时间: |
|
查看次数: |
5549 次 |
最近记录: |