数万台服务器下的Docker深度安全实践

本文整理自OPPO互联网安全团队刘湛卢的分享,他们主要负责OPPO互联网安全团队的研发工做,若是你也关注容器安全问题,但愿这篇文章能带来启发。node

同时欢迎关注OPPO互联网技术团队的公众号:OPPO_tech,与你分享OPPO前沿互联网技术及活动。mysql

本文主要内容以下:linux

  1. Docker生态与架构
  2. 安全问题和应对方案
  3. OPPO容器安全实践
  4. 容器生态的安全展望

先简单介绍一下行业背景。web

当前,OPPO在全球有超过2亿+的DAU,最近几年数据量增加超过180倍。从服务器数量和业务量的变化趋势,能够看到互联网业务总体的发展趋势是呈指数型上升,同时业务量的增加带来了服务器数量的高速增加,这也与业务指数曲线是相似的。而当下,业界主流技术已经从物理服务器承载业务转向了Docker化,Docker是当前热门的云计算主流技术。redis

Datadog 2018年6月统计的数据显示,25%的公司已经采用Docker,预计2020年会达到50%,其余没有使用Docker的公司也在追赶过程当中。sql

1、Docker生态与架构

所谓容器生态,就是围绕容器周边的一系列元素和容器一块儿构成整个容器构建、运行的方案和工具、文件等,而容器的安全并不只仅只是容器自己的安全性,也和容器生态的安全牢牢结合在一块儿,须要有容器整个生态的安全支撑才能一块儿构建容器完善的安全方案。shell

那么容器的安全具体包括哪些元素?毫无疑问,Docker自己是其中核心的一部分。这是把容器运行起来的关键,控制着容器的启停、管理容器运行所须要的资源、以及容器和外界的交互等容器核心功能点。数据库

同时,Docker容器的运行是须要镜像做为支撑点的。每一个业务功能可能会有一个镜像,当业务众多,并且有不一样版本时,尤为像微服务这种对业务的拆分粒度很小的状况,会产生大量的镜像。在Docker里面是由registry来管理镜像,他存放着咱们全部的镜像,当Docker在运行的时候,能够指定从某个registry拉取相应镜像到本地运行,固然这个拉取动做Docker本身会去执行。api

到了生产环境,尤为是业务体量比较大的公司或者机构,对如何管理镜像的分发、容器的调度、业务的高可用能力、容器多副本的维护等方面提出了很大的挑战,由此kubernetes应运而生。kubernetes的出现更加方便了容器在大规模使用,复杂业务场景上的使用。浏览器

先来看一副Docker安全与传统安全的对比图:

传统的主机层安全问题包括操做系统的安全漏洞,webshell,恶意二进制程序,rootkit,内核安全,ssh暴力破解等。

Docker的安全包括:Docker自己的安全(包括主机的安全),镜像的安全,registry的安全,镜像分发传输的安全,编排系统(kubernetes)的安全将会成为容器安全建设的核心点。

Docker的架构:

通常而言,Docker会跨私有网络和互联网运行,宿主机,企业级本身的私有注册中心都会在私有网络中,而Docker hub 这类公有注册中心,互联网上的其余的公共注册中心会运行在公网。在私有网络中,宿主机上包括Docker客户端和Docker的守护程序(Docker daemon),经过Docker客户端向Docker的守护进程发送Docker指令来启停容器,或者获取容器的相关信息。Docker守护程序则接收到来自客户端的请求则执行Docker命令,包括解析Docker指令,执行容器的启停,向各个仓库拉取镜像等来完成容器的操控。因此Docker守护程序的安全是很是关键的,他能直接操控该主机上的全部容器。

2、安全问题和应对方案

几个核心安全问题,第一是主机与容器守护安全,第二是镜像安全,第三是容器运行时安全问题,第四是生态安全。

主机与容器守护安全问题。主机上的安全配置是否影响到容器的运行,主机的安全漏洞是否影响到容器运行,容器内的进程是否能够利用主机上的安全漏洞。

镜像安全方面。镜像是否安全,镜像传输过程当中是否会篡改,镜像被销毁后是否还存在安全问题。

容器运行时的安全问题。各容器之间的通信是否安全,隔离是否充分,容器在资源使用上是否安全。

生态安全。主要是Docker自己的安全性,还有编排系统的安全问题,容器的秘钥管理和传统的秘钥管理是否不同,容器化之后的数据隐私保护方案是否和传统方案一致。

