使用 Smack 和 SELinux 增强轻量级容器(5)

现在,我们再次帮助 vs1 进行伪装。像创建 vs1 那样创建 vs2,在每个步骤中将 vs1 替换为 vs2。然后在 vs1 的 /mnt 下绑定装载根文件系统:

mount --bind /vs1 /vs1

mount --make-runbindable /vs1

mount --rbind / /vs1/rootfs.vs1/mnt

使用 vs1.sh 启动容器。注意,您还可以从 kvm 主机看到 vs1 和 vs2 上的 Web 页面。此外还要注意,vs1 不能通过网络访问 vs2。它也不能查看 vs2 的文件:

vs1:~# ls /mnt/

(directory listing)

vs1:~# ls /mnt/vs2/rootfs.vs2

ls:/mnt/vs2/rootfs.vs2: Permission denied

vs1:~# mkdir /cgroup

vs1:~# mount -t cgroup cgroup /cgroup

vs1:~# ls /cgroup

ls:/mnt/vs3: Permission denied

vs1:~# mknod /dev/sda1 b 8 1

mknod: `/dev/sda1': Operation not permitted

vs1:~# mount /mnt/dev/sda1 /tmp

mount: permission denied

它能查看主机文件系统。对于需要保护的任何东西,可以使用 host 标签进行标记。在 cgroup 文件系统上就采用了这种做法,这正是 ls /cgroup 失败的原因。

最后,设备白名单 cgroup 防止我们创建磁盘设备,或在它存在的情况下装载它(因为这需要通过 /mnt 来完成)。

当然,我们的设置方式让容器管理员可以删除 /mnt/dev/sda1,或用其他方法扰乱主机,因此除了用于演示外,这种绑定装载是不如人意的!

注意,在 SELinux 系统上,默认(且容易的)路由允许容器通过网络彼此进行对话,而在 Smack 中则恰好相反。目前,允许容器彼此对话还是比较困难的。不久以后,将可以在 IP 地址上设置标签,并且允许建立策略以实现容器之间的通信。

在如何建立 Smack 网络方面还有另一个问题。命令 kill -9 -1 终止系统上的每个任务。当这个操作由容器中的任务执行时,它将仅终止同一容器中的任务。这种行为已经在上游内核中得到修复,但我们使用的 Fedora 10 内核还存在该问题。因此,每个任务都会发出一个 -9 信号。

在受 SELinux 保护的容器中,SELinux 阻止该信号通过容器边界,因此 kill -9 -1 实际上是安全的。但在 Smack 中,默认情况下任务被标记为 _(就像网络一样),因此由于我们允许容器执行 _ 写操作以写到网络中,并且终止任务在 Smack 中被认为是写访问,所以允许容器管理员在整个系统上终止任何任务。

另一个缺点(SELinux 容器仍然存在该缺点)与 Unix98 伪终端有关。打开两个图形化终端。在第一个终端中,启动 vs1 并查看 /dev/pts。您将看见至少两个条目(0 和 1),它们分别属于每个终端。可以从 vs1 容器写入到与另一个终端对应的条目。

对于 Fedora 内核,有两个解决方案。可以使用设备白名单 cgroup 拒绝容器打开设备。但是这必须在容器每次启动时手动操作,以允许它访问自己的终端;或者应用 SELinux 和 Smack 标签,结果是一样的。

更新的 2.6.29 内核支持 devpts 名称空间。容器必须重新装载 /dev/pts,在这个操作之后,它将不能访问属于主机或其他容器的 devpts 条目。

致谢

Dan Walsh 提供了关于 SELinux 策略的反馈,Smack 的作者 Casey Schaufler 为构建受 Smack 保护的容器提供了帮助。我在此对他们表示衷心感谢!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/28638.html