Docker容器的安全性,很大程度依赖于linux系统自身,评估Docker的安全性时,主要考虑以下几个方面:
1linux内核的命名空间机制提供的容器隔离安全
2linux控制组机制对容器资源的控制能力安全
3linux内核的能力机制带来的操作权限安全
4docker程序本身的抗攻击性
5其它安全增强机制对容器安全性的影响
命名空间隔离的安全
1当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间,docker提供了最基础也是最直接的隔离。
2和虚拟机方式相比,通过linux namespace来实现的隔离不是那么彻底。
3容器只是运行在宿主机的一种特殊进程,多个容器之间使用的还是同一个宿主机的操作系统内核。
4在linux内核中,有很多资源和对象是不能被namespace化的,比如:时间
例:
运行容器,查看容器pid号
可以查看到,通过namespace(ns)为该容器提供了六种基本的隔离
控制组资源控制的安全
1当docker run启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合。
2linux Cgroup提供了很多有用的特性,确保各容器可以公平的分享主机的内存,cpu,磁盘IO等资源
确保当发生在容器内的资源压力不会影响到本地主机系统和其它容器,它在防止拒绝服务(DDos)方面必不可少。
内核能力机制
能力机制是linux内核一个强大的特性,可以提供细粒度的权限访问控制。
大部分情况下,容器并不需要真正的root权限,容器只需要少数的能力即可。
默认情况下,docker采用白名单机制,禁用必须功能之外的其它权限。
docker服务端防护
1使用docker容器的核心是docker服务端,确保只有可信的用户才能访问到docker服务
2将容器的root用户映射到本地主机的非root用户,减轻容器和主机之间因权限提升而引起的安全问题。
3允许docker服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程只允许在特定范围内进行操作。
容器资源控制
linux Cgroup的全称是linux Control Group
是限制一个进程可以使用的资源的上限,包括cpu,内存,磁盘,网络带宽等.
对进程进行优先级设置,以及将进程挂起和恢复等操作
linux Cgroup给用户暴露出来的操作接口是文件系统。
它以文件和目录的方式组织在操作系统的/sys/fs/cgroup路径下
执行以下命令可以查看
mount -t cgroup
限制cpu:
cpu限额
举例:
docker run -it --cpu-period=100000 --cpu-quota=20000 ubantu
cpu_period 和cpu_quota这两个参数需要组合使用,用来限制进程在长度为cpu_period的一段时间内,只能内分配到总量为cpu_quota的cpu时间,以上设置表示20%的cpu时间。
进入到该目录,可以查看到值被改变:
可以安装cgroup的工具进行一些设置:
安装后会有如下的设置命令:
比如默认cpu的优先级都是1024
该目录下会自动复制父级目录下的所有参数:
默认的优先级为1024:
设置优先级为100:
让dd的指令用在x1的控制器下面:
此时优先级变为原来的十分之一
相当于把此进程放置在x1的tasks下:
删除x1控制器:
限制内存:
容器可用内存包括两个部分:物理内存和swap交换分区
例:docker run -it --memory 200M --memmory-swap=200M ubantu
–memory设置内存使用限额
–memory-swap设置swap交换分区限额
创建内存控制器:
创建名为x2的控制器:
默认内存无限制
设置限制:
将内存限制为200MB(换算大小)
测试:
dev/shm默认占总内存的一半:
用以上dd命令运行完则结束,所以可以利用控制器操作(保存下来):
之前将内存限制为200MB,所以利用x2控制器创建100 200内存的大小成功,创建300MB的时候依然会成功,只不过物理内存使用了200MB,多出来的100MB内存被放置到了swap分区中:
释放掉内存:
将swap分区也设置为200MB:
此时创建300MB内存失败:
测试完释放掉内存:
注意用以下命令创建时,swap限制为200MB,但是显示为2G,实际上容器的内存控制已经生效
原因资源隔离不彻底,proc没有被隔离,所以此时显示的是宿主机的内存
进入到该容器的目录,可以查看到已经生效:
可以查看到此目录就是该容器:
容器资源控制
Block io限制
例:
docker run -it --device-write-bps /dev/sda:30MB ubantu
–device-write-bps限制写设备的bps
例如吞吐量,读的量:
过滤docker中与bps读写有关的参数:
设置为10MB,可以发现为10.5MB
不设置直连参数则不会限制,在此达到2.3GB/s
docker安全加固
利用LXCFS增强docker容器隔离性和资源可见性
打入后台:
此时在该目录下生成:
在运行容器时,将这些隔离信息直接挂载在/proc/内,此时隔离生效
例如:此时容器内的swap不在是宿主机的信息
安全加固续
1设置特权级运行的容器 --privileged=true
有时候我们需要容器具备更多的权限,比如操作内核模块,控制swap交换分区,挂载usb磁盘,修改mac地址等
打开该参数则该容器和宿主机的权限接近,权限特别大:
此时可以在容器内对宿主机的硬盘进行设置(权限过大):
不加该参数则没有:
–privileged=true的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限,此时docker提供了权限白名单的机制,使用–cap-add添加必要的权限。
手册查看地址
http://man7.org/linux/man-pages/man7/capabilities.7.html
例如添加控制网络的模块: