引言
随着云计算的发展,以容器和微服务为代表的云原生技术,受到了人们的广泛关注,其中Docker和Kubernetes是企业容器运行时和容器编排的首要选择。然而,在应用容器和Kubernetes过程中,大多数企业都遇到过不同程度的安全问题,如何保障容器安全,已成为企业最关心的问题。
应用容器带来新挑战
容器应用之前,云中应用系统多数运行于虚拟机上,但虚拟机仍会有额外的资源浪费和维护成本,并且其启动速度较慢。容器技术因具有占用资源少、部署速度快和便于迁移等特点,开始受到企业青睐。在典型的云原生环境中,通常包括主机、镜像、容器、容器编排平台、网络和微服务等对象,但由于目前多数企业使用容器技术部署业务应用,故下面将重点分析与容器相关的安全挑战。
容器技术风险
作为一种操作系统虚拟化技术,容器共享操作系统内核,但并未实现完全隔离,若虚拟化软件存在漏洞,或宿主机被攻击,将会造成容器逃逸或资源隔离失效,影响某个容器或多个容器的安全。
容器逃逸:利用虚拟化软件存在的漏洞,攻击者通过容器获取主机权限,可攻击容器所在主机,甚至是该主机上的其他容器。过去几年内已经发现了多个相关漏洞,其中CVE-2019-5736是RunC的一个安全漏洞,它会导致18.09.2版本前的Docker允许恶意容器覆盖宿主机上的RunC二进制文件,使攻击者能够以Root身份在宿主机上执行任意命令。
资源隔离失效:攻击者只要攻破容器操作系统内核,就可访问到主机上的文件系统,或进入其它容器,导致容器隔离失效。如果把主机的文件系统挂载到多个容器的目录里,容器就可以访问同一个目录,将会引起信息泄露或内容篡改等安全问题。
不安全的镜像
镜像是一个包含应用/服务运行所必需的操作系统和应用文件的集合,用于创建一个或多个容器,它们之间紧密联系,镜像的安全性将会影响容器安全。根据镜像创建和使用方式,通常有三个因素影响镜像安全。
现有镜像不安全:镜像通常是开发者基于某个现有镜像创建的,无论是攻击者上传的恶意镜像,还是现有镜像存在的安全缺陷,基于它创建的镜像都将会是不安全的。
使用包含漏洞的软件:开发者经常会使用软件库的代码或软件,如果它们存在漏洞或恶意代码,一旦被制作成镜像,也将会影响容器的安全。
镜像被篡改:容器镜像在存储和使用的过程中,可能被篡改,如被植入恶意程序和修改内容。一旦使用被恶意篡改的镜像创建容器后,将会影响容器和应用程序的安全。
东西向攻击
网络实现了容器之间、容器与外部之间的通信,以及应用之间的交互,但在虚拟化的容器网络环境中,其网络安全风险较传统网络更复杂、严峻。以Docker环境为例,它支持Bridge、Overlay和Macvlan等网络,尽管实现方式不同,但有一个共同和普遍的问题:如果容器之间未进行有效隔离和控制,则一旦攻击者控制某台主机或某台容器,可以以此为跳板,攻击同主机或不同主机上的其他容器,也就是常提到的“东西向攻击”,甚至有可能形成拒绝服务攻击。
运行环境未加固
作为容器的载体和编排管理软件,主机和容器编排平台等运行环境也是容器安全的重要因素之一。如前所述,主机上的容器并未实现完全隔离,如果主机未进行安全加固,一旦攻击者发起提权攻击,将会控制主机上其他容器。对于不安全的容器编排平台同样如此,某汽车制造企业就曾深受其害,由于其公有云环境中的Kubernetes Master节点未设置密码保护,攻击者在盗取访问权限后,使用Kubernetes集群挖掘加密货币。
容器安全应对举措
从LXC开始,容器就利用了大部分Linux通用的安全技术,它们构成了容器安全的基础。面对新挑战,无论传统的安全加固,还是新的镜像组成分析,镜像、容器技术、网络和主机等不同层面的安全措施,都将有助于提升容器安全性。
Linux内核安全机制
Linux通用的安全技术包括命名空间(Namespace)、控制组(Cgroups)、系统权限(Capability)、强制访问控制(MAC)系统以及安全计算(Seccomp)等。一个好的容器平台,应该具备这些能力,下文将聚焦前三种能力。
命名空间(Namespace):本质上容器是由各种命名空间组成的,它们为容器提供了基础隔离,让每个容器拥有独立的进程ID、网络栈、根目录、内存、用户名和主机名。
图1 容器是命名空间的组合
控制组(Cgroups):控制组负责实现资源审计和限制,让每个容器公平的分享主机资源,并设置了限制,以免单个容器过度消耗资源,影响到主机系统和其他容器运行,也可以防止拒绝服务攻击。
图2 控制组限制容器可使用的资源
系统权限(Capability):Root用户拥有全部的权限,以Root身份运行容器很危险;但如果以非Root身份在后台运行容器的话,由于缺少权限会处处受限。系统权限机制可以提供细粒度的权限访问控制,控制容器运行所需的Root用户权限,即使攻击者取得了Root权限,也不能获得主机的较高权限,可以限制进一步的破坏。
图3 系统权限控制容器权限
安全容器
Linux通用安全技术为容器提供了基础隔离,但未实现100%隔离。安全容器通过增加额外的隔离层可以进一步增加容器的安全性。它是一种容器运行时技术,为容器应用提供一个完整的操作系统执行环境(常常是Linux ABI),将应用的执行与宿主机操作系统隔离开,避免应用直接访问主机资源,从而可以在容器主机之间或容器之间提供额外的保护。
gVisor和Kata Containers是两个代表性的安全容器实现,其中Kata Containers通过使用硬件虚拟化,利用轻量级的虚拟机为容器提供隔离,每一个Container/Pod运行于独立的虚拟机上,他们不再从主机内核上获取相应所有的权限,从而使Kata Containers与VM一样能提供强隔离性。
图4 Kata Containers结构及原理
镜像安全分析
作为容器运行的基础,容器镜像的安全在整个容器安全生态中占据着重要位置。容器镜像由若干层镜像叠加而成,通过镜像仓库分发和更新。因此,可以从镜像构建安全、仓库安全以及镜像分发安全三方面实现镜像安全。
镜像构建安全:在构建镜像时,验证所依赖镜像的完整性和来源,只安装必要的软件包,使用恰当的指令,缩小攻击面;并利用加密技术,保护好密码、令牌、密钥和用户机密信息等。
镜像仓库安全:镜像仓库分为公共镜像仓库和私有镜像仓库,使用公共镜像仓库的镜像时,使用官方发布最新版本的镜像,对下载的镜像要经过漏洞扫描评估,并保持定时更新。对于私有镜像仓库,一方面保持仓库自身的安全性,例如在使用时要配置相应的安全证书,另一方面使用镜像过程中,利用用户访问权限控制确保交互过程的安全性。
镜像分发安全:在镜像下载和上传时,利用数字签名和Https来保障容器镜像的完整性和机密性,抵御中间人攻击等威胁。
微隔离
网络的基本防护手段是隔离和访问控制,容器网络防护可使用容器环境自身安全机制或第三方微隔离产品。对于Kubernetes网络,其自身安全策略对每个Pod的入口强制执行访问控制,从而能够隔离高风险的微服务,但Pod内容器间通信和离开Pod的出口流量无法控制。第三方微隔离产品可是比Kubernetes更详细地记录出入网络连接、深入检测网络中威胁和攻击,以及检测数据泄露,实现七层微隔离和网络可视化。
运行环境加固
利用安全基线对容器主机和Kubernetes进行安全检查和加固,将会进一步增加容器的安全性。CIS发布的Docker 基线已成为Linux主机配置和Docker主机加固的最佳实践。通过创建一个特权容器,将Docker主机安全配置与CIS 基线进行对比,可以发现安全问题和实施加固。同样,CIS也发布了Kubernetes基线,传统的漏洞扫描工具、独立的容器安全产品(如Aqua Security和NeuVector)和私有维护人员已经在GitHub上发布了脚本,可实现自动化的Kubernetes安全检查。
容器安全实践
随着DevOps兴起,软件开发人员与运维人员之间紧密合作,通过自动化流程来完成软件开发、测试、发布和维护,整个过程更加快捷、频繁和可靠,缩短了软件上线时间,减少了很多重复性和人工工作。现在,针对容器安全风险,已经形成了多种安全控制措施,如何将它们融入到DevOps中高效保护应用系统,是容器安全实践需要考虑的首要问题。
为此,我们秉承DevSecOps理念,提出了容器全生命周期安全保护方案,该方案利用容器安全管理系统,通过容器编排技术将安全容器部署于容器环境中,进行持续的检测和分析,实现容器环境的资源可视化管理、镜像风险管理、容器运行时安全管理、合规性检测和微服务API风险管理,最终保障容器在构建、部署和运行整个生命周期的安全。
总体架构
容器安全防护方案采用模块化和分层设计,通过与容器运行环境进行对接,实时获取容器环境中的镜像和容器等对象的相关信息,利用各种安全能力进行监控和分析,进行统一的安全管理,最后通过图形化方式为用户展示容器环境的安全态势。
图5 容器安全防护架构
安全管理层:负责安全管理功能,包括容器环境的资产管理、策略管理和安全能力管理等,通过安全能力适配将各种管理信息下发给各种安全能力,以及收集各种安全信息,经集中分析和处理后,集中对用户展示容器环境的主机、容器、镜像和网络等对象的安全状态。
安全能力层:负责提供具体安全能力,为容器环境提供安全保护,安全能力涉及系统安全扫描、镜像文件分析、恶意文件分析、入侵检测和微隔离等。
运行环境层:负责提供容器镜像、容器编排管理等功能,以及运行应用程序的容器,并与容器能力层进行交互,共同实现容器安全防护。
容器全生命周期保护
根据容器安全防护架构,本方案将各种安全能力与DevOps流水线相结合,从持续集成/持续部署和运行时进行安全防护,为容器提供构建、部署和运行的全生命周期保护,最终实现应用系统的安全运行。
图6 容器全生命周期保护
构建安全
在应用程序构建阶段,通过与CI/CD流水线集成,分析构建镜像时所使用的命令和配置参数,还原镜像文件构建过程,掌握命令使用的敏感操作,以及分析镜像文件是否包含密码、令牌、密钥和用户机密信息等敏感信息。同时,分析镜像的软件组成,发现镜像文件中包含的恶意文件、病毒和木马,以及所使用的依赖库和组件存在的安全漏洞,避免带病交付。
部署安全
分析镜像无风险后,镜像被提交至镜像仓库。在该阶段,将检查容器环境的镜像仓库配置,确保使用加密方式连接镜像仓库。通过与Kubernetes联动,当镜像仓库中新增镜像或使用镜像创建容器时,自动化校验镜像签名或MD5值,确保镜像来源可信且未被篡改,一旦发现镜像来源不可信或被篡改,禁止使用该镜像创建容器。
运行安全
当确认镜像安全后,进入到容器运行阶段。在该阶段利用系统安全扫描能力,基于Docker和Kubernetes CIS 基线,对主机和容器编排工具Kubernetes进行合规性检查,检查范围包括主机安全配置、Docker守护进程配置、Docker守护程序配置文件、容器镜像和构建、容器运行安全和Docker安全操作等,确保容器运行环境安全。
同时,利用微隔离对容器进行网络隔离,通过入侵检测能力实时监测容器运行状态,监测对象包括容器内运行进程(如netlink socket、perf event和eBPF)和文件系统,以及主机环境的权限提升和破坏容器隔离性等行为。当发现容器运行异常时,利用访问控制机制限制容器进一步的行为和通信。
结语
伴随着云原生应用发展,企业通过微服务来交付应用系统的比例在增加,容器安全也将不仅仅是容器自身和容器环境安全,将延伸到微服务安全和应用安全,企业在应用云原生技术时,应整体考虑容器安全,让安全与云原生相融合,更好的保护应用系统。