APP下载

Docker容器逃逸防护技术研究

2022-08-08张新有栗晓晗

信息安全研究 2022年8期
关键词:访问控制内核客体

胥 柯 张新有 栗晓晗

(西南交通大学计算机与人工智能学院 成都 611756)

随着容器技术的持续升温,其安全问题也备受关注.比如镜像安全问题[1]、容器逃逸、拒绝服务攻击[2]等.Docker的使用愈发广泛,容器逃逸安全加固手段却十分匮乏,若不对其安全逃逸问题加以重视,一旦发生逃逸将会造成严重后果[3].

本文从访问控制的角度出发,限制用户的操作权限,提高容器间的隔离性,可切实缩小逃逸后攻击者的访问权限,降低其带来的危害.但传统的强制访问控制(mandatory access control, MAC)系统主/客体的安全等级可能存在难确立且含有过多主观因素的干扰.本文结合模糊聚类分析与风险矩阵分析,采用客观真实的数据对主客体进行安全等级划分.并与MAC相结合,提出一种针对Docker容器逃逸加固的多级模糊安全访问模型CFMAC,并利用LSM技术进行实现.

1 研究现状

Docker孵化至今,经历了8年的发展.随着其广泛应用,安全问题也开始引人关注,国内外研究人员开始致力于Docker安全研究,分析它的攻击面以及研究安全加固方案.

王娟等人[4]针对非授权通信等问题,提出使用可信计算提高容器的安全性.主要使用信任链与完整性度量,通过构造容器内部到文件的完整信任链,设计实现了安全性更高的Docker容器.该方法主要针对单一容器,保证镜像等文件不被篡改,但不适应集群环境.马小淋[5]提出一种基于负载特征的容器云弹性伸缩策略,减少了暂行性负载增减造成的伸缩抖动.李平平等人[6]提出基于LSM的Docker访问控制机制,为Docker容器逃逸防护提供了可能,但是提出的方案也未结合实际的生产环境,不能应用至集群.

Red Hat的Docker安全的总负责人Walsh[7]提出可通过更加细粒度的权限分配和访问控制系统对Docker容器进行加固.陈莉君等人[8]认为容器的部分安全问题来自于隔离性的不足,采用分层设计实现容器资源隔离系统,具有良好的性能.但是并未对宿主机关键文件以及容器共享出的文件进行隔离,一旦逃逸发生就会对宿主机关键文件进行修改,危及宿主机和容器的安全,严重时可能导致服务失效.

也不乏一些前辈从性能资源监控的角度出发,设计监控警报系统,让安全管理员及时作出应对措施,时至今日,这些监控技术已经渐进成熟.Dhakate等人[9]认为为了自动化云服务的整个测试过程,应该有一种精确的实现方式,使其在底层基础设施更改期间更加稳定和可接受,于是设计了一种集监控与智能警报于一体的轻量级分布式云平台监控系统,并提出在未来实现自动修复的可能.Salvatore[10]认为监控系统应呈现给用户简洁、智能、友好的交互窗口,尽可能降低用户的操作复杂度,同时监控系统也应在分布式的大环境下适应容器生命周期的快速变更.

目前,市场上存在一些监控软件,例如DataDog,Grafana,Prometheus等[11],这些大都提供再开发的功能,使用难度也参差不齐,都是对内存、流量、CPU占用率等数据进行监控,缺乏对Docker容器逃逸等攻击的针对性监控.

上述对Docker的安全性分析与安全加固研究,都在一定程度上从Docker易受攻击的角度,包括仓库镜像与远程连接、拒绝服务攻击、权限分配等,提升Docker的安全性.但是针对Docker容器逃逸的防护措施匮乏,这是因为容器逃逸方式多变、诱因各异所致.本文从限制容器逃逸后的访问权限出发与强制访问控制相结合,尽可能保证核心文件的安全,从而达到提升Docker容器安全性的目的.

2 相关技术

2.1 MAC

MAC系统主要包括主体、客体与访问控制策略[6].客体一般为需要保护的对象或者需要进行访问控制的对象,而主体即为向客体发起访问的对象,通常来说为进程.在CFMAC模型中,主体即为容器.主体和客体各自具有独立的安全属性,且安全属性的设置权限为管理员所持有,不能随意更改.无论主体对客体的何种操作都将必须执行访问控制策略,判断操作是否允许[12].

MAC通过无法避免的存取限制来阻止直接或间接的非法入侵[13].有许多安全敏感的系统,如军事部门、政府、银行等,这些部门的资源通常按照安全级别进行分区,而整个系统使用严格的MAC来保持数据的机密性和完整性.Bell-Lapadula模型是David Bell和Leonard LaPadula为模仿军事安全政策而提出的一种计算机安全模型,在高安全性系统中得到了广泛的应用和研究,如SELinux和数据库安全系统.

2.2 命名空间

命名空间(Namespaces)是Linux对全局系统资源的一种封装及安全隔离方法.通过Namespace进程只能看到与自己相关的资源,进程之间感觉不到对方的存在.具体的实现方式是把1个或多个进程的相关资源指定在同一个Namespace中.

当进行Linux应用开发时,对需要的Namespace类型进行声明,就可以实现对应的资源类型隔离.Namespace是Linux容器技术的基础.Linux内核支持6种不同的Namespace,如表1所示:

表1 Linux Namespace

由表1可知PID,IPC,Network等资源属于某个特定的Namespace,不再是全局变量,Namespace之间相互独立.Namespace定义请参见文献[14].1个Namespace可以产生多个子Namespace.运用Kernel中的Namespace机制和Cgroup机制实现轻量级的虚拟,多个虚拟容器共用宿主机的Kernel,彼此之间资源隔离.Docker也正是依赖于此[16].

3 总体设计

使用模糊聚类对MAC的安全等级进行划分,减少主观因素的影响,使分级更加规范科学.针对Docker的实际应用情况,改良传统MAC模型,对Docker进行安全加固,从而降低逃逸后攻击者对系统带来的危害.

3.1 主客体及安全等级划分

CFMAC模型属于强制访问控制的范畴,对于访问控制系统设计、访问控制的3个要素(主体、客体、控制策略)必须有清楚的定义.在主体划分方面,定义容器Ci(1≤i≤v,i为正整数,v为当前宿主机存在的容器个数)为主体,包含容器内所有子进程;在客体划分方面,将容器将要访问的文件定义为客体,根据文件的直接归属不同,主要分为3类.分别定义为:宿主机系统关键路径文件HF;Docker容器i与j共享数据卷文件SF{i,j}(1≤i≠j≤v,i,j为正整数,v为当前宿主机存在的容器个数),也即在创建共享数据卷容器时所使用的参数;Docker容器Ci的直接相关文件即容器创建后overlay2下的容器运行所依赖文件CFi.

目标将主、客体分为3类.设待分类样本集合为X={x1,x2,…,xi,…,xn},n为样本个数,本文系统将上述主、客体设置为样本集合.每个独立的样本包含m个统计指标,xik表示第i个样本的第k个指标.统计指标反映最终的准确程度,是取得合理聚类的首要条件.依据风险等级评级方法中的风险矩阵分析法,RK=L·S,其中RK是风险值,是事故发生的可能性与事件后果严重性的综合指标,L是事故发生的可能性,S是事故后果的严重性,RK值越大,说明该文件被攻击者访问对系统危险性越大,相对应的安全等级也应设置较高[17].同时参照Docker容器逃逸的实际应用场景,现选取2个具有实际意义的指标,将事故发生的可能性L设置为引发容器安全问题的安全漏洞个数,用P表示,将事故后果的严重性S设置为安全问题带来的直接经济损失,用M(元)表示:

1) 安全漏洞个数P.数据来源于由Sysdig公司所提供的最近年度容器安全现状分析[18].

2) 逃逸损失M.M反映该目录文件若被攻击者获取造成的财产损失额.设每个与Docker容器相关文件所带来的损失为单位1,Ci的损失为CFi与SF{i,j}之和,HF损失值即宿主机关键路径文件带来的损失.宿主机关键路径文件会对系统安全带来一定影响,若容器逃逸至宿主机,那么该宿主机上的所有容器都将无法使用,故HF的损失值估计为宿主机上所有容器损失之和.根据Kubernetes1.2更新日志中的说明,推荐1台机器部署3个Pod.结合当下时速云公司的生产环境中平均每个Pod约有2~3个Docker容器,取折中2.5个,所以HF的损失值约为单个容器逃逸损失的750%.

