关于Docker安全的一点调研

一个课程作业的报告

DOCKER架构及组件

提到Docker的安全,那么首先就要从Docker的整个架构来入手。Docker是基于Client/Server模式来设计的,主要部分分为Docker Client、Docker Daemon、Docker Registry组成的。Docker Client为用户提供了很多操作的接口,主要功能是向Docker Daemon发送请求来获取服务。Docker Daemon 运行于宿主机上位客户端请求服务,类似一个服务器。Docker Registry是一个集中存储和分发镜像的地方,负责处理从Daemon发过来的请求。它们三者及其所依赖的组件如图所示。 在这里插入图片描述

DOCKER 安全威胁

Docker的安全威胁实际上和Docker的架构密切相关。构成整个Docker的各个组件都可以成为攻击的点。目前关于Docker的安全问题主要是围绕网络、容器、容器依赖的Linux内核、镜像。Docker的攻击面如下图所示。
在这里插入图片描述

镜像安全威胁

Docker运行的镜像是从仓库上面下载过来的。运行不安全的镜像会对整个系统造成很大的威胁。镜像安全问题主要包括两个部分:镜像自身安全威胁和镜像仓库安全威胁。
镜像自身安全威胁又可分为镜像缺陷和镜像中毒。简单说就是镜像存在漏洞这样的缺陷和镜像存在病毒等恶意软件。镜像缺陷指的是镜像在制作过程中都是基于一些基础镜像构建的,可能安装了很多不必要的库和依赖,而这些库中存在很多漏洞,从而导致了镜像存在可以被攻击者利用的缺陷。
镜像中毒指的是镜像被植入了后门或者病毒这类的恶意软件。有些恶意用户会在镜像中植入病毒或者后门上传到官方社区中。2018年6月,安全厂商Fortinet和Kromtech在Docker Hub上发现17个包含用于数字货币挖矿恶意程序的Docker镜像,而这些恶意镜像当时已有500万次的下载量。这种挖矿的镜像严重了损害了用户的利益。
镜像仓库安全威胁指的是仓库中的镜像被外部的攻击者恶意篡改。比如,私有镜像仓库由于配置不当而开启了2357端口,将会导致私有仓库暴露在公网中,攻击者可以直接访问私有仓库篡改镜像内容,破坏镜像的完整性,造成镜像安全隐患。

网络安全威胁

网络安全威胁主要是针对Docker各个组件的通信进行攻击。这也是所有互联网信息系统所面临的重要风险。Docker提供桥接网络、MacVLAN、Overlay等多种组网方式。默认使用的是网桥模式,在宿主机上创建一个虚拟网桥docker0,在各个网络接口间自动地进行包转发,每创建一个新的容器,就增加一个虚拟网络接口,并将该网络接口连接到网桥Docker0。然而默认情况下,虚拟网桥没有对转发的数据包进行过滤,容器间也没有网络安全管理机制,无法对同一宿主机内各容器之间的网络访问权限进行限制。所以攻击者可以利用某个容器对宿主机内的其他容器进行ARP欺骗、嗅探和广播风暴,导致信息泄露和影响网络运行等安全隐患。
另外一种攻击模式是拒绝服务攻击,简称DoS攻击。这里又可分为容器间的DoS攻击和容器外的DoS攻击。容器间的DoS攻击指的是攻击者本身可以操纵某容器,利用该容器向其他容器发起DoS攻击,降低其他容器的网络数据处理能力。容器外的DoS攻击是基于同一台宿主机所有容器共享宿主机的物理网卡资源的前提来发动的。攻击者通过使用大量受控主机组成的僵尸网络向某个宿主机发送大量数据包进行DoS攻击,有可能占满宿主机的网络带宽资源,造成宿主机和其他容器的拒绝服务。

容器安全威胁

容器存在的安全问题可以分为Docker代码漏洞、配置不当、拒绝服务攻击这些问题。
Docker本身也是一种应用软件。这样就意味着Docker本身在代码实现上会存在缺陷。在CVE官网上搜索关于Docker历史版本的漏洞有81个,而这些漏洞很有可能会被攻击者利用。
此外,容器存在一类配置不当引起的安全问题。例如,当容器启动时,给定权能-net=host时,Docker不会将容器放入单独的网络命名空间中,因此,它使容器能够完全访问主机的网络堆栈;配置容器重启策略时,如果不限制重启次数,可能会被恶意反复重启,导致耗尽计算资源,形成DoS攻击。除了计算资源会被恶意利用,攻击者针对存储资源,利用CGroups没有对AUFS文件系统限制单个容器的存储资源的特性,向宿主机的某个容器的AUFS文件系统不断地进行写文件操作,可能会导致宿主机存储设备空间不足,导致无法满足其他容器的存储需求。不同于上一小节的DoS攻击,这里的DoS攻击不是通过网络来实施的,但目的是一样的,都是占用主机资源,导致其他容器无法正常工作。