2.1 主机与Docker守护进程的安全问题

先看Docker守护进程的安全,这个是用root权限建立的文件,经过非root文件就把它删除掉了,这种主要是Linux对内核隔离性的不足,在Docker使用时隔离级别是由用户自行决定的,把这个帐号直接加到Docker的帐号组里就具有了这个权限。

咱们再看一个例子,曾经爆出来的Docker swarm集群管理配置问题,就是将Docker daemon的相关接口暴露在公网上,而且并无启用任何保护措施,从而致使任何人均可以使用Docker api来操纵容器,这就形成了一个危险极大的安全隐患。

而一般安全可靠的作法能够由这几种方式:

  1. 使用Docker自己提供的TLS/HTTPS加密接口通道,但这种在大规模使用的时候在证书和秘钥的管理方面会带来必定的挑战。

  2. 经过统一的代理来访问每一个Docker daemon的接口,而不直接暴露其接口,这样使用安全代理加固的方式保护Docker daemon的接口安全性。

总的来讲 Docker 守护进程的安全问题主要来自这几个方面:

  1. 须要root权限运行,这个在daemon安全上可能会带来很大的安风险;

  2. 守护进程对外提供API服务,用于的容器和整个Docker的管理工做,这使得对这些接口进行安全保护是很是重要的;

应对方案:

  1. 尽可能不要直接开启Docker remote api服务,若是必要则能够经过中间代理层来作隔离控制;

  2. 在隔离层添加ACL,添加控制白名单,增强对访问源的监管;

  3. 启用TLS认证,增强验证和通信的传输过程;

  4. 守护进程的相关安全配置的合规扫描和审计;

2.2 镜像安全问题

全部容器都是基于镜像运行,若是镜像的安全性受到威胁,显然容器就被攻陷了,甚至主机均可能沦陷。

Docker hub是在行业主流的镜像仓库,其由Docker官方提供。曾经有人对其镜像进行抽样,使用clair对镜像扫描,发现安全的镜像只有24%,而风险镜像占到76%,其中高风险的镜像有67%,这说明镜像已经成为Docker安全中的一个重要的安全攻击防护战场了。

例子:有人曾经利用Docker hub 传播了17个恶意镜像,其中包括有挖矿代码,后来分析其相关镜像的恶意代码,发现其中相关联的钱包地址显示,这些恶意镜像挖出了价值9万美圆的门罗币;因此,利用恶意镜像进行挖矿、传播恶意文件、勒索病毒、逃逸到主机系统作恶意攻击等等,这些均可以植入到镜像中。

总结一下镜像会产生安全问题的几个方面:

镜像内容安全:镜像能够携带的安全问题如依赖库漏洞,植入病毒,恶意文件等其余安全问题,若是使用了基础镜像,那么基础镜像是要可信的;

镜像内容性质:镜像内容的大小,在磁盘上是否会建立或者包含较大的磁盘空间,由于一个镜像能够建立多个容器,容器多了之后容易致使主机资源不够用,再者是镜像中文件个数过多,会致使大量的inode被占用而过多消耗系统资源;

镜像仓库安全:包括仓库自己的问题和安全加固,镜像的传输安全,安全认证,镜像签名体系等等;

镜像中的用户权限控制:默认在镜像中的进程是root权限运行,用户能够在构建镜像时听从相关规范,以最小权限原则执行;

镜像扫描审计:经过对镜像的深度扫描和审计,能够及时发现镜像的安全问题。

镜像安全扫描工具:

Clair:当下很是主流的镜像安全扫描工具,其扫描分析特色是使用静态分析方式,会把镜像包拆开,对镜像进行层级分析,和已知的CVE库进行版本对比的方式来扫描镜像。这种分析方式有不少局限性,只能根据CVE库的版本进行对比,换言之对0day是毫无防护能力,没有收录在CVE或其恶意库中的将得不到准确的扫描结果。因此扫描效果不是特别明显。

其余几个扫描工具包括 anchore 和 Dockerscan 的扫描工具也是相似的思路。

这些都是当前开源、主流的一些扫描工具,后面咱们也会讲讲oppo的深度镜像扫描系统的相关实践。

2.3 运行时安全问题

