使用apparmor提升lxc的安全性

阿凡达2018-08-14 09:22
相对于kvm等重量级的全虚拟化而言,lxc是基于操作系统层面进行虚拟化管理,lxc虚拟机和宿主机共用同一内核,存在着一定的安全隐患,比如说用户可以在自己的lxc云主机中修改宿主机的某些配置。本文将通过一个简单的读写文件实例来介绍如何使用apparmor安全模块提升lxc的安全性。
环境:debian7服务器, 3.2内核

1. 利用libvirt创建lxc
1) 配置wheezy-backports源,apt-get install libvirt-bin python-libvirt
2) 创建lxc前需要在debian server中挂载cgroups系统(cpu、cpuacct、cpuset、memory、blkio,devices)
# mount Cgroup shell script
mount -t tmpfs cgroup_root /sys/fs/cgroup/
mkdir /sys/fs/cgroup/cpuset
mount -t cgroup -ocpuset cpuset /sys/fs/cgroup/cpuset
mkdir /sys/fs/cgroup/blkio
mount -t cgroup -oblkio blkio /sys/fs/cgroup/blkio/
mkdir /sys/fs/cgroup/cpuacct
mount -t cgroup -ocpuacct cpuacct /sys/fs/cgroup/cpuacct/
mkdir /sys/fs/cgroup/devices
mount -t cgroup -odevices devices /sys/fs/cgroup/devices/
mkdir /sys/fs/cgroup/cpu
mount -t cgroup -ocpu cpu /sys/fs/cgroup/cpu
mkdir /sys/fs/cgroup/memory
mount -t cgroup -omemory memory /sys/fs/cgroup/memory
debian系统默认disable 掉了memory cgroup,默认情况下无法挂载memory cgroup。(可以在 /etc/default/grub文件中,增加一行 GRUB_CMDLINE_LINUX="cgroup_enable=memory"  ,然后执行 update-grub2 命令,并重启服务器来enable memory cgroup。
可以通过cat /proc/cgroups来查看当前系统可以挂载的cgroups。
3)  启动一个简单的lxc
创建一个简单的lxc libvirt配置xml

    
root@debian:~# cat > helloworld.xml <<EOF
<domain type='lxc'>
  <name>helloworld</name>
  <memory>102400</memory>
  <os>
    <type>exe</type>
    <init>/bin/sh</init>
  </os>
  <devices>
    <console type='pty'/>
  </devices>
</domain>
EOF
根据上述的配置来定义一个lxc 并 启动它。

   
root@debian:~# virsh -c lxc:/// define helloworld.xml
Domain helloworld defined from helloworld.xml
root@debian:~# virsh -c lxc:/// start helloworld
Domain helloworld started
root@debian:~# virsh -c lxc:/// list
Id Name                 State
----------------------------------
31417 helloworld           running

2. 设置apparmor前,在lxc中进行服务器/root目录的读写测试
宿主机中观察/root目录的内容:

   
root@debian:~# ls /root
helloworld.xml
root@debian:~# 
通过libvirt的console接口进入lxc,并进行文件读写操作:

   
root@debian:~#virsh -c lxc:/// console helloworld
Connected to domain helloworld
Escape character is ^]
# ls /root 
# helloworld.xml
# touch /root/hello 
# ls /root 
hello helloworld.xml
#
此时,在debian服务器上可以看到/root目录中新增了创建的hello文件:

   
root@debian:~# ls /root
hello helloworld.xml
备注:debian服务器中默认并未加载mount等namespace,因此在lxc中可以访问到宿主服务器的文件系统。服务器加载了哪些namespace可以通过如下命令查看:

   
root@debian:~# ls /proc/self/ns 
ipc net uts

3. 为libvirt lxc配置apparmor安全策略
1)安装apparmor软件, aptitude install apparmor apparmor-utils dh-apparmor libapparmor-dev
2)/boot/grub/grub.cfg启动项参数中增加 “apparmor=1 security=apparmor”来加载apparmor内核模块(https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=701714)并重启debian server
3)修改libvirt配置,启动libvirt 的apparmor安全驱动
在/etc/libvirt/lxc.conf中配置 security_driver = "apparmor"  并重启libvirt服务
4) 设置helloworld lxc的apparmor profile,如下:

   
root@debian:~# virsh -c lxc:/// domuuid helloworld
5c4f5baf-eed3-4d80-8dbe-f2021f37610
root@debian:~# cat /etc/apparmor.d/libvirt/libvirt-5c4f5baf-eed3-4d80-8dbe-f2021f376103
#                                                                              
# This profile is for the domain whose UUID matches this file.                  
#                                                                                                                                                             
#include <tunables/global>                                                                                                                                   
profile libvirt-5c4f5baf-eed3-4d80-8dbe-f2021f376103 {                          
  #include <abstractions/libvirt-lxc>                                          
  deny /root/* wklx,                                                                   
                                                       
  # Globally allows everything to run under this profile                        
  # These can be narrowed depending on the container's use.                    
  file,                                                                        
  capability,                                                                  
  network,                                                                      
}
在上述apparmor的profile配置中,我们禁止该lxc 写/root目录。
5) 重启helloworld lxc后通过console进入lxc中进行/root目录的写入操作:

   
root@debian:~#virsh -c lxc:/// console helloworld 
Connected to domain helloworld 
Escape character is ^] 
# ls /root 
hello helloworld.xml
# touch /root/world 
touch: cannot touch `/root/world': Permission denied 
通过上述测试结果可知,通过apparmor限制lxc对/root目录的写权限后,lxc内部无法在/root目录下面创建文件。

本文只是介绍apparmor提升lxc安全性的一个小应用。除了文件的访问控制之外,apparmor还可以进行linux capabilities,network等方面的权限控制,有兴趣的可以自己深入研究下apparmor的使用机制。

参考:
https://www.berrange.com/posts/2011/09/27/getting-started-with-lxc-using-libvirt/ 
http://wiki.apparmor.net/index.php/Libvirt
https://wiki.debian.org/AppArmor/HowTo
http://wiki.apparmor.net/index.php/QuickProfileLanguage



网易云新用户大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者管强授权发布。