我们在上一章讲过了docker容器的安全,那么在这一章我们再来讲一下lxcfs来提供容器中的资源可见性。
lxcfs是一个开源的FUSE(用户态文件系统)实现来支持LXC容器。
LXCFS通过用户态文件系统,在容器中提供下列 procfs 的文件:
- /proc/cpuinfo
- /proc/diskstats
- /proc/meminfo
- /proc/stat
- /proc/swaps
- /proc/uptime
比如,把宿主机的 /var/lib/lxcfs/proc/memoinfo 文件挂载到Docker容器的/proc/meminfo位置后。容器中进程读取相应文件内容时,LXCFS的FUSE实现会从容器对应的Cgroup中 读取正确的内存限制。从而使得应用获得正确的资源约束设定
一、利用LXCFS增强docker容器隔离性和资源可见性
在上一章我们做过容器的资源控制,不过我们也要注意到当我们查看系统资源的时候发现出现的数据并不是我们者之的那样,这样明显是不合理的。
1.安装LXCFS
[root@server1 ~]# ls
busybox.tar distroless.tar lxcfs-2.0.5-3.el7.centos.x86_64.rpm ubuntu.tar
convoy docker nginx.tar
convoy.tar.gz game2048.tar rhel7.tar
[root@server1 ~]# yum install -y lxcfs-2.0.5-3.el7.centos.x86_64.rpm
安装完lxcfs之后,会在/var/lib目录下生成lxcfs目录。只是/var/lib/lxcfs目录中没有内容。
2.启动lxcfs
[root@server1 ~]# cd /var/lib/lxcfs/
[root@server1 lxcfs]# ls
[root@server1 lxcfs]# lxcfs /var/lib/lxcfs/ & 启动lxcfs,但是注意按回车结束,不要使用ctrl+c,否则就直接结束lxcfs进程
[1] 2458
[root@server1 lxcfs]# hierarchies:
0: fd: 5: pids
1: fd: 6: hugetlb
2: fd: 7: perf_event
3: fd: 8: blkio
4: fd: 9: cpuacct,cpu
5: fd: 10: memory
6: fd: 11: cpuset
7: fd: 12: net_prio,net_cls
8: fd: 13: freezer
9: fd: 14: devices
10: fd: 15: name=systemd
[root@server1 lxcfs]# cd
[root@server1 ~]# cd /var/lib/lxcfs/ 启动后自动生成cgroup目录和proc目录
[root@server1 lxcfs]# ls
cgroup proc
[root@server1 lxcfs]#
使用ps ax 命令查看lxcfs进程
3.docker使用lxcfs的数据卷测试
[root@server1 ~]# docker run -it --name vm4 -m 200m \
> -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo \
> -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
> -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
> -v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
> -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
> -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
> ubuntu
root@3acc5223e233:/# free -m
total used free shared buffers cached
Mem: 200 5 194 16 0 0
-/+ buffers/cache: 5 194
Swap: 200 0 200
root@3acc5223e233:/#
看一看到我们的容器的内存大小是我们设置的那样
注意:
不能直接把/var/lib/lxcfs/proc目录挂载到容器内的/proc目录下,因为容器内的/proc目录下本身是有内容的,是系统的进程信息等等,如果直接把/var/lib/lxcfs/proc目录挂载到容器内的/proc目录下,会覆盖容器内/proc目录下的内容,而/proc目录下记录的是容器的进程信息等等内容,是不能被覆盖的,所以不能直接把/var/lib/lxcfs/proc目录挂载到容器内的/proc目录下。
二、设置特权级运行的容器:–privileged=true
有的时候我们需要容器具备更多的权限,比如操作内核模块,控制swap交换分区,挂载USB磁盘,修改MAC地址等。
我们建立容器后,进入容器的root帐号的权限是受限制的,不是真正的root用户。
加入–privileged=true参数,获得的是具有管理员权限的root用户。
–privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时Docker 提供了权限白名单的机制,使用–cap-add添加必要的权限。
安全加固的思路
1.保证镜像的安全
- 使用安全的基础镜像
- 删除镜像中的setuid和setgid权限
- 启用Docker的内容信任
- 最小安装原则
- 对镜像进行安全漏洞扫描,镜像安全扫描器:Clair
- 容器使用非root用户运行
2.保证容器的安全
- 对docker宿主机进行安全加固
- 限制容器之间的网络流量
- 配置Docker守护程序的TLS身份验证
- 启用用户命名空间支持
- 限制容器的内存使用量
- 适当设置容器CPU优先级
3.主要的内核子系统都没有命名空间,如:
- SELinux
- cgroup
- 在/sys下的文件系统
- /proc/sys, /proc/sysrq-trigger, /proc/irq, /proc/bus
4.设备没有命名空间:
- /dev/mem
- /dev/sd*文件系统设备
- 内核模块
如果你能沟通或攻击的其中之一作为特权的过程中,你可以拥有自己的系统。