内核安全威胁

从Docker容器是基于和宿主机共享内核机制构建的,而目前Linux内核层面提供的支撑机制还不够完善。因此,攻击者可以基于容器和操作系统共享内核这一特性,利用内核存在的漏洞,进行提权,从而可以对宿主机和宿主机其他容器进行访问。在Black Hat USA 2019会议上,就提到了若干基于这种方式实施的攻击,例如CVE-2016-5195 脏牛漏洞。这个漏洞利用linux内核函数get_user_page在处理Copy-on-Write的时候产生竞态条件,导致可以向只读内存区域写数据的机会,攻击者可以利用这点进一步修改su或者passwd文件获得root权限。
此外,由于处理器出现Meltdown、Spectre等漏洞,导致侧信道攻击这几年大行其道。这些漏洞都是基于共享这一特性进行攻击。而容器存在很多共享的情况。基于硬件的侧信道攻击如Meltdown、Spectre,不仅可以泄露底层内核的信息,还可以泄露运行在同一主机上的其他信息。

DOCKER安全防御

上一章节分析了Docker存在的安全问题,这一节将介绍业界基于这些安全问题的解决方案。

镜像安全防御

保护镜像自身安全的策略有镜像安全扫描和镜像完整性度量。镜像安全扫描主要是在从公共镜像仓库获取镜像时对其进行安全检查,防止存在安全隐患的镜像运行。这类工具有Docker Security Scanning、Clair、Anchore、Trivy、Auqua等等。
镜像完整性度量主要是保护镜像的完整性,即保护镜像不被恶意篡改。这类技术基于可信计算中的TPM来实现的。
针对镜像仓库的防御,主要是保护镜像从镜像仓库push或者pull的过程的安全。这里的防御是利用Docker的内容信任(Content Trust)机制实现的。内容信任机制的主要功能是对从Docker 仓库传送过来的镜像进行完整性和发布者真实性校验,并对镜像进行数字签名。内容信任机制开启后,只有已签名的基础镜像才能通过docker build进行镜像构建。

容器安全防御

与传统的虚拟化不同,容器架构中没有Hypervisor层,需要依赖操作系统内核来对容器进行管理。因此,容器间共享内核导致了容器间产生了诸多的安全问题。针对容器的防御机制也是最多的,主要集中于隔离技术、容器运行时监控、容器安全审计这几方面,下面将依次展开。
容器的隔离技术是通过linux内核的Namespace机制实现容器与宿主机之间、容器与容器之间资源的相对独立。通过为容器创建自己的命名空间,保证容器中进程的运行不会影响到其他容器或宿主机的进程。此外,Docker使用Cgroup来对宿主机的不同容器进行资源限制,包括CPU、内存、I/O等物理资源进行均衡化配置,防止单个容器耗尽宿主机所有资源,以防拒绝服务攻击。然而,Cgroup不是很完善,没有对磁盘存储资源进行限制。对此,Docker也采用-storage-opt来限制磁盘存储,但是这种方式仅支持Device Mapper系统,难以针对Docker容器实现基于进程或目录的磁盘限额。针对这个问题,Docker可以采取虚拟文件系统、选择XFS等针对目录进行磁盘使用量限制的文件系统等方法。
容器运行时监控是指在容器运行时,监控系统的各项指标,遇到安全威胁及时预警并响应。这类工具有docker stats、cAdvisor、DataDog、Sensu等等。最常见的是原生的Docker stats命令和谷歌的cAdvisor。
容器安全审计指的是对容器的各类行为进行记录,对日志进行审查追踪安全行为的过程。对于Docker容器而言,不仅要对主机Linux文件系统进行审计,也要对Docker守护进程进行审计。但是系统不会默认对Docker守护进程进行审计,因此,Docker提供了auditctl命令来添加审计规则。

网络安全防御

