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

使用命令 lxc-start -n vsplain 启动这个容器。这时将出现登录提示。通过不需要密码的根用户名登录到容器。最后,当容器运行时,则需要执行下面的命令:

apt-get install openssh-server

apt-get install apache

现在可以使用 ssh 技术安全地从 kvm 主机转移到容器,并使用 vsplain 和主机的 ip 地址(分别是 10.0.2.20 和 10.0.2.15)查看它的 Web 页面。您随时可以通过命令 lxc-stop -n vsplain 从 kvm 主机的根终端关闭容器。

在这里,通过从这个模板克隆两个新的虚拟机可以节省一些时间。关闭 vm 并执行:

cp vm.img selinux.img

cp vm.img smack.img

受 SELinux 保护的容器

我们将在容器上使用的 SELinux 策略包含一个 策略模块;这个模块已经发布到 refpolicy -- SELinux Reference Policy 开发邮件列表。将这个策略分别下载到 /root/vs 目录下的 vs.if、vs.fc 和 vs.te 文件中。像下面这样编译和安装新的模块:

cp vm.img selinux.img

cp vm.img smack.img

然后使用 lxc-debian 创建 /vs1 and /vs2 容器,并且使用

mkdir /vs1; cd /vs1

lxc-debian create

container name: vs1

hostname: vs1

address: 10.0.2.21

gateway: 10.0.2.2

arch: 2 (i386)

mkdir /vs2; cd /vs2

lxc-debian create

container name: vs2

hostname: vs2

address: 10.0.2.22

gateway: 10.0.2.2

arch: 2 (i386)

fixfiles relabel /vs1

fixfiles relabel /vs2

重新标记它们的文件系统。

在启动容器时(例如通过使用命令 lxc-start -n vs1),很可能会收到一些关于 SELinux 访问拒绝的审计消息。但不要担心 —— 容器将正常启动,并且会启用网络服务并 隔离容器。如果在启动容器之前使用 mount --bind / /vs1/rootfs.vs1/mnt 帮助容器 vs1 进行伪装,那么您将会发现,即使是根用户,也会重用 ls /mnt/root。

为了了解其中的原理,我们看看 vs.if 接口文件。这个文件定义一个称为 container 的接口,它带有一个参数(即容器将要定义的基本名称)。vs.te 文件使用容器名 vs1 和 vs2 两次调用这个函数。在这个接口中,$1 被扩展到这个参数,因此当我们调用 container(vs1) 时,$1_t 就会变成 vs1_t(从这里开始,假设我们定义的是 vs1)。

包含 vs1_exec_t 内容的行是最重要的。这个容器以 vs1_t 类型运行。当 unconfined_t 执行容器的 /sbin/init(类型为 vs1_exec_t)时,它将进入这种类型。

剩余的策略主要是授与容器充分的特权,以访问系统的各个部分:网络端口、设备和控制台等。该接口很长,这是由现有 SELinux 引用策略的细粒度特性决定的。正如我们将要看到的一样,受 Smack 保护的容器具有更加简单的策略;但是它在系统服务行为失误时提供的灵活保护要少得多。

还有一件事情需要做。需要注意的是,虽然容器不能够重写它的 $1_exec_t(即 /sbin/init),但它能够执行

mv /sbin /sbin.bak

mkdir /sbin

touch /sbin/init

生成的 /sbin/init 的类型为 vs1_file_t。容器管理员为什么需要这样做呢?因为它会在 unconfined_t 域中启动容器,包括 ssh daemon,这使他能够获得有特权的 shell,并且能够绕过我们将要实施的 SELinux 限制。

为了避免这样做,需要通过定制脚本实际启动容器,并在启动容器前将 sbin/init 重新标记为 vs1_exec_t。事实上,如果容器管理员不介意的话,可以将一个 init 原始副本复制回容器中并重新标记它。但我们仅重新标记现有的 init:

cat >> /vs1/vs1.sh << EOF

#!/bin/sh

chcon -t vs1_exec_t /vs1/rootfs.vs1/sbin/init

lxc-start -n vs1

EOF

chmod u+x /vs1/vs1.sh

现在需要使用 /vs1/vs1.sh 启动容器,而不是使用 lxc-start 手工启动。

受 Smack 保护的容器

在启用 Smack 时重新编译内核。您必须能够进入 /root/rpmbuild/BUILD/kernel*/linux* 目录的 make menuconfig,然后转到 security 菜单禁用 SELinux 并启用 Smack。接下来仅需重复步骤 make && make modules_install && make install。

此外,也要停止用户空间对 SELinux 的配置。这可以在 SELinux 管理 GUI 上实现,或编辑 /etc/selinux/config 并设置 SELINUX=disabled。要在引导时安装 Smack 策略还需要几个步骤:

mkdir /smack

cd /usr/src

wget

tar xf smack-util-0.1.tar; cd smack-util-0.1

make && cp smackload /bin

实际的 Smack 策略类似于清单 1:

清单 1. smackaccesses

vs1 _ rwa

_ vs1 rwa

vs2 _ rwa

_ vs2 rwa

_ host rwax

host _ rwax

应该将它复制到一个名为 /etc/smackaccesses 的文件中。下次运行 /bin/container_setup.sh 时会将这个文件加载到 smackload。

这个策略十分简单。默认情况下,任何标签都可以读取标记有 _ 的数据。我们为容器不能访问的主机的私有数据定义一个新标签 host;并且将这个标签应用到 container_setup.sh 脚本中的 cgroups 文件系统。其他敏感文件,比如 /etc/shadow,应该使用这个标签。

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

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