评估容器安全的现状,解你心中疑惑

  1. 云栖社区>
  2. 博客>
  3. 正文

评估容器安全的现状,解你心中疑惑

晚来风急 2017-07-03 15:31:00 浏览919
展开阅读全文

任何理性的企业都希望能在容器上运行关键任务型服务,但他们会有这样的疑问:“容器真的安全吗?我们真的可以把数据和应用程序放心地交给容器吗?”

在技术人员当中,这常常导致容器与虚拟机之争,并讨论虚拟机中的虚拟机管理程序层提供的保护。虽然这可能是一种有趣而翔实的讨论,但容器与虚拟机这种对立本身就是错的;有关方应在虚拟机里面运行容器,目前这一幕出现在大多数云提供商身上。一个显著的例外是来自Joyent的Triton,它使用SmartOS Zones,确保租户相互隔离。还有一个日益壮大的社区认为,Linux上的容器安全和隔离已得到了长足的改进,用户可以使用裸机容器服务,而不是使用虚拟机,实现隔离。比如说,IBM在Bluemix公共云服务上构建了一种托管的容器服务,该服务运行时租户之间虚拟机并不隔离。

为了保持容器的灵活性优势,多个容器在每个虚拟机里面运行。关注安全的企业可以使用虚拟机,隔离在不同安全级别下运行的容器。比如说,可以安排处理计费信息的容器在不同于留给面向用户型网站的节点的节点上运行。值得关注的是,包括Hyper、英特尔和VMware在内的几家公司正致力于构建速度飞快的基于虚拟机的框架,这些框架实施了Docker API,试图把容器工作流程的速度与虚拟机管理程序的安全性结合起来。

一旦我们改用容器并不意味着放弃虚拟机管理程序提供的已确立、得到验证的安全性,下一步就是调查,可以通过使用容器和基于容器的工作流程实现安全的增益。

安全工作流程

在典型的工作流程中,一旦开发人员完成了某项功能,就会推送到持续集成(CI)系统,该系统将构建和测试镜像。然后,镜像被推送到注册中心(registry)。现在镜像准备部署到生产环境,这通常需要一种编排系统,比如Docker的内置编排工具、Kubernetes和Mesos等。一些企业可能在推送到生产环境之前改而推送到登台环境。

容器安全的现状评估

图1:在容器工作流程中,开发人员将变更内容推送到拥有测试组件的持续集成系统。签名的镜像将移到注册中心,它在这里可以部署到生产环境。

遵循安全最佳实践的系统会拥有下列功能和属性:

·镜像起源:安全标签系统落实到位,负责识别生产环境中运行的容器到底确切地来自哪里。

·安全扫描:镜像扫描工具自动检查所有镜像,查找已知漏洞。

·审查:生产环境定期接受审查,确保所有容器都基于最新的容器,主机和容器都得到了安全配置。

·隔离和最低权限:使用最少资源和最低权限运行的容器需要高效运行。它们不能对主机或其他容器造成不当的干扰。

·运行时威胁检测和响应:这种功能检测运行时环境中的容器化应用程有没有活跃威胁,并自动采取响应措施。

·访问控制:AppArmor或SELinux等Linux安全模块用来执行访问控制。

镜像起源

企业要认真对待运行的软件,尤其是生产环境中的软件。避免运行过期、易受攻击的软件,或避免已受到某种破坏或篡改的软件,这点至关重要。由于这个原因,能够识别和验证任何容器的来源,包括谁构建了容器,它到底在运行哪个版本的代码,这很重要。