容器运行时安全是从Docker daemon根据镜像拉起一个容器开始,那么在运行过程中,容器的安全性就和容器的运行机制、运行时库、系统调用、读写行为等这一系列的动态动做关联起来了。前不久爆发的runC容器逃逸的漏洞,简单来讲这个漏洞就是经过在拉起一个恶意镜像的过程当中,把Docker-runc这个关键程序覆盖了,固然Docker daemon下次再启动容器时就会执行替换的Docker-runc恶意代码。除了runc容器逃逸的安全问题,主机层内核若是存在dirty cow漏洞也能够溢出到主机上。

容器运行时安全,除了从容器内逃逸到主机上以外还有其余的方式,容器运行时的安全问题还有下面这些:

  • 磁盘资源限制上,例如某个容器把磁盘写满了致使其余容器没法正常工做。

  • 容器之间的Ddos攻击,某个容器把当前主机的带宽打满,致使其余容器没法工做。

  • 因为kernel层的隔离性不足上面,例如/proc,/sys等子系统的隔离性不足,容器内看到的cpu个数/mem等数据不许确等等。

那么应对这些问题都有哪些办法?Docker自己在这个层面上的安全控制能力是比较弱的,主要依靠内核层面有提供一些能力和权限限制工具来辅助处理,包括seccomp,capability,selinux,apparmor,tc流量控制,quota技术等。

2.4 容器生态安全问题

除了容器的运行时安全,镜像安全,守护进程的安全问题,容器生态中还有很是重要的一环,容器编排和调度,当下最主流的容器编排和调度系统kubernetes,那么kubernetes的安全性是怎么样的呢,其实kubernetes也发生过好多安全问题,包括曾经遭遇的大范围的劫持等。

对于kubernetes的安全应对方案:

  • 对系统使用最小特权。

  • 按期更新系统软件来确保已经被官方修复的漏洞获得保护。

  • 对其操做日志进行记录和审计,是系统保持在一个被安全监控的环境下运行。

  • 权衡好安全和生产力的依托关系,经过调整产品形态把对一下有安全风险的功能关闭,或者使用其它方式替代使用。

  • 使用安全端口进行通讯等。

3. OPPO容器安全实践

整个容器的生命周期,包括了从镜像构建到编排分发,从容器建立到运行、销毁这一系列阶段,所以咱们须要从容器生命周期全阶段进行安全加固和保护。

在镜像的生成阶段:从镜像构建到把镜像推送到注册服务器,镜像构建中须要根据业务状况来定制安全构建策略,听从镜像的安全构建规范,例如建立专门用在容器的用户来启动容器内业务进程、使用可信镜像、涉密信息不存储在Dockerfile、在Dockerfile中使用copy而不是add等等;那么在注册服务器,镜像仓库中会进行镜像的深度扫描、签名验证等以防止恶意镜像流入生产环境的镜像仓库,同时须要对镜像仓库接口进行加固和镜像操做日志进行审计以防止镜像仓库系统的入侵攻击和被恶意修改。

编排分发阶段:编排系统一样须要作安全基线审查扫描,提供有效的安全策略配置,编排系统kubernetes的接口层安全加固,这是由kubenetes自己所提供的一系列机制来实现集群安全控制,其中包括API Server的认证受权、准入控制机制以及保护敏感信息的securet机制等。同时在编排系统也须要作好日志审计,以便于风险问题的预警分析和溯源。

容器镜像的传输:在传输途径中须要使用https进行加密传输,以防止中间人攻击篡改镜像。

镜像的运行:镜像最终是须要流转到主机来真正使用,由Docker守护程序根据镜像建立容器运行,那么在主机层的镜像审计和回扫都是很关键的,同时也须要对镜像进行深度分析、镜像的合规基线扫描,来检测在主机侧是否有恶意镜像。

3.1 镜像安全构建

安全构建,是在业务侧进行,咱们须要给业务侧提供镜像的安全构建规范,业务方严格强流程按照安全构建规范完成构建。

主要是为了达到如下几个目的:

  1. 有可信的安全的基础镜像,能够由运维或者基础镜像团队统一提供安全基础镜像;

  2. 镜像内业务权限最小化,依赖资源最小化,例如使用专用的容器运行帐号来启动业务进程而非root用户,移除没必要要的权限如setuid/setgid等系统调用能力防止提权攻击;

  3. 尽可能减小镜像中外部资源的使用;包括使用COPY替代ADD,由于ADD能够经过外部连接来加载资源,不在Dockerfile中单独使用更新命令等等。

3.2 镜像仓库加固