上述2个指标的核心参数统计结果如表2所示:

表2 核心参数统计结果

将上述数据处理得到原始数据矩阵T,第1列值为相关安全漏洞数,第2列值为容器逃逸损失.

(1)

采用最大值标准化方法将T标准化,使值全部在[0,1]的区间范围内Y,Y为T的标准化处理结果.

(2)

(3)

用传递闭包求R的模糊等价矩阵.传递闭包是包含R的最小传递矩阵,采用平方法求R的传递闭包V:

(4)

模糊等价矩阵V按α截关系对其进行聚类,V的α截矩阵为V=(αrij)n×m,其中:

(5)

对于不同的α截矩阵,分类结果不同其实际意义和经济意义也不同,从中可判断出与实际最接近的分类方案.当α<μ时,Rα的分类是Rμ的加细,当α由1变为0时,Rα的分类由细变粗,形成一个动态聚类图,如图1所示:

图1 动态聚类图

当0<α≤0.227 1时,得到的分类是{Ci,CFi,SF{i,j},HF};

当0.227 1<α≤0.650 0时,得到的分类是{Ci,CFi,SF{i,j}}{HF};

当0.650 0<α≤0.893 3时,得到的分类是{CFi,Ci}{SF{i,j}}{HF};

当0.893 3<α≤1时,得到的分类是{CFi}{Ci}{SF{i,j}}{HF}.

根据实际需要目标分类是主、客体分为3类,记作{CFi,Ci}{SF{i,j}}{HF}.且依据统计量F确定最佳α值,也分类为{CFi,Ci}{SF{i,j}}{HF}.

统计量F的计算公式为

(6)

其中,

(7)

(8)

式(6)中分子表示分类与分类之间的距离,分母表示分类内样本间的距离.因此,F值越大,说明类与类之间的距离越大,类与类间的差异越大,分类就越好.计算得到最优分类为{CFi,Ci}{SF{i,j}}{HF},F值最大约为185.360 7.

依据风险值RK作辅助评判,因为HF>Ci>CFi>SF{i,j},故安全等级设置为HF>CFi=Ci>SF{i,j},与构想安全等级设置一致.将安全等级设置为secret>general>public.

3.2 HF,CFi访问控制

CFMAC系统启动之前,需要对访问控制的主客体进行安全属性设置.然而宿主机内文件繁杂众多,若以文件为单位进行安全属性的设置,工作量会十分庞大,故考虑从目录的角度出发,系统对宿主机文件进行访问时按照配置文件的目录配置信息进行访问控制.

当某个进程发起访问时,首先对进程源进行判定,通过对PID chain的识别判断是否为容器进程,CFMAC只针对容器进程的访问控制.其次对文件进行定位,获取文件的安全信息,对主客体进行安全等级判断,决定是否可以进行访问.因为PID Namespace的存在,使得子进程在父进程的Namespace下进行活动,所以在Linux中所有的进程都有1个共同的父进程为0号进程,同理,Docker中的所有进程都在Docker Daemon的范围下进行活动,进行PID溯源操作,得到PID chain便可判断当前正在执行进程是否为Docker相关进程.

图2显示了容器进程隔离模块的设计目标.对于单个容器范围内的文件访问严格遵守安全等级限制;对于多容器范围,对CF不允许跨容器访问,从而实现容器间相互隔离.

图2 容器进程访问CFi和HF

3.3 SF{i,j}访问控制

针对Pod内容器对SF{i,j}的访问,需对共享文件进行信息记录,包括路径、Pod名以及参与共享的容器.在同Pod内若某个容器没有主动将某文件共享,则当容器逃逸后对SF{i,j}也没有访问权限.图3清楚地反映了访问控制情况.对于同Pod而言,容器C2,C4不能访问SF{1,3},同样容器C1也对SF{2,3,4}没有访问权限.对于异Pod而言,Pod1内有4个容器C1,C2,C3,C4,不可访问Pod2中SF{5,6}.同样Pod2中容器C5,C6也不能访问Pod1中的任意SF{i,j},即SF{1,3},SF{2,3,4}.