镜像起源的黄金标准是Docker Content Trust(https://docs.docker.com/engine/security/trust/content_trust/)。启用Docker Content Trust后,一个数字签名被添加到镜像,然后镜像被推送到注册中心。获取镜像时,Docker Content Trust会验证签名,从而确保镜像来自相应的企业,确保镜像内容完全符合被推送的镜像。这确保攻击者没有篡改镜像,无论在传送过程中,还是存储在注册中心时。Docker Content Trust还通过实施更新框架(TUF),可以预防其他更先进的攻击,比如回滚攻击和冻结攻击。

撰写本文时,Docker Content Trust得到了Docker Hub、Artifactory和Docker Trusted Registry(目前处于实验阶段)的支持。可以用Docker Content Trust来搭建开源的专用注册中心,但是这还需要搭建一台Notary服务器(欲知详情,请参阅这些说明:https://docs.docker.com/engine/security/trust/content_trust/)。

要是没有Docker Content Trust,仍可以使用摘要(digest)来验证镜像起源,摘要就是镜像内容的密码散列。镜像被推送后,Docker客户机返回表示镜像摘要的一个字符串(比如sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2)。然后,这个摘要可用于获取镜像。只要以这种方式获取镜像,Docker就会验证摘要与镜像匹配。不像标记,摘要总是会指向同一个镜像;镜像的任何更新都会导致新的摘要生成。使用摘要存在的问题是,企业需要搭建一个专有系统,用于自动提取并分发摘要。

还需要明确来自第三方的镜像的起源,无论它们直接使用,还是用作基本镜像。使用Docker Hub时,所有“官方”镜像已得到Docker的审核,附有内容信任信息,应该被视为是最安全的Hub镜像。使用其他镜像应谨慎行事,不过要注意:“自动化构建的镜像”连接到构建所使用的源代码,应该被认为比普通的用户镜像更值得信赖。企业应考虑自行从源代码构建镜像,而不是从不可信的库来获取。由于Docker Store(https://store.docker.com)的出现,这种情况目前在发生一点变化。Store将为发布者提供一个可信赖的商店,运作方式如同苹果的应用程序商店。

安全扫描

Docker镜像的安全扫描是几家公司提供的一项新服务。基本想法很简单:拿来Docker镜像后,将镜像包含的软件与已知安全漏洞列表相互对照,为镜像出具一份“健康证明”。基于这些信息,企业随后就可以采取行动,缓解安全漏洞。

目前的产品包括红帽的Atomic Scan、IBM的Bluemix Vulnerability Advisor、CoreOS的Clair、 Docker公司的Docker Security Scanning、Aqua Security的Peekr以及Twistlock Trust。无论工作方式、访问方式还是成本,它们都大不一样。一个关键的区别在于扫描工具识别安装在镜像中的软件的方式。

包括Clair在内的一些扫描工具会质询软件包管理器(比如Debian和Ubuntu上的Apt),以查找已安装的软件,但是这对通过打包软件(tarball)安装的软件来说行不通;如果扫描工具无法识别软件包管理器,也行不通。相比之下,Docker Security Scanning对镜像执行二进制代码层面的分析;无论是什么软件包管理器,这种方法都适用,还能识别静态链接库的版本。Twistlock也值得关注,原因在于它可以对通过打包文件安装的软件执行扫描,漏洞扫描能够发现零日攻击,并且可在严加隔离的环境下工作。

考虑安全扫描如何整合到你的系统中至关重要。Docker Security Scanning可作为Docker Cloud和Docker Datacenter的一个组成部分,而不是作为一项独立服务。其他提供商提供应用程序接口(API),允许整合到现有的CI系统和定制工作流程中。一些扫描工具可安装在本地环境,这对要求所有软件都放在内部的企业来说很重要。

一旦你已整合了安全扫描服务,首先想到的可能是全面禁止存在安全漏洞的任何镜像在生产环境中运行。遗憾的是,你很可能会发现,你的大多数镜像存在一些漏洞,全面禁止在现实中不是一个办法。比如说,Ubuntu向来以迅速更新镜像而著称,但是在撰写本文时,由于使用的Perl版本,16.04基本镜像随带一个重大的安全漏洞(其他大多数镜像存在的问题多得多)。因此你可能会发现,需要逐个调查发现的漏洞,确定它们是不是果真对系统构成了重大风险。

如果使用去除了不必要软件的轻量级容器,就可以大大缓解这种情况。要做到这一点,最简单的方法就是,使用非常小巧的基本镜像,比如Alpine,大小只有5MB。另一种有点极端的方法就是,构建静态链接二进制代码,然后把代码拷贝到“空空如也”的镜像上。这样一来,根本不存在操作系统层面的漏洞。这种方法的主要缺点是,构建和调试变得复杂许多,甚至没有外壳可用。

对业界的安全人士来说,自动化扫描向前迈出了一大步。它迅速发现潜在风险,并对厂商施压、要求及时给易受攻击的基本镜像打补丁。通过关注扫描结果、迅速反应,企业才能比许多潜在的攻击者领先一步。

审查

紧随安全扫描和镜像起源的就是审查。我们希望能够随时看到哪些镜像在生产环境下运行,它们在运行哪个版本的代码。尤其是,识别哪些容器在运行过期、可能易受攻击的镜像很重要。

使用容器时,强烈建议遵循有时所谓的“黄金镜像”方法:别给运行中的容器打补丁,而是把它们换成运行更新后代码的新容器――蓝绿部署和滚动升级可以用来避免停机。使用这种方法,只要查看构建所用的镜像,就可以审查数量众多的运行中的容器。Docker diff之类的工具可用来验证容器文件系统没有偏离底层镜像。

请注意:在部署镜像之前扫描镜像还不够。新的漏洞报告后,之前拥有健康证明的镜像会变得已知易受攻击。因此,不断扫描生产环境中运行的所有镜像很重要。是否需要深入的重新扫描,这取决于具体使用的扫描解决方案;扫描工具可以列出镜像已扫描的软件,并迅速拿来与新的漏洞作一比较。

审查基于容器的系统下的主机仍然很重要,但是如果运行极简发行版,比如CoreOS、Red Hat Atomic或Ubuntu Snappy,可以简化这一步,这类发行版被设计成可运行容器,所含的需要审查的软件比较少。另外,Docker Bench for Security等工具可用于核查配置,Aqua Security和Twistlock都提供了审查主机和配置的解决方案。

隔离和最低权限

容器的一大安全好处就是添加了隔离方面的工具。容器的工作原理是,构建一种在文件系统、网络和进程方面有着不同世界观(即独立命名空间)的系统。另外,控制组(cgroup)用于控制对处理器和内存等资源访问的级别。此外,可以通过Linux功能和seccomp,控制容器做出的Linux内核调用。

信息安全领域的基本概念之一是最低权限原则,这个原则最初是这样阐述的:

“系统的每一个程序和每一个特权用户都应该使用完成工作所必需的最低权限来操作。” —Jerome Saltzer

就容器而论,这意味着每个容器应该以有效操作所需的最低权限来运行。运用这个原则使攻击者的日子难过得多;即使发现了某个容器的漏洞,攻击者也很难有效地利用弱点。如果容器无法访问易受攻击的特性,它就不会被坏人利用。

一个有效而简单的安全措施就是运行拥有只读文件系统的容器。在Docker中,只要将–read-only标志传递给docker run,就能做到这一点。这一步落实到位后,利用漏洞的任何攻击者会发现对系统做手脚困难得多;他们无法将恶意脚本写入到文件系统,也无法篡改文件内容。许多应用程序想要写出到文件,但是针对特定的文件或目录使用tmpfs(https://docs.docker.com/engine/reference/run/#tmpfs-mount-tmpfs-filesystems)或卷,就可以支持这一点。

限制对其他资源的访问同样有效。限制容器可用的内存量将防止攻击者耗用主机上的所有内存,导致其他运行中的服务无内存可用。限制处理器和网络带宽可以防止攻击者运行耗用大量资源的进程,比如比特币挖掘或种子文件节点(Torrent peer)。

在生产环境中运行容器时最常见的错误也许是容器以root用户的身份来运行。构建镜像时,通常需要root权限来安装软件、配置镜像。然而,容器启动时执行的主进程不该以root的身份来运行。如果这么做,黑客只要危及进程,就会在容器里面拥有root层面的权限。最糟糕的是,由于用户在默认情况下并不使用命名空间,万一攻击者设法摆脱容器、进入到主机,他们也许能够对主机获得root层面的全部权限。

为了防止这种情况,应始终确保Dockerfile声明非特权用户,执行主进程之前切换到该用户。自Docker1.10以来,就有支持启用用户命名空间的选项,这会自动将容器中的用户映射到主机上的高编号用户。这一招管用,但目前有几个缺点,包括使用只读文件系统和卷存在问题。许多这些问题在Linux社区的上游得到了解决,因此预计在不远的将来,用户命名空间支持对更大比例的使用场合而言会变得更切实可行。

限制容器所做的内核调用也能显著减小攻击面,一方面限制攻击者能做的破坏,另一方面减小内核代码面临漏洞的风险。限制权限的首要机制是使用Linux功能。Linux定义了约40种功能,它们映射到一组组内核调用。容器运行时环境(包括rkt和Docker)让用户可以选择容器应以哪些权限来运行。这些功能映射到约330个系统调用,这意味着几种功能(尤其是SYS_ADMIN)映射到大量调用。想对允许哪些内核调用实行更精细的控制,Docker现在拥有seccomp支持,用于指定到底可以使用哪些调用,并随带一个默认的seccomp策略,它已证明在缓解Linux内核的问题方面颇有成效。这两种方法的主要问题就是,要搞清楚你的应用程序需要做出的一组最少的内核调用。仅仅以不同级别的功能来运行、查找故障很有效但很费时,可能会错过未测试的部分代码中的问题。

现有工具可能有助于确定应用程序使用系统调用的情况,而不是求助于反复试错。如果你能借助跟踪功能(比如strace2elastic)完全演练应用程序的代码路径,这将报告容器运行过程中在你的应用程序里面使用的系统调用。

虽然操作系统层面的隔离和实施最低权限至关重要,但隔离还需要与应用程序逻辑联系起来。如果不了解在主机上运行的应用程序,操作系统层面的隔离可能本身不是很有效。

运行时威胁检测和响应

不管你在漏洞扫描和容器加固方面的工作做得多好,运行时总会出现未知的代码错误和安全漏洞,会引起入侵或泄密。这就是为什么为系统添置实时威胁检测和事件响应功能很重要。

相比整体式应用程序,容器化应用程序明显来得更精简、不可改变。这就有可能为你的应用程序设定基线,其逼真度比传统的整体式应用程序来得更高。使用该基线,你应该能够检测实时威胁、异常情况和安全隐患,误报率低于传统的异常检测系统。

行为基线是2016年黑帽大会上最热门的潮流之一,它是指,安全机制专注于了解应用程序或系统的典型行为,从而识别异常情况。行为基线的关键是让设定基线、持续监控以及检测和响应尽可能实现自动化。如今,大多数企业结合手动劳力和数据科学来获得行为基线。然而,由于容器具有瞬时性,整个过程自动化显得尤为重要。

主动式响应与基线相辅相成。主动式反应是指一旦检测到威胁,如何应对攻击、泄密或异常情况。响应可能有多种不同的形式,比如提醒相关人员、与企业故障单系统进行联系,或者对系统和应用程序采取一些预先确定的纠正措施。

在容器环境下,主动式响应可能意味着执行额外的日志,运用额外的隔离规则,动态禁用用户,甚至积极删除容器。自动化在这里又是关键――执行的所有操作不得对应用程序逻辑带来负面影响,比如让系统处于不一致的状态,或者干扰非幂等操作。

目前提供这种级别的运行时威胁检测和响应的一些产品包括:Aqua Security、Joyent Triton SmartOS、Twistlock和红帽OpenShift。随着越来越多的关键任务型应用程序迁移到容器,运行时威胁检测和响应自动化对容器安全而言将越来越重要。想针对容器化环境扩展运行时安全体系,唯一的办法就是能够关联信息、分析攻陷指标、管理取证及响应动作,而且这一切采用自动化方式。

访问控制

Linux内核支持在执行内核调用之前执行策略的安全模块。两种最常见的安全模块就是AppArmor和SELinux,两者都实现了所谓的强制访问控制(MAC)。MAC可核查用户或进程有权对某个对象(比如文件、套接字或进程)执行各种操作,比如读取和写入。访问策略集中定义,而且无法由用户改变。与之形成对比的则是文件和权限的标准Unix模式:拥有足够权限的用户随时可以更改,这有时又叫自由访问控制(DAC)。

SELinux最初由美国国家安全局(NSA)开发,但现在主要由红帽开发,用在红帽的发行版中。虽然使用SELinux确实另外添加了一道强大的安全层,但用起来有点难度。一旦启用SELinux,你会注意到的头一件事就是,卷无法正常工作,需要额外的标志来控制卷的标签。AppArmor很相似,但不如SELinux来得全面,对于卷缺乏同样的控制。默认情况下它在Debian和Ubuntu发行版上已被启用。

在这两种情况下,可以制定特殊的策略,以便运行特定的容器,比如运行Apache或NGINX的Web服务器策略,允许某些网络操作,但是不允许其他各种调用。理想情况下,所有镜像都有各自专门制定的策略,但是制定这类策略往往是令人沮丧的过程,bane等第三方工具有一点帮助。在将来,我们预计会看到与容器如影相随的集成式安全配置文件,为内核调用、SELinux/AppArmor配置文件和资源需求指定设置。

进一步探讨访问控制话题,有必要指出:有权运行Docker容器的人实际上拥有该主机的root权限――他们可以挂载和编辑任何文件,或者创建可以拷回到主机的setuid(一旦执行就设置用户ID)二进制代码。在大多数情况下,这一点完全要注意,但一些企业希望对用户权限拥有更细粒度的控制。为此,企业可能应该考虑使用更高级的平台,比如Docker Datacenter和OpenShift,或者是Aqua Security和Twistlock之类的工具,添加这类控制。

结论

企业在实施基于容器的工作流程或在生产环境中运行容器时,考虑安全至关重要。安全影响整个工作流程,需要一开始就考虑进来。镜像起源始于开发人员在笔记本电脑上构建、获取和推送镜像,然后通过持续集成和测试阶段,最后终于容器在生产环境下运行。

容器和黄金镜像方法带来了新的工作方式和新的工具,尤其是镜像扫描和审查方面。企业更能够跟踪了解生产环境下运行的软件,而且极容易、极快速地应对安全漏洞。更新后的基本镜像可以在短短几分钟内测试、集成和部署。镜像签名证实了容器的真实性,确保攻击者没有篡改容器的内容。

由于经过验证和签名的镜像变得很常见,集成式安全配置文件等功能添加以来,未来会出现更重要的功能。在今后几个月,单单安全优点就是企业向容器迁移的一个充分理由。

本文转自d1net(转载)

网友评论

登录后评论
0/500
评论
晚来风急
+ 关注