镜像仓库的架构中,通常仓库API不要直接对外提供服务,能够经过增长一个中间代理层proxy来负责全部访问对接,不管是在开发环境构建镜像仍是扫描引擎对镜像进行安全扫描,仍是产环境对容器进行编排部署都经过proxy进行来作镜像的操做审计,客户端认证、受权等操做。

中间层的做用主要包括:

  • 镜像的提交审计;

  • 传输加密;

  • 客户端认证、受权;

  • 扫描引擎和镜像仓库的扫描对接;

  • 对镜像仓库服务器IP作访问控制,接口恶意调用拦截等安全加固。

镜像仓库上能够给它进行角色上的权限认证,好比不一样角色分配不一样权限,像开发、扫描和生产环境上分别配置不一样的角色和配置不一样权限,对业务进行划分,不一样业务使用时也有不一样的权限,能够设置黑白名单进行访问控制,日志操做审计,在操纵流程中包括上传、下载及全部操做。

3.3 镜像深度扫描

把镜像从镜像仓库拉取下来,对镜像的Dockerfile作指令分析,固然镜像里面并无直接携带Dockerfile文件,而是对其产生的history指令进行分析扫描,检测其是否有不合规指令,包括基础镜像进行分析,帐号权限分析,ADD指令分析,内容信任分析,setuid/setgid等合规检查。

镜像是由各个层叠加而成,在history指令分析之后,咱们须要对其各个层进行拆解,对每个层级进行深度扫描分析;拆解之后,会对全部文件进行恶意特征扫描,包括从公司内部收集和沉淀的恶意版本特征库,cve漏洞库,黑白名单等进行版本特征扫描。

在版本特征扫描以后,会进入到深度扫描部分,包括webshell的深度扫描,例如使用yara规则,语法分析,大数据机器学习,模糊hash检测等;恶意elf文件的深度扫描,一样的,elf的扫描也有相应的yara规则,黑白名单,符号表分析,模糊hash,病毒、木马特征库检测;敏感信息检测,分析镜像各层中的文件,查看里面是否存在敏感信息,好比说是镜像里面写的有各种帐号密码(如mysql/redis),咱们会对其进行统一分析扫描,用于保护密码泄露,及早发现和预警。如今各种敏感信息泄露的事件层出不穷,敏感信息泄露也是咱们很是关注的一个层面。这个就是总体的深度镜像扫描流程。

刚才咱们介绍的是单个镜像的扫描全流程,整个镜像仓库应该如何去扫描?OPPO当前的用户体量也是很是庞大,有超过两亿+的用户,业务体系也很是庞大,像浏览器,信息流,内容分发等互联网业务很是丰富,如今微服务的架构大行其道,成千上万的镜像该如何组织,如何扫描,这是很是值得咱们深度思考的问题,从镜像构建到镜像管理都是很是具备挑战性的。

从实践来看,镜像的组织通常划分三大层次:

  1. 由运维提供的基础镜像层,该层镜像只提供系统基础能力,必要的通用工具,运行时库;

  2. 基础组件层,基础组件层会对各业务提供基础组件,包括相关的业务通用库文件等等,提供相关共性业务所须要的通用能力;

  3. 业务服务层,这个层面的镜像是彻底业务化的,不一样的业务有不一样的镜像,一个业务有多个镜像;

  4. 而且这个三个层次通常都有继承关系,基础组件层会继承自运维提供的base镜像,业务会继承基础镜像。

3.4 主机安全加固

除了镜像的安全扫描,主机层也须要对Docker进行安全加固,包括两个层面:

  1. 内核层面的加固:使用apparmor/selinux等配置精细的安全策略,针对进程级的通信访问权限作限制,seccomp:(secure computing mode),是一种内核特性,可用于限制进程可以调用的系统调用范围,从而减小内核的攻击面,用于构建沙箱;capability,用户权限的能力限制,把相同的用户划分为不一样的各个组,能够给每一个组赋予的系统调用能力不同,例如系统超级权限用户root,能够把它划分红多个组,每一个组给作一些不一样的能力削减,一样是root用户所能操做的能力是不同的,从而达到权限的精细化管理。

  2. 用户层加固:尽量的缩小容器用户的权限,限制挂载敏感目录,磁盘单独分区用于运行容器,主机安全的基线配置规范,Docker守护进程的日志和相关配置目录进行操做审计等这些层面来增强对主机的安全加固。