网络安全防御这部分工作主要是为了防止基于网络的攻击,比如中间人攻击和ARP欺骗。Docker为了应对这类攻击设立了网络访问控制规则。其将容器放在不同的桥接网络中。当Dokcer使用Docker network create命令创建新的桥接网络时,会在iptables中的DOCKER-ISOLATION新增DROP丢弃规则,阻断与其他网络之间的通信流量,实现容器网络之间隔离的目的。同时也可修改白名单规则来按需设置网络访问控制,即根据实际需要在iptables中添加访问控制策略,以最小化策略减小攻击面。
然而在大规模容器云环境中,存在频繁的动态变化,手动配置规则显然是不现实的。因此,可以通过微分段机制来实现面向容器云环境的容器防火墙。微分段(Micro-Segmentation)是一种细粒度的网络隔离机制,与传统的以网络地址微基本单位的网络分段机制不同,微分段可以以单个容器、同网段容器、容器应用为粒度实现分段隔 离,并通过容器防火墙实现微分段间的网络访问控制。
此外,容器间的流量限制可以防止潜在的网络DoS攻击。流量限制有两种,一种是完全禁止容器间通信,一般应用于特定场景。一种是限制流量,其通过linux的流量控制模块traffic controller对容器网络流量进行限制。这个模块的原理是简历数据包队列并制定发送规则,实现流量限制与调度功能。

内核安全防御

由于容器技术很依赖linux内核,所以一旦linux内核出了什么毛病,容器也会跟着出问题。而针对内核保护的研究实际上已经比较成熟,但内核爆出的漏洞也逐年增长,这是一个攻防博弈的过程。内核防御机制有权能机制(Capabilities)、强制访问控制、Seccomp机制、Grsecurity/PAX等。
权能机制是按照最小化权限原则来限制容器的能力。权限被细分为37个小权能,只有具有某种权能才能执行某种特定任务。这种机制可以防止容器的权限滥用。
强制访问控制相对于自主访问控制可以提供更严格的保护,用户不能改变他们的安全级别和对象的安全属性,只能依据预先设定的安全等级来做决策。这种机制已经在内核安全模块中实现了,比如SELinux、AppArmor等。
Seccomp机制是Linux内核提供的安全特性,可以实现沙盒机制,以白名单/黑名单的方式限制进程能够进行的系统调用范围。
Grsecurity/PAX是一个linux内核的加固补丁,让linux内核的内存页受限于最小权限原则。

总结与思考

本文对Docker容器技术产生的安全问题以及业内解决方案做了调研,总结的思维导图如下图所示。可以发现,攻击者的攻击面几乎在整个系统运行的每个步骤都存在,攻击者只要攻破某个点就能实现目的。防御者只要阻止一个完整的攻击的某个步骤就能防御住。攻击有攻击的优势,防御也有防御的优势,所以这也是一个攻防博弈的过程。此外,我们也可以发现,许多安全问题是因为存在共享导致的。共享虽然提供了便利,但同时也引入了安全问题。容器技术相对于传统虚拟化,更依赖于Linux底层,这也导致了Linux内核出现的问题也会带给容器。这也就是说,底层技术的安全性得到保障,才能保障上册的安全。或者可以降低容器和linux内核的依赖关系,二者相互独立,也能避免很多安全问题。实际上,正因为容器技术依赖Linux内核,丢掉了Hypervisor层,才能让容器成为一个轻量级的技术。由此可见,容器的优点可能也导致了它的缺点。做安全,实际上也是一个不断trade-off的过程,什么样的情景需要安全,什么样的情景需要性能或者操作便捷。一个系统不能十全十美,但可以是最适合某个场景。

参考文献
[1] 鲁涛, 陈杰, 史军. Docker安全性研究%Research of Docker Security[J]. 计算机技术与发展, 2018, 028(006):115-120.
[2] Yasrab, Robail. “Mitigating docker security issues.” arXiv preprint arXiv:1804.05039 (2018).
[3] Bui, Thanh. “Analysis of docker security.” arXiv preprint arXiv:1501.02967 (2015).
[4] 余金键, 贾川, and 蒲东. “Docker 安全性研究综述 A Review of Docker Security Research.” Computer Science and Application 9.05 (2019): 926.
[5] 狴犴安全团队.Docker容器安全性分析[EB/OL].https://www.freebuf.com/articles/system/221319.html,2019-12-15.
[6] 王婷婷,徐国坤.Docker安全风险,原来有这么多[EB/OL].https://cloud.tencent.com/developer/news/243123,2018-06-14.
[7] The MITRE Corporation. Common Vulnerabilities and Exposures[EB/OL].https://cve.mitre.org/,2020-3-20.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章