图3 容器进程访问SF{i,j}

4 系统功能的实现

本节介绍CFMAC的实现过程,包括功能架构及实现流程等相关细节.图4为CFMAC模型整体架构.

4.1 进程识别

Linux内核使用task_struct数据结构来关联所有与进程有关的数据和结构,Linux内核涉及到进程和程序的所有算法都是围绕该数据结构建立的,是内核中最重要的数据结构之一.

利用内核中指向当前进程的current指针,获取正在执行访问任务进程的PID.根据获取到的PID,获得完整的PID chain,根据PID chain中的内容判断出是否为Docker 相关进程.进程识别流程如图5所示.

4.2 CFMAC访问控制

CFMAC通过定义相关LSM钩子函数,实现对文件访问控制,主要通过file_open实现.security_hook_list如下:

static structsecurity_hook_list dockerlsm_hooks[]={

LSM_HOOK_INIT(file_open,dockerlsm_file_open);

…};

当只涉及单容器访问时,访问规则严格遵守安全等级.当涉及多容器访问时,容器进程访问控制流程如下:首先进行系统初始化,包括钩子函数拦截访问访问、配置文件读取等.然后进程识别,若是容器相关进程执行目标文件识别,否则直接结束允许访问.识别目标文件,获取目标文件来源,判定文件类型HF,CFi,SF{i,j}.主客体安全等级判断:若文件为HF则拒绝访问;若为CFi,判断文件与进程安全标签是否一致,若一致且访问的是CFi则允许访问,否则拒绝访问;若为SF{i,j},则判断Pod是否一致,若一致则进行Pod内id大小判断,若主体id大于等于客体id允许访问,否则拒绝访问.

图4 CFMAC模型整体架构

图5 进程识别流程

4.3 文件识别

为提高系统效率,先对靶向文件进行识别,若为HF,CF,SF中的某一类文件再进行访问控制.对HF,CF,SF文件进行安全标签填充,即比普通文件多1个security.cfmac的扩展属性.首先判断扩展属性security.cfmac值是否为空,若不为空则执行安全等级校验,若为空则进行有无父inode节点判断.

因为CF,SF的文件众多,若逐一设置安全标签则会给安全管理员带来很多负担.为提高管理员的工作效率,最终选择将安全标签贴至总目录上,这样可以避免对每个文件设置安全标签.故文件识别时直到无父inode或者安全扩展属性不为空为止.若一直为空,则不为HF,CF,SF中的某一类文件,则允许访问.一旦出现security.cfmac不为空,则一定为HF,CF或SF中的某一类文件,则需要进一步作安全访问控制校验.

在用户态使用setfattr命令为文件设置扩展属性,-n参数后接上key值进行设置.在内核态利用inode节点中的getxattr操作进行扩展属性获取.单个文件识别流程如图6所示.首先获取当前访问file的结构体信息,然后使用getxattr获得扩展属性security.cfmac得到值,若为空则进行有无父inode判断,当存在父inode时,则该文件仍保留为CF或SF的可能,故需要一直向上取父inode,直到不存在父inode时则所有可能性都进行了安全标签的判断.若最后无父inode且安全标签也一直为空,则这个文件只是普通文件,不会对系统或Docker容器带来危害,则可以直接放行.一旦扩展属性security.cfmacy有值,则说明文件为HF,CF或SF中的某一类,需要进行强制访问控制.

图6 单个文件识别流程

5 模型测试

本节对CFMAC模型进行测试,分别设置单容器、同Pod多容器、多Pod多容器对SF{i,j},CFi,HF的访问效果进行测试.测试目标包括:1)单容器下严格遵守安全等级总则进行访问,Ci只可访问CFi及SF{i,j},不可访问HF;2)容器间不可自由访问彼此的CF文件;3)Pod内id相对大的可访问Pod内id相对小的SF{i,j}文件;4)Pod之间不可自由访问SF{i,j}文件.根据上述测试目标及实际逃逸模拟情况,为方便进行测试给出如下测试方式.

