【报告解读系列二】容器环境脆弱性分析

容器技术基于容器主机操作系统的内核,通过对CPU、内存和文件系统等资源的隔离、划分和控制,实现进程之间透明的资源使用。因此,容器主机的安全性对整个容器环境的安全有着重要的影响。

1.   概述

最近有很多关于容器安全性的讨论,尤其是当在生产环境中部署使用容器的时候。容器环境所面临的大多数安全威胁,和非容器环境存在的威胁在本质上基本是一致的。只不过基于容器的某些特性,出现了一些新的场景和攻击面。

那么对于容器环境来说,都有什么样的安全威胁呢?总结起来可以从以下三个方面来进行简单划分。

(1)基础设施/运行环境是否是安全的。容器技术是基于容器主机操作系统内核实现的资源隔离,相比较vm来讲,容器对主机的操作系统有了更多的权限,因此诸如OS的安全补丁、API、权限、认证、隔离等问题对容器的安全性有着很大的影响。

(2)容器的镜像是否是安全的。关于容器镜像的安全性,比如像镜像的漏洞、恶意程序等问题,之前的文章《容器镜像的脆弱性分析》已经进行了比较全面的分析,这里就不再过多介绍了。

(3)容器运行时是否是安全的。比如容器中是否运行了非法的进程、是否遭到了DDoS攻击、是否发生了逃逸等。

2. 容器环境脆弱性分析

本小节将从三个方面,简单介绍容器基础设施/运行环境的安全性。

2.1 容器逃逸

容器逃逸攻击与虚拟机逃逸攻击相似,利用虚拟化软件存在的漏洞,通过容器获取主机权限入侵主机,以达到攻击主机的目的。这里通过容器入侵主机的逃逸,一方面包括在容器中获取到更多的主机权限;另一方面包括不完善的隔离存储。

具体地,一些PoC工具,如Shocker,可展示如何从Docker容器逃逸并读取到主机某个目录的文件内容。Shocker攻击的关键是执行了系统调用open_by_handle_at函数,Linux手册中特别提到调用open_by_handle_at函数需要具备CAP_DAC_READ_SEARCH能力,而Docker1.0版本对Capability使用黑名单管理策略,并且没有限制CAP_DAC_READ_SEARCH能力,因而引发了容器逃逸的风险。

2.2 容器网络

Docker默认采用预设的桥接网络驱动,一个docker0的网桥将所有容器连接该网桥,docker0网桥扮演着路由和NAT的角色,容器间通信都会经过容器主机。

默认情况下,这种桥接采用黑名单的方式,即同一主机上的容器之间是允许所有通信的,用户根据业务需求添加访问控制规则。如果各容器之间没有防火墙保护,攻击者就可以利用主机内部网络进行容器间的ARP欺骗、嗅探、广播风暴等攻击。

2.3 拒绝服务

默认情况下容器可以使用主机上的所有资源,如果某个容器以独占方式访问或消耗主机的大量资源,则该主机上的其它容器就会因为缺乏资源而无法正常运行。

DoS攻击可针对任何资源,例如计算资源、存储资源、网络资源等,下面分别以这三种资源进行说明。

(1)计算资源。Fork Bomb 是一个很典型的计算型DoS攻击场景,主机内核正常情况下只能支持一定数量的进程,如果某个容器内的进程组新建过多进程,消耗了主机上的所有进程资源,那其它的容器就没有资源来创建新的进程,甚至会危及主机的正常工作。

