LWN:无特权的chroot() !

关注了就能看到更多这么棒的文章哦~

Unprivileged chroot()

By Jonathan Corbet
March 15, 2021
DeepL assisted translation
https://lwn.net/Articles/849125/

可以说大多数 Linux 开发者都不会在应用程序中使用 chroot()。这个系统调用会将调用它的进程放入一个新的文件系统视角,也就是将传入的目录作为根目录。它可以用来将此进程与文件系统的大部分隔离开,不过这个安全优势还是比较有限的。调用 chroot()是一种特权操作,但是,如果 Mickaël Salaün 能成功推销这组 patch set 的话,至少在某些情况下后面会发生变化。

chroot() 通常会被用来对网络守护进程(network daemon process)放到一个小监狱(jail)里。如果该进程被入侵了,那么它也只能访问这个新设置的根目录之内的子目录。由此而产生了安全防护的效果,尽管这种防护并不是最强防护(有很多方法可以突破 chroot()的限制),但它仍然可以为攻击者增加一些麻烦。chroot()还可以用来让各个进程看到不同的文件系统,比如运行 container 的时候就需要这个能力。

这个系统调用并不是任何人都可以使用的,需要有 CAP_SYS_CHROOT 这个 capability 才能调用 chroot()。进行这个限制是为了防止攻击者在精心制作的文件目录树中运行 setuid 程序,从而来欺骗(和利用)这些程序。举个简单的例子,如果 setuid 程序看到的/etc/passwd 或/etc/sudoers 文件其实是攻击者提供出来的,那么就会产生严重的错误行为。

长久以来,chroot()的局限性导致了它很难得到应用。近年来,它的应用范围更小了,因为出现了 Mount namespace 这种更灵活的机制也可以实现使用新的文件目录树的功能,并且也更难被攻破。所以相对来说,很少有开发者认为在今后的开发中需要使用 chroot()。

因此,当 Salaün 带着他的 chroot()补丁出现时,人们有点惊讶。一旦合入了这个 patch,无权限的进程也可以调用 chroot(),但前提是必须满足几个条件:

  • 此进程必须在调用 prctl()时使用 PR_SET_NO_NEW_PRIVS 选项。这就阻止此进程在今后获得任何新的特权。例如运行 setuid 和 setgid 程序也将不再能获得这些程序属主的特权。既然在该模式下不再会有特权程序,那么相应地这些特权也就不会再被利用了。

  • 此进程不能与其他任何进程共享它的文件系统上下文(也就是 struct fs_struct,其中包含了 root 目录和当前工作目录这些信息),否则 chroot()调用会对这两个进程都生效,而另一个进程可能不会预料到它的文件系统环境会突然改变。

  • 新的 root 必须在文件系统层次结构中的当前 root 之下。这就阻止了那些可能会导致进程可以跳出当前 jail(监牢) 或 mount space 之外的手段。

如果满足这些条件,可以认为,允许进程调用 chroot() 就是安全的。

但是,为什么要这样做呢?其中一个原因是,一个正常运行的 chroot() 环境通常需要有一个包含了最少信息的/dev 目录,而创建这些设备节点仍然是一个需要特权的操作。如上所述,Linux 早就已经有了比 chroot() 更好的选择了。但 Salaün 说,在一些使用场景中,某个进程可能希望在从不受限的环境中加载到它的依赖关系(例如函数库)之后,自己进入沙箱,而设备文件通常可能是用不到的。

对这个 patch 的最初反应比较冷淡。Eric Biederman 担心无权限的 chroot()与其他机制混合使用之后会产生安全问题:

在建立了 sandbox、使用了 seccomp filter、并且启用了 no_new_privs 之后,还仍然允许 chroot,这似乎是在自找麻烦,并且可能会削弱现有的 sandbox。

Casey Schaufler 认为 chroot()已经过时了,同时也担心类似的跟其他机制混合使用的问题:"我们仍然发现了一些 corner case(比如 ptrace),在这些情况下 no_new_privs 是有缺陷的"。他还指出,对 chroot()的访问已经有了更加精细的 capability 控制,也就是 CAP_SYS_CHROOT。

CAP_SYS_CHROOT 就是针对 chroot 的。它不会提供其他不需要的权限,不像 CAP_CHOWN 或 CAP_SYS_ADMIN 那样。把 chroot 变成不需要特权的这种做法是愚蠢的,因为它可能是 capability 机制本来就应该起作用的场景。

Salaün 并没有回答所有这些问题,但似乎并不气馁,在讨论结束后,他发布了第二版 patch set。不过,如果没有更有说服力的回应的话,很难将此改动推到 upstream。以安全为导向的开发者需要被说服,让他们相信 chroot()值得改进。对于那些与其他安全机制混用可能会出现意外的改动,upstream 的门槛会更高。

讨论最终很可能会回到具体使用场景上。在 2021 年是否还真的需要不需要特权的 chroot()?如果有用户可以从这个功能中受益,现在可能是他们站出来解释为什么需要这个功能的好时机。如果没有这些信息,那么 unprivileged chroot() 很可能就是不会成为现实。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值