转载

将容器变成真正的沙箱

【编者的话】本文来自于Jessie Frazelle的博客,原文链接 here 。

容器现在非常流行,其最核心之处所使用的Linux原语和创建应用程序沙箱是一致的。大家比较熟悉的沙箱技术可能是Chrome沙箱,关于Chrome沙箱的详细介绍可以访问链接 chromium.googlesource.com/chromium/src/+/master/docs/linux_sandboxing.md ,其中与本文比较相关的是它使用了用户命名空间技术和seccomp机制,以及其他一些已经弃用的功能,包括AppArmor和SELinux。听起来有些熟悉?那是因为今天我们所了解的容器技术都使用了这些相同的功能。

为什么现在容器没有被认为是一个“沙箱”?

运行Chrome沙箱和运行容器的关键不同点之一在于权限的使用。Chrome沙箱以非特权用户身份运行,而大多数容器(例如docker、runc或者rkt)以root用户身份运行。

当然,我们都知道容器里运行的都是非特权进程,但是创建和启动容器在某些地方是需要使用root特权。

怎么以非特权用户运行容器?

你可能会说,非常容易,使用用户命名空间啊!但事实上没有这么简单。Chrome沙箱和容器的主要区别之一在于cgroups。Cgroups控制的是进程所能够使用的资源,而命名空间控制的是进程的可见范围。容器内嵌了cgroup资源管理,使用非特权用户创建cgroups是比较困难的,特别是设备控制组。

如果我们暂时忽略“使用非特权用户创建cgroups”这个难题,那使用非特权用户创建容器就简单了。用户命名空间技术允许我们在不使用任何特权的情况下创建所有命名空间,唯一需要提醒的是 {uid,gid}_map 必须将宿主机当前用户映射为容器内进程运行所使用的uid, {uid,gid}_map 的大小可以只设置为1。比如说,你使用uid为1000的用户来创建容器, {uid,gid}_map 设置为 0 1000 1 ,即表示在容器内以uid为0的用户身份来运行进程,而1指的是 {uid,gid}_map 的大小。

Docker对于用户命名空间的支持有什么不同?

Docker对于用户命名空间的支持与上述方式完全不同。默认情况下,当重映射用户被创建时, /etc/subuid/etc/subgid 这两文件将连续地写入65536范围以内从属用户和组的ID,起始ID的偏移量从这些文件当前条目开始计算。Docker的实现让更大范围的用户能够存于容器中,甚至可以让“匿名”用户来映射宿主机用户。如果你想了解更多关于Docker用户命名空间的实现,推荐 estesp 的博客或者docker的 官方文档

POC或者GTFO

为了证明在不使用cgroups情况下实现非特权容器的想法,我创建了 binctr 。我在谷歌论坛上也建了一个帖子来讨论如何在runc或者libcontainer中实现这个想法,具体可见 here 。 Aleksa Sarai 已经开始提交代码,这可能很快就会成为一个现实。

这是否处于“沙箱”范畴?

通过实现,我们将

  • namespaces
  • apparmor
  • selinux
  • seccomp
  • capabilities limiting

这些都使用非特权用户进行创建!

沙箱应该是比较面向具体应用的,使用定制的AppArmor配置文件、Seccomp配置文件等等。通用容器决不会等价于沙箱,因为它过于普遍而不能真正地锁定应用程序。

容器并不能够完全防止你的应用程序受到危害,但它能够限制受到危害的程度。攻击者在一个拥有定制AppArmor或Seccomp配置文件且十分严谨的容器中所看到的与不使用容器所看到的是完全不同的世界。通过命名空间我们可以限制应用程序的可见范围,例如网络、挂载点、进程等等。而且通过cgroups我们能够进一步限制攻击者所能够使用的资源,无论是内存、cpu,还是fork原语。

但关于cgroups呢?

我们可以使用非特权用户给内存、blkio、cpu和pids建立cgroups,只要cgroup子系统的所有者被修改为当前用户。设备却是另外一回事,不过无法在一个用户命名空间中使用mknod并不是世界上最糟糕的事情。

我们不要完全把设备cgroup排除,将来完全有可能实现。4.6版本以上的内核,将会有一种新的cgroup命名空间。而现在的做法就是在容器内掩盖了cgroups路径,所以对于非特权容器来说不是完全有用。但未来也许可以(如果我们的要求足够好?)

这个想法带给我们的最棒收益是什么?

GitHub上讨论非特权runc容器这个问题的评论者中大多数都是来源于一些科学社区,他们都严格地被要求使用非root用户来运行程序。

但是这个想法的用处远不止于这个。我最期盼的用法之一就是 Alex Larsson 在 xdg-app 所完成的工作,即在沙箱中运行应用程序。如果感兴趣的话可以了解下 bubblewrap 。

还有 subgraph ,基于OS的容器专门用于安全和隐私方面,和我们有着相同的想法。

对于在容器中运行桌面应用以及解决容器的多租户问题我都有非常大兴趣,我衷心希望能够帮助容器发展成一个真正的沙箱。

原文  http://dockone.io/article/1305
正文到此结束
Loading...