【从零造容器】Mount Namespace 与 pivot_root:构建容器文件系统
内容提要
本文讨论了容器文件系统隔离问题,指出传统的 chroot 方法存在安全隐患,容易被逃逸。介绍了 pivot_root 作为更安全的替代方案,通过创建独立的挂载点和切换根目录,确保容器进程只能访问自己的文件系统。同时强调了挂载传播类型的重要性,以及构建安全容器环境的必要性,包括设备节点和只读根文件系统的实现。
关键要点
-
容器进程能看到宿主机的文件系统,传统的 chroot 方法存在安全隐患。
-
chroot 只改变进程的根目录指针,无法有效隔离挂载表,容易被逃逸。
-
pivot_root 是更安全的替代方案,通过交换挂载树的根,确保容器进程只能访问自己的文件系统。
-
mount namespace 创建独立的挂载点表副本,确保容器的挂载操作不影响宿主机。
-
pivot_root 需要在 mount namespace 中使用,且 new_root 必须是挂载点。
-
容器的 /dev 需要最小化设备节点,避免暴露宿主机的设备。
-
容器的根文件系统应为只读,以防止攻击者修改文件系统。
-
挂载传播类型的设置至关重要,必须在容器初始化时设为 private,以避免宿主机的挂载变化影响容器。
延伸解读
chroot的局限性
传统的chroot方法虽然在历史上被广泛使用,但其安全性极为脆弱。文章指出,chroot仅仅改变了进程的根目录指针,无法有效隔离挂载表,导致容器进程可能轻易逃逸到宿主机的文件系统中。这一缺陷使得chroot不适合用于现代容器的安全隔离。
pivot_root的优势
pivot_root提供了一种更为安全的根目录切换机制,通过交换整个挂载树的根,确保容器进程只能访问其自身的文件系统。这种方法不仅消除了逃逸的可能性,还能在容器运行时有效隔离宿主机的文件系统,增强了容器的安全性。
挂载传播类型的重要性
文章强调了挂载传播类型的设置对容器安全的重要性。使用MS_PRIVATE可以确保容器的挂载操作不会影响宿主机,避免了潜在的安全风险。相反,如果未正确设置,容器内的挂载操作可能会意外影响宿主机的文件系统,导致严重的安全隐患。
只读根文件系统的必要性
将容器的根文件系统设置为只读是防止攻击者修改文件系统的重要措施。文章指出,虽然容器需要某些可写的目录(如/tmp和/run),但整体上保持根文件系统的只读状态可以有效提高容器的安全性,确保容器镜像的不可变性和可重复性。
延伸问答
为什么传统的 chroot 方法不安全?
传统的 chroot 方法只改变进程的根目录指针,无法有效隔离挂载表,容易被逃逸。
pivot_root 是如何提高容器安全性的?
pivot_root 通过交换挂载树的根,确保容器进程只能访问自己的文件系统,避免了逃逸风险。
什么是 mount namespace,它的作用是什么?
mount namespace 创建独立的挂载点表副本,确保容器的挂载操作不影响宿主机。
在构建容器时,如何确保根文件系统是只读的?
在 pivot_root 之后,可以通过重新挂载根文件系统为只读来确保其不可修改。
容器的 /dev 目录应该如何处理?
容器的 /dev 目录需要最小化设备节点,避免暴露宿主机的设备,通常使用 mknod 创建必要的设备节点。
挂载传播类型在容器初始化中有什么重要性?
挂载传播类型的设置至关重要,必须在容器初始化时设为 private,以避免宿主机的挂载变化影响容器。