3.5 容器日志收集

主机日志审计,须要有一套高效日志收集系统,统一日志规范,在主机上有统一的日志收集容器,不一样的业务容器的日志统一收集发送到大数据平台,进行恶意日志分析,包括使用日志规则库进行恶意日志扫描,对恶意样本日志进行训练,使用机器学习方式作补充识别等业界主流日志分析方式。分析到异常日志对接到统一的安全预警平台进行容器安全预警。

3.6 流量分析

网络流量安全:Docker daemon会帮容器在主机上创建一个网桥Docker0用于容器间的通信,所以咱们在主机上作流量分析时须要同时监听Docker0和eth0(固然这里的名字须要根据具体的主机配置来定)确保同主机和跨主机的各容器之间的流量都能被分析到;流量分析还有一种方式,交换机旁路镜像分析,这种方式的优势是不影响主机的计算力,能够分析到容器跨主机之间的通信,可是不能分析同主机的容器流量,也没法检测和防护同主机的容器之间Ddos攻击。

流量分析主要是检测容器间的恶意访问,包括恶意域名检测,网址检测,入侵检测,病毒检测,内容审计等,同时会作到协议还原,文件内容还原等,包括像主流的协议,TCP/UDP/DNS/HTTP/MYSQL/REDIS等等。同时在网络层进行网络安全配置规范化,例如只映射必要端口到主机,特权端口禁止映射,不共享主机网络的namespace等。在主机上作TC,traffic control,防止容器间的Ddos行为;

3.7 对容器进程的监控

  1. 获取容器的进程列表,把容器ID和其相关进程映射起来;

  2. 在主机层监控异常进程,发现有异常进程,例如容器中的反弹shell,肯定其所属容器并预警;

  3. 对敏感目录的挂载进行文件监控,发现有异常操做进行预警。

除了作进程监控外,进程的审计调用也很是关键,包括网络是否有外联网络联到恶意的地址或域名,Exec函数族审计,还有域名解析审计。Docker的关键命令程序进行监控,须要监控Docker目录下像Docker-runc、Dockerd、Docker的程序有没有被篡改,须要进行监控和预警保护。

3.8 主机入侵检测与Docker的结合

主机入侵检测中,首先须要把进程和容器ID、镜像ID都关联起来,对进程和相关的webshell/恶意二进制文件进行疑似恶意分析,对于疑似的恶意文件提交到后台进行yara,符号表,特征库,ssdeep的模糊hash等方面的深度分析从而造成检测结果。在这过程当中也会遇到比较大的挑战,例如webshell扫描,扫描过程当中容器启停问题,业务混布,文件多并且混杂,在基线扫描方面也须要考虑的针对容器自身的安全基线和安全策略的扫描。

这是oppo在入侵检测方面覆盖到Docker的检测实践:第一个是检测到容器中的一个反弹shell的问题;第二个是容器外部挂载的一个目录中发现了webhsell;第三个则是在容器运行中发现的一个恶意二进制的后门。

4. 容器生态的安全展望

整体来讲容器的安全方面包括:

  1. 容器的安全运维方案:自动编排,编排系统的安全性,对接到现有业务中,为了兼容业务架构,在容器上线的初期有可能会作出调整而破坏一部分安全机制;

  2. Docker方案代替传统方案以后对数据的安全审计和秘钥管理也会带来很大的挑战,像容器的漂移性,部分流量并不会过交换机,因此其安全审计方案会变得更加复杂;

  3. 容器自身的安全机制,包括0day,并且目前容器主要仍是依靠主机来提供安全机制,而Docker自己对安全方面所作的较少;

  4. 对内核的安全机制依赖,目前内核的隔离机制尚不完善,同时内核的安全问题也透露到容器层面;

  5. 防护与检测方面:容器漂移很是频繁,同时与主机上文件的映射关系较复杂等等,这一些列问题都会给让与检测的带来很大的挑战,并且方案也会更加复杂。

最后重点来啦

OPPO互联网运维云存储团队急招多个岗位,欢迎对MongoDB内核源码、Wiredtiger存储引擎、RocksDB存储引擎、数据库机房多活、数据链路同步系统、中间件、数据库等有兴趣的同窗加入,一块儿参与OPPO百万级高并发文档数据库研发。

工做地点:深圳 / 成都

联系邮箱:yangyazhou@oppo.com(最好注明来源掘金)

相关文章
相关标签/搜索