Fork Bomb也是自2015年到现在Docker社区一直讨论的问题,目前最好的方法是限制内存的使用(–kernel-memory=#M),但是,当在与加密文件一起使用时可能会偶尔出现问题。

(2)存储资源。在容器技术的实现中,通过mount命名空间实现了文件系统的隔离。但是文件系统隔离仅仅是一个非常基本的要求。不建议使用AUFS做存储驱动,虽然AUFS创建出的容器文件系统互相隔离,但是在存储空间方面却没有任何限制。换言之,一个容器如果不断写文件,将会写满存储介质,其它容器将无法执行写操作,导致拒绝服务攻击。

(3)网络资源。DoS攻击层出不穷,容器内网络带宽耗尽也是其中一种,攻击者使用大量的受控主机向被攻击目标(容器)发送大量的网络数据包,以占满容器的网络宽带,并消耗容器主机的网络数据处理能力,达到拒绝服务的目的。

3. CIS Benchmark

CIS针对Docker和Kubernetes,分别提出了安全基准文档,用于对Docker和Kubernetes运行环境进行安全审计。

下面本文将通过两个例子,介绍在默认情况下容器环境的安全风险。

3.1 Docker默认配置风险

宿主机采用Ubuntu 16.04.4 LTS(4.4.0-116-generic,x86_64)。

参照Docker官方的安装文档https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-up-the-repository,安装Docker。版本如下图所示。

使用docker-bench-security(https://github.com/docker/docker-bench-security)对其进行检查。

检查结果如下表所示:

序号 检查内容 检查总数 INFO/NOTE PASS WARN
1 Host Configuration 13 9 0 4
2 Docker daemon configuration 18 3 8 7
3 Docker daemon configuration files 20 16 4 0
4 Container Images and Build File 11 8 2 1
5 Container Runtime 0 0 0 0
6 Docker Security Operations 2 2 0 0
7 Docker Swarm Configuration 10 0 10 0
总计 74 38 24 12

 

从上表的结果中可以看出,检查结果总计可以划分为三类:

(1)通知提示(INFO/NOTE)。比如针对2.6的检查,要求确保配置了对Docker daemon访问的TLS认证。而测试环境默认启动的Docker daemon是没有启动TCP监听服务的,因此,对于该条目,设置为通知提示。

[INFO] 2.6  – Ensure TLS authentication for Docker daemon is configured

[INFO]      * Docker daemon not listening on TCP

 

(2)通过(PASS)。比如针对2.2的检查,要求确保Docker日志级别设置为“INFO”,Docker默认的日志级别符合该要求,因此检查结果为PASS。

[PASS] 2.2  – Ensure the logging level is set to ‘INFO’

 

(3)警告(WARN)。比如针对2.1的检查,要求连接在默认网桥上Docker实例之间的网络流量,是要限制其之间的网络访问。而Docker的默认配置,是允许所有实例通信的,因此该条目提示为告警级别。

[WARN] 2.1  – Ensure network traffic is restricted between containers on the default bridge

 

由于在CIS的标准中,第5章是针对Container Runtime的,在主机上没有容器实例运行时,这一大项的检测是跳过的,因此所有的数据都是0。这种情况下,针对全部的74项检测,除去通知级别的38项,剩下的36项检测中,告警的有12项,比例达到了33%。主要包括以下内容。

(1)主机配置检查

[WARN] 1.1  – Ensure a separate partition for containers has been created

确保为存储Docker文件,创建一个单独的分区(逻辑卷)

[WARN] 1.5  – Ensure auditing is configured for the Docker daemon

确保Docker daemon要将审计的能力进行配置,在/etc/audit/audit.rules文件中添加一条审计规则:–w /usr/bin/docker –k docker。

[WARN] 1.6  – Ensure auditing is configured for Docker files and directories – /var/lib/docker

确保对docker文件和目录进行审计,在/etc/audit/audit.rules文件中添加一条审计规则:–w /var/lib/docker –k docker。

[WARN] 1.7  – Ensure auditing is configured for Docker files and directories – /etc/docker

同样是对Docker文件和目录进行审计的检查,在/etc/audit/audit.rules文件中添加一条审计规则:–w /etc/docker –k docker。

(2)Docker daemon配置检查

[WARN] 2.1  – Ensure network traffic is restricted between containers on the default bridge

确保容器间在默认的桥接网络上,采用白名单方式实现通信。将docker daemon启动参数(/etc/docker/daemon.json)icc设置为false。

[WARN] 2.8  – Enable user namespace support

确保在Docker守护进程中启用用户命名空间,将启动参数userns-remap设置为default。

[WARN] 2.11  – Ensure that authorization for Docker client commands is enabled

确保启用Docker客户端命令的认证授权,Docker默认是没有对客户端命令进行授权管理的功能,这里需要借助第三方插件实现。Docker官方给出的插件主要包括Casbin AuthZ Plugin、HBM plugin和Twistlock AuthZ Broker这三种。可以采用以下命令运行插件:

# docker run -d -v /var/lib/authz-broker/policy.json:/var/lib/authz-broker/policy.json -v /run/docker/plugins/:/run/docker/plugins twistlock/authz-broker

然后在docker daemon启动参数(/etc/docker/daemon.json)中的authorization-plugins设置为authz-broker。

[WARN] 2.12  – Ensure centralized and remote logging is configured

确保配置了集中式和远程的日志记录。在docker daemon启动参数(/etc/docker/daemon.json)中的log-driver设置为syslog,log-opts设置为{

“syslog-address” : ” = tcp://192.x.x.x”。

[WARN] 2.14  – Ensure live restore is Enabled

确保容器实例可以支持无守护进程运行,也就是说,docker daemon在关闭或者恢复时,不会停止容器,并且可以在daemon重新启动后重新接管。

将docker daemon启动参数(/etc/docker/daemon.json)中的live-restore设置为true。

[WARN] 2.15  – Ensure Userland Proxy is Disabled

Docker引擎提供了两种将主机端口转发到容器端口的方式:DNAT和Userland Proxy。默认情况下,Userland Proxy已启用。

将docker daemon启动参数(/etc/docker/daemon.json)中的userland-proxy设置为false。

[WARN] 2.18  – Ensure containers are restricted from acquiring new privileges

确保限制容器获取新的权限。

将docker daemon启动参数(/etc/docker/daemon.json)中的no-new-privileges设置为true。

(4)Docker镜像和构建文件检查

[WARN] 4.5  – Ensure Content trust for Docker is Enabled

确保启用了Docker的内容信任,默认情况下,内容信任是被禁止的。可以通过修改环境变量来进行设置,export DOCKER_CONTENT_TRUST=1。

 

考虑到这里的检测,并未覆盖到第5章中Container Runtime相关的内容,因此在测试环境中,我们运行一个容器,再来进行一下测试,结果如下表所示。

# docker run -d -p 80:80 –read-only -v $(pwd)/nginx-cache:/var/cache/nginx -v $(pwd)/nginx-pid:/var/run nginx(https://hub.docker.com/_/nginx/,以只读模式运行nginx)

序号 检查内容 检查总数 INFO/NOTE PASS WARN
1 Host Configuration 13 9 0 4
2 Docker daemon configuration 18 3 8 7
3 Docker daemon configuration files 20 16 4 0
4 Container Images and Build File 11 8 0 3
5 Container Runtime 31 6 16 9
6 Docker Security Operations 2 2 0 0
7 Docker Swarm Configuration 10 0 10 0
总计 105 44 38 23

 

对比这两个结果可以发现,1/2/3/6/7这五部分的结果是完全一样的,第四部分原来的2个PASS的内容变成了WARN,第五部分的内容进行了检测。至于第五部分的内容,涉及到运行时,不同的容器可能结果会不同,因此这里不再详细分析。第四部分由PASS转为WARN的2项是:

[WARN] 4.1  – Ensure a user for the container has been created

[WARN]      * Running as root: pensive_burnell

默认情况下,容器以root权限运行,并且以容器中的用户root身份运行,应确保容器镜像的Dockerfile包含USER指令,或者在USER指令前通过useradd命令添加特定用户。

[WARN] 4.6  – Ensure HEALTHCHECK instructions have been added to the container image

[WARN]      * No Healthcheck found: [nginx:latest]

确保将HEALTHCHECK指令添加到Docker镜像中,进而能够对运行的容器实例进行运行状况检查。默认情况下,HEALTHCHECK未进行设置。

3.2 Kubernetes默认配置风险

采用两节点使用Kubeadm部署Kubernetes v1.12.1。

Master节点检测结果如下表所示。

序号 检查内容 检查总数 INFO/NOTE PASS WARN
1 API Server 34 0 8 26
2 Scheduler 1 0 0 1
3 Controller Manager 6 0 4 2
4 Configuration Files 12 2 9 1
5 etcd 8 0 6 2
6 General Security Primitives 8 8 0 0
总计 69 10 27 32

 

Worker节点检测结果如下表所示。

序号 检查内容 检查总数 INFO/NOTE PASS WARN
1 Kubelet 13 0 3 10
2 Configuration Files 6 2 4 0
总计 19 2 7 10

 

由于篇幅的限制,这里就不再对结果进行详细分析了。

 

 

点击此链接,下载《2018绿盟科技容器安全技术报告》完整版。

容器安全的全球威胁分析

 

 

添加好友,备注“进群”,加入容器安全技术交流群,通过后会拉您入群。

 

绿盟科技星云实验室致力于云计算安全,研究方向主要包括:公有云/政务云/行业云/私有云等云计算系统的相关安全问题以及安全解决方案的研究、SDN/NFV等虚拟化网络安全问题的研究、Docker/Kubernetes/Service Mesh/Serverless等云原生相关安全问题及安全解决方案研究、5G在接入安全、切片网络安全、隐私保护等方面的安全问题以及安全解决方案研究、边缘计算在计算、存储、网络等方面的安全问题以及安全解决方案研究等新技术和新领域。在课题研究上,承担并完成了多个国家、省、市以及行业重点单位的创新研究课题。

 

Spread the word. Share this post!

Meet The Author

Leave Comment