5.1 测试环境

宿主机环境:操作系统Centos 7,Linux内核版本4.5.4,Docker版本1.14.1;容器环境:镜像Ubuntu15.10,Linux内核版本4.5.4.

容器间网络配置使用Docker默认配置,各容器共享宿主机网络,彼此间相互隔离.模拟逃逸利用Docker共享数据卷功能实现.

5.2 测试方案

5.2.1 单容器访问测试

1) 将宿主机HF挂载至Docker容器内,用来测试单容器下Ci访问HF.在容器内对宿主机/root目录发起访问,测试结果如图7所示,使用cat命令对文件进行查看,cat会自动将文件参数识别为无效参数,从而无法打开文件.超出容器范围进行访问,进程将会被识别为逃逸程序,触发访问控制程序,限制容器内发起的访问,CFMAC在内核中的运行效果如图8所示.

图7 单容器访问HF

图8 内核运行CFMAC效果

2) 挂载1个普通数据卷至Docker容器内,测试单容器下Ci访问SF{i,j}.在容器内对/usr目录发起访问,可自由查看文件内容,测试结果如图9所示:

图9 单容器访问SF{i,j}

3)CFi访问测试不用另行创建容器,可直接利用上述创建的2个容器进行测试.测试结果如图10所示,可自由查看自己容器内文件.

图10 单容器访问CFi

5.2.2 同Pod多容器访问测试

1) 创建容器volumetest05,将宿主机中/var/lib/Docker中其他容器所属文件,挂载至volumetest05,用于测试跨容器访问CF文件.结果如图11所示:

图11 跨容器访问CFi

2) 基础容器创建docker run -it -v /data --name=test -d ubuntu:15.10;将容器test中创建的共享数据卷/data挂载至容器sfvolumetest01,sfvolumetest02,并在配置文件中设置为Pod1,用于测试同Pod多容器间访问SF{i,j}文件.同Pod容器中访问SF文件,id相对小者禁止访问由id相对大者共享的SF{i,j}文件.反之则允许访问.测试结果如图12、图13所示:

图12 容器Pod内id小者访问SF{i,j}

图13 容器Pod内id大者访问SF{i,j}

5.2.3 异Pod多容器访问测试

异Pod容器创建,配置文件中设置sfvolume03容器group为2,id为0.测试异Pod访问SF,测试结果如图14所示,禁止跨Pod访问SF.

上述异Pod容器创建情况(部分)如图15所示:

图15 异Pod容器创建情况

5.2.4 性能测试

安全加固方案的性能也是十分重要的,不能为了安全而过分地舍弃性能,本文方案对Docker的源码未作任何修改,故对Docker的性能不会带来大的影响.所以只对Linux系统性能进行测试,现对加载了CFMAC模型内核的系统和未加载的原始系统作对比测试实验.测试方法是分别在2种环境下让UnixBench执行10次,对UnixBench给出的Index Score取均值.

从图16的数据可知,综合性能损失约为14.97个“George”基线系统.CFMAC对系统的性能影响较小.

图16 UnixBench性能测试结果

6 结束语

本文从实际生产应用环境出发,为防止容器逃逸带来巨大损失,提出CFMAC模型对Docker容器进行安全加固.CFMAC是一个基于Docker的强制访问控制模型.该模型从结构上对传统安全模型进行修改,结合模糊聚类进行安全等级划分.利用LSM技术,对file_open进行访问拦截实现.测试结果达到预期目标,表明CFMAC能有效进行安全加固,对用户文件操作进行访问控制,达到最小化权限限制[19].在下一步的工作中,将模型进行调整使其贴合实际集群应用环境,对其他权限也进行限制.

猜你喜欢

访问控制内核客体
一种跨策略域的林业资源访问控制模型设计
社会公正分配客体维度与道德情绪的双向互动
多内核操作系统综述①
强化『高新』内核 打造农业『硅谷』
活化非遗文化 承启设计内核
浅议犯罪客体
微软发布新Edge浏览器预览版下载换装Chrome内核
云的访问控制研究
云计算访问控制技术研究综述
“凡客体”之不凡处