前言:
Docker容器的安全性,很大程度上依赖于linux系统本身,当进行docker安全
评估时,主要考虑以下几个方面:
linux内核的命名空间机制提供的容器隔离安全
linux控制组机制对容器的控制能力安全
linux内核的能力机制带来的操作权限安全
docker程序(特别是服务器)本身的抗攻击能力
其他安全增强机制对安全性的影响。
控制组资源控制的安全
当docker run 启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
Linux Cgtoup提供了很多有用的特性,确保各容器可以公开地分享主机地内存,cpu,磁盘
的IO等资源。
确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务
攻击DDos方面必不可少,
正文:
进行docker软件的安装:
[root@server1 ~]# yum install -y * ###进行软件以及依赖性的安装
基于我们要了解容器的资源管理机制,我们首先应该了解以下,Linux系统中的资源管理机制,
这里我们使用cgroup进行资源的控制管理,cgroup与进程类似,是分等级的,各个属性是继承
于父进程的,用户可以通过cgroup为其控制的任务分配资源,如CPU 、 内存、网络带宽、cgroup
包含了多个子系统,每个子系统代表一个单一的资源,以redhat企业板7.3为例,我们可以在/sys/fs/cgroup
下进行查看。
a) bikio:用于限制每个块设备的输入与输出,如磁盘和USB等
b) cpu: 提供对cpu的访问
c) cpuacct : 生成cgroup任务的cpu资源报告
d) cpuset: 对于多核的cpu。该子系统为cgroup任务分配单独的cpu和内存
e) device: 允许或者拒绝cgroup任务对设备的访问
f) freezer: 暂停和恢复cgroup任务
g) memory : 提供对内存的访问以及生成内存资源报告
h) net-cls:提供对网络带宽的访问
i) ns: 命名空间子系统
进行cgroup工作目录的查看
[root@server1 cgroup]# mount -t cgroup ###即行cgroup工作目录的查看
在/sys/mfs/cgroup/cpu下进行子系统的建立
[root@server1 cpu]# mkdir x1
[root@server1 cpu]# cd x1/
[root@server1 x1]# ls
可以看到子系统继承了父级进程
进行cpu限额的查看
[root@server1 x1]# cat cpu.cfs_period_us ###进行cpu总格的查看
[root@server1 x1]# cat cpu.cfs_quota_us ###进行cpu限额的查看,-1表示没有限制
在cpu没有限制的情况下,使用dd命令进行测试,再进行cpu状态的查看
[root@server1 x1]# dd if=/dev/zero of=/dev/null &
[root@server1 x1]# top ###进行cpu状态的查看
我们可以看到在没有限制的情况下,cpu的使用率达到了接近100%,在实际生产环境中是
不允许的,因此我们可以通过cgroup来进行cpu限额的管理
我们可以进行如下操作:
进行cpu的限额
[root@server1 x1]# echo 20000 > cpu.cfs_quota_us ###进行对cpu的限额
[root@server1 x1]# cat cpu.cfs_quota_us
将所限制进行的pid加入tasks中
[root@server1 x1]# echo 1305 > tasks
[root@server1 x1]# cat tasks
使用top命令进行查看
[root@server1 x1]# top
通过查看cpu的状态发现dd命令下的进程cpu使用率已经控制在20%左右,达到了实验要求。
除了cpu的限额外,我们还可以进行内存的限额。
在/sys/fs/cgroup/memory的目录下进行子系统的建立
[root@server1 memory]# mkdir x2
[root@server1 memory]# cd x2
[root@server1 x2]# ls
我们可以看到,同cpu中的相同,它同样继承了父级的工作文件
在没有进行设定的情况下,对内存的限制进行查看
[root@server1 x2]# cat memory.limit_in_bytes
我们可以看到,限制的数额非常大,因此也就是没有进行限制。
我们可以进行以下测试:
我们对/dev/shm目录下进行文件的写入
[root@server1 shm]# pwd
/dev/shm
[root@server1 shm]# dd if=/dev/zero of=bigfile bs=1M count=200
[root@server1 shm]# dd if=/dev/zero of=bigfile bs=1M count=400
[root@server1 shm]# free -m
我们可以看到,在没有限制的情况下,在不超过总内存的情况下是可以无无限制的
进行文件的写入。
在x2目录下,我们进行对使用的内存进行限制(我们设定为300M)
[root@server1 x2]# echo 314572800 > memory.limit_in_bytes
[root@server1 x2]# pwd
/sys/fs/cgroup/memory/x2
\
为了实验方便,我们进行之前bigfile文件的删除
[root@server1 shm]# rm -f bigfile
[root@server1 shm]# free -m
这里我们引入cgroup工具,libcgroup-tools.x86_64
进行软件的安装
[root@server1 shm]# yum search cgroup ###进行软件的搜寻
[root@server1 shm]# yum install -y libcgroup-tools.x86_64 ###进行软件的安装
在做了限制之后,我们进行测试
[root@server1 shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=200
[root@server1 shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=400
[root@server1 shm]# free -m
我们可以看出,虽然内存的限额起到了作用,我们可以看到我们写入了400M大小的文件,但是除了
300M之外,其余的都出现在swap分区里,这时我们不愿意看到的,因此,我们可以使用以下方法
进行解决。
在x2目录下,对swap分区文件的大小进行限制(注意的是,在swap分区设置的文件的大小为限制的内存和分区大小之和)
[root@server1 x2]# echo 314572800 > memory.memsw.limit_in_bytes ###进行swap分区的限额
[root@server1 x2]# cat memory.memsw.limit_in_bytes
进行之前文件的删除,便于后面的测试:
[root@server1 shm]# rm -f bigfile
[root@server1 shm]# free -m
进行测试:
[root@server1 shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=400
[root@server1 shm]# du -sh bigfile ###进行文件大小的查看
[root@server1 shm]# free -m
我们可以看到,swap分区中没有写入,因此实验成功。
在容器中进行cpu的限额
[root@server1 ~]# docker run -it --name vm2 --cpu-period=100000 --cpu-quota=20000 ubuntu
root@33c8e88bc4dd:/# dd if=/dev/zero of=/dev/null &
root@33c8e88bc4dd:/# top ###进行cpu情况的查看
对写入速度的限制:
[root@server1 ~]# docker run -it --rm --device-write-bps /dev/sda:30MB ubuntu ###进行写入速度的控制
root@e201b17ac97c:/# dd if=/dev/zero of=file bs=1M count=300 oflag=direct ###进行写入的测试
默认进入容器后,只享受普通用户的权限
[root@server1 ~]# docker run -it --name vm1 ubuntu bash ###进行容器的运行
root@86da440bf14c:/# ip addr show
root@86da440bf14c:/# ip addr add 172.17.0.100/24 dev eth0 ###进行网络的添加
设置特级运行的容器: --privileged=true
有时我们需要容器具有更多的权限,比如操作内核模块,控制swap分区,挂载usb磁盘,修改
mac地址等。
[root@server1 ~]# docker run -it --name vm3 --privileged=true ubuntu bash
root@6b8e0873e271:/# ip addr show
root@6b8e0873e271:/# ip addr add 172.17.0.100/24 dev eth0
root@6b8e0873e271:/# ip addr show
设置容器的黑白名单: --cop-add
--privileged=true的权限非常大,接近宿主机的权限,为了防止用户的滥用,需要增加
限制,只提供容器必须的权限,此时docker提供了权限黑白名单的机制,使用--cap-add
添加必要的权限,
[root@server1 ~]# docker run -it --name vm4 --cap-add=NET_ADMIN ubuntu bash
root@f9eacca196e4:/# ip addr show
root@f9eacca196e4:/# ip addr add 172.17.0.100/24 dev eth0
root@f9eacca196e4:/# ip addr show
docker安全加固的思路:
保证镜像的安全
使用安全的镜像基础
删除镜像中的setuid和setgid权限
启动docker的内容信任
最小安装原则
定期对镜像进行漏洞扫描,镜像安全扫描器:clair
容器使用非root用户运行