1.3 持续安全
持续安全由三个领域组成,图1.4中已由三个带编号的方框标出。每一个领域都聚焦于DevOps流水线的一个特定方面。客户的反馈刺激了组织的扩张,从而驱动出新的特性,这一过程也适用于持续安全。本书分为三个部分,每一部分分别覆盖了持续安全的一个领域:
•测试驱动安全(TDS,Test-Driven Security)——保障程序安全的第一步就是定义、实现并测试安全控制。TDS覆盖了简单的安全控制,比如Linux服务器的标准配置,还有Web应用必须实现的安全标头。通过持续地实现基本的安全控制,并不断地测试这些安全控制的准确性,可以获得极大的安全感。在实施得不错的DevOps中,人工测试应该是例外而不是规则。安全测试的处理方式和所有应用测试的处理方式一模一样:自始至终都要自动化。我们将在第1部分中通过在一条简单的DevOps流水线中应用多个层次的安全控制来介绍TDS。
图1.4 持续安全的三个阶段通过反馈环不断地改进安全性来保护组织的产品和客户。
•攻击监控与应对——在线服务命中注定会受到威胁。当事件发生时,组织会向安全团队求助,团队必须准备好应对之策。持续安全的第2个阶段就是监控和应对风险,保护组织赖以生存的服务和数据。在第2部分里,我将讨论欺诈和入侵检测、数字取证及事件响应等技术,目的是让组织在面对突发事件时能够更从容。
•评估风险并完善安全性——本书的前两个部分大多谈的是技术,但安全策略如果只是关注技术问题,则不能称之为成功。持续安全的第3个阶段将跳出技术范畴,在更高的层面观察组织的安全形势。在第3部分里,我将说明风险管理和安全测试(包括内部的和外部的)是如何帮助组织重新聚焦于安全上的投入,并把好钢用在刀刃上。
成熟的组织信任它们的安全程序,而且会和它们的安全团队紧密协作。要做到这一点,组织需要专注、经验及良好的意识,即知道什么时候承担风险及什么时候规避风险。全面的安全策略要结合技术和人员,识别出可以改进的方方面面,并且合理地分配资源,所有这些都发生在快速完成的改进周期中。本书的目的就是为你提供能让组织达到这种成熟度的工具。
将持续安全的模型铭记于心,现在让我们详细了解它的三个部分,以及它们在产品安全方面的含义。
1.3.1 测试驱动安全
只用手机就能突破层层防火墙或是破解密码,这样的黑客神话只是电影大片里的噱头,真实世界里鲜有这样的事情发生。在大多数情况下,攻击者会挑软柿子捏:有安全漏洞的Web框架,过时的系统,密码容易被猜到且可以公开访问的管理页面,以及不小心泄露在开源代码里的安全凭证,这些都是攻击者喜欢的目标。实现持续安全策略的第一个目标就是守住底线:在组织的应用和基础设施上使用基本的安全控制集并持续地进行测试。例如:
•所有系统的SSH root登录必须禁用。
•系统和应用必须在最新可用版本发布后30天内升级补丁。
•Web应用必须使用HTTPS,禁用HTTP。
•严禁在应用代码中保存密码和凭证,它们只能单独保存在保险库中,只有运维人员可以访问。
•管理界面必须被保护起来,并且只能通过VPN访问。
安全团队、开发人员及运维人员之间应该建立安全最佳实践清单,以确保每个人都认同其价值。通过收集这些最佳实践并加入一些常识,基线需求的列表很快就可以建立起来。在本书的第1部分中,我将介绍确保应用、基础设施及CI/CD流水线安全性的各个步骤。
应用安全性
现代Web应用暴露在大量的攻击之下。开放Web应用安全项目(OWASP,Open Web Application Security Project)发布了排名在前十名的最常见的攻击手段(链接1.4):跨站脚本攻击、SQL注入攻击、跨站请求伪造、暴力攻击,等等,似乎数不胜数。幸运的是,每一种攻击向量都可以通过在正确的地方使用正确的安全控制来化解。在讨论应用安全性的第3章里,我们将深入了解为了保障Web应用安全,DevOps团队应该实现的安全控制。
基础设施安全性
依靠IaaS运行软件并不能让DevOps团队高枕无忧,从而不用去关心基础设施的安全性。所有系统都有对外授予更高权限的入口,比如VPN、SSH网关,或者管理面板。随着一个企业的不断扩张,在开放新的入口和集成更多模块时,必须一直小心翼翼地保护好系统和网络。
流水线安全性
DevOps交付产品的自动化方式和大多数安全团队熟悉的传统运维方式完全不同。破坏CI/CD流水线只会把运行在生产环境中的软件的控制权拱手让给攻击者。在从代码提交到生产环境部署的这个过程中,采用的自动化步骤可以使用提交签名和容器签名这样的完整性控制来保护。我将介绍如何增加组织对CI/CD流水线的信心,以及如何保证生产环境中运行的代码的完整性。
持续测试
在刚刚定义的三个领域中,对于任意一个领域中的应用来说,安全控制单独实现起来都相当简单。困难来自随时随地测试和实现它们。这就是TDS该发挥作用的时候了。TDS是一种类似测试驱动开发(TDD,Test-Driven Development)的方法。TDD建议开发人员先编写表达期望行为的测试,然后再来编写满足测试的代码;TDS建议先编写表达期望状态的安全测试,然后再实现让测试通过的安全控制。
在传统环境中很难实现TDS,因为测试必须在运行了多年的系统上执行。而在DevOps中,软件或基础设施的每一次变更都要经过CI/CD流水线,这非常适合实施TDS,如图1.5所示。
图1.5 测试驱动安全被融入CI/CD之中,以便在部署到生产环境基础设施之前执行安全测试。
TDS方法带来了不少好处:
•编写测试强迫安全工程师澄清期望并记录成文档。工程师可以在全面理解所需安全控制的情况下构建产品,而不是亡羊补牢。
•安全控制必须要小且有针对性才容易测试。要避免像“加密网络通信”这样含糊的需求,而应该明确地说明“强制所有传输使用采用了密码套件X、Y及Z的HTTPS”,这样的描述才能清晰地表明期望。
•跨产品重用测试的可能性很大,因为大多数产品和服务共享同样的底层基础设施。一套基线测试一旦完成,安全团队就可以把精力集中到更复杂的任务中了。
•缺失的安全控制会在部署之前被发现,这让开发人员和运维人员能有机会在客户被置于风险之前解决这些问题。
TDS方法中的测试一开始会失败。这是符合预期的,在特性实现之后,通过这些测试就能验证它们的正确性。首先,安全团队应该帮助开发人员和运维人员在软件和基础设施中实现安全控制,一条测试接一条测试地提供实现指导,最终将测试转交给DevOps团队。如果测试通过,团队就能确信安全控制被正确地实现了,并且测试应该再也不会失败。
TDS的一个重要部分是把安全当成产品的一个特性来对待。这一特性可以通过直接在产品的代码或系统中实现安全控制来完成。将安全建立在应用和基础设施之外的安全团队很可能会形成缺乏信任的文化。我们应该远离这种方式。它不仅会造成团队之间的紧张气氛,而且它提供的安全性也很糟糕,因为安全控制如不知道应用的准确行为就会遗漏一些内容。安全策略如果不是由工程团队来主导,那么就注定不会长久,并且会随着时间推移慢慢退化。对安全团队来说,定义、实现和测试的工作非常重要,但是将关键组件的主导权委托给正确的人同样非常重要。
TDS吸收了流水线自动化和团队紧密协作的DevOps原则。它强迫安全人员在开发人员和运维人员所采用的环境中构建和测试安全控制,而不是构建自己独立的安全基础设施。通过TDS覆盖安全基础可以显著降低服务被破坏的风险,但是对生产环境的监控依然不能放松。
1.3.2 攻击监控与应对
安全工程师在无聊的时候喜欢玩游戏。2005年,我们曾经玩过一个很流行的游戏:将完全没有打过补丁的Windows XP安装在一个虚拟机上,然后直接接入互联网(没有防火墙,没有杀毒软件,也没有代理),接下来就是等待。你能猜到它多久会被攻击?
由恶意软件制造者操纵的扫描器很快就发现了这个系统,然后向它发送了一段漏洞利用代码,这只是众多攻击Windows的漏洞利用代码中的任意一种。在几小时之内,系统就会被攻破,并敞开后门让更多的病毒感染系统。隔岸观火挺有趣,但更重要的是,它给我们上了重要的一课:所有连接到互联网的系统最终都会被攻击——无一例外。
在公共互联网上运营受欢迎的服务,本质上和上面的Windows XP试验是一样的:在某一时刻,扫描器会发现它并尝试入侵。攻击可能会以特定用户为目标并尝试猜测他们的密码,也可能会中断服务索要赎金,或者可能会利用基础设施的漏洞进入数据层盗取信息。
现代组织十分复杂,要想用合理的成本覆盖每一个角落基本上是不可能的。安全团队必须权衡优先级。我们的攻击监控与应对方法集中在以下三个方面:
•日志和欺诈检测。
•入侵检测。
•事件响应。
如果组织能做到以上三项,那么就是做好了应对安全事件的准备。我们来概要地看一下这三个方面。
日志和欺诈检测
日志的生成、保存和分析在组织的每一个部分都发挥着作用。开发人员和运维人员需要日志来跟踪服务的健康度。产品经理使用它们来度量特性受欢迎的程度或是用户留存率。对安全性来说,我们要关注两个特定的日志需求:
•检测安全异常。
•在调查事件时提供取证能力。
日志收集和分析达到理想化的要求几乎是不可能的。海量的数据使存储变得不切实际。在本书的第2部分,我将介绍如何选择用于安全分析的日志,并将重点集中在DevOps流水线的特定部分上。
我们将探讨日志流水线的概念,它处理并集中来自各种日志源的日志事件。日志流水线十分强大,因为它提供了一条可以执行异常检测的单一管道。和每个组件自己执行检测相比,它的模型更简单,但是它在大型环境中的实现可能比较困难。图1.6概括了日志流水线的核心组件,我将在第7章详细介绍它们。
图1.6 日志流水线实现了一个标准的管道,基础设施产生的事件可以在这里分析并存储。
日志和流水线包含了五层:
•用于记录来自基础设施各个组件的日志事件的收集层。
•用于捕捉和路由日志事件的流式处理层。
•用于检查日志内容、检测欺诈并告警的分析层。
•用于归档日志的存储层。
•允许运维人员和开发人员访问日志的访问层。
强大的日志流水线为安全团队提供了监控基础设施所需的核心功能。我将在第8章介绍如何在日志流水线中建立起一个可靠的分析层,并展示各种关于监控系统和应用的有效技术。这将为我们在第9章学习入侵检测打下基础。
入侵检测
在入侵基础设施时,攻击者通常会按照以下四个步骤执行:
1.在目标服务器上留下恶意载荷。恶意载荷是一种非常小的后门脚本或恶意软件,小到可以被下载和执行而不会引起注意。
2.一旦部署,后门便会与母船建立联系,通过命令与控制(C2,Commandand-Control)信道接收进一步指令。C2信道可以采用很多种形式,包括:出站IRC连接,在正文中隐藏特殊关键字的HTML页面,或者在TXT记录中嵌入命令的DNS请求。
3.后门执行指令并在网络中扩散,扫描并入侵其他主机直到发现有价值的目标。
4.找到目标后,攻击者势必要盗取其中的数据,很可能是通过另一条和C2信道平行的信道来盗取这些数据。
在第9章,我将说明一个机警的安全团队如何检测每一个步骤。我们的重点是观察和分析使用下面这些工具的网络流量和系统事件:
•入侵检测系统(IDS,Intrusion Detection System)——图1.7展示了IDS如何通过持续不断地分析网络流量副本,以及如何通过持续不断地在网络连接上应用可检测欺诈活动的复杂逻辑,来检测C2信道。IDS擅长对千兆字节的网络流量中的欺诈活动模式进行实时检查。我们将探索怎样在IaaS环境中使用它。
图1.7 入侵检测系统通过寻找欺诈活动的模式及对出站流量的系统分析,能够发现被破坏的主机和母船的联系。
•连接审计——分析经过基础设施的全部网络流量有时是不现实的。NetFlow提供了另一种审计网络连接的方式,它通过将连接信息记录在流水线中的方式来进行审计。当无法访问底层时,NetFlow是审计IaaS基础设施中的网络层活动的好方法。
•系统审计——对线上系统的完整性进行审计是跟踪整个基础设施中发生的一切事情的绝佳方法。在Linux中,内核的审计子系统可以记录在系统中执行的所有系统调用。攻击者在入侵系统时常常会在这种类型的日志中留下蛛丝马迹,将这些审计事件发给日志流水线可以帮助我们检测到入侵。
入侵检测难度很大,常常需要安全团队和运维团队密切合作。如果操作不当,这些系统就会占用本该用于运营生产服务的资源。你将了解如何用一种渐进的和谨慎的方式帮助入侵检测有效地融入DevOps之中。
事件响应
在任何组织中,遇到的最紧张的情况或许就是处理安全事故了。即使是最稳定的公司,安全事件给公司带来的混乱和不确定性也可能严重破坏其健康运转。在工程团队手忙脚乱地恢复系统和应用的完整性时,领导层也必须做好止损,并确保业务能尽快恢复正常运营。
我将在第10章介绍组织在应对安全事件时应该遵循的一套六阶操作手册。它们是:
•准备——确保有一套处理安全事件的最精简流程。
•识别——迅速判断异常是否是安全事件。
•隔离——阻止破坏进一步扩散。
•杀灭——消除对组织的威胁。
•恢复——恢复组织正常运营。
•总结——事后进行回顾并总结经验教训。
每一个安全事故都不一样,而且组织的应对方式也不尽相同,这使得为读者总结出一些可操作的建议变得十分困难。在第10章我们将用一个案例分析来介绍事件响应,这个案例展示了一家典型的公司所经历的混乱过程,以及它在这个过程中如何充分发挥DevOps技术的优势。
1.3.3 评估风险并完善安全性
完整的安全策略远远不是只涵盖实现安全控制和事件响应等技术方面的因素。持续安全中的“ 人”的因素才是实施风险管理的关键,在本书中,我们还会不断地说明这一点。
评估风险
对许多工程师和管理人员来说,风险管理就是制作花花绿绿的超大电子表格,任由它们在收件箱里堆积如山。不幸的是,这种现象屡见不鲜,这导致许多组织放弃了风险管理。在本书的第3部分,我将介绍如何打破这种模式,为DevOps组织带来简捷、高效的风险管理。
管理风险就是识别出威胁到生存和增长的问题,以及排列出它们的优先级。电子表格中的花哨的单元格的确有用,但那并不是重点。好的风险管理必须达到以下三个目标:
•频繁快速地以小迭代的方式运作。软件和基础设施会持续不断地变化,一个组织必须能够频繁地讨论风险,而不是陷进数周漫长的流程中。
•自动化!这是DevOps,手动操作只是例外,而不是规则。
•组织里的每个人都要求参加风险讨论。构建安全的产品和维护安全是整个团队的工作。
第11章将呈现一个实现了上述全部三个目标的风险管理框架。如果实施正确,它就能变成组织的真正资产,并成为组织中每个人都认可和追寻的产品生命周期中的核心组成部分。
安全测试
成熟的安全程序的另一个核心强项是能够通过安全测试定期评估自身的表现。在第12章,我们将探讨成功的测试策略如何在以下三个重要方面来帮助完善组织的安全性:
•使用漏洞扫描、模糊测试、静态代码分析或者配置审计等安全技术手段对应用和基础设施的安全性进行内部评估。我们将讨论多种可以集成到CI/CD流水线中的技术,它们将变成DevOps策略中软件开发生命周期(SDLC,Software Development Lifecycle)的一部分。
•利用外部公司来审计核心服务的安全性。如果目标正确,安全审计会给组织带来很多价值,并且有利于用新的思路和视角审视安全程序。我们将讨论如何有效地使用外部审计和“红军”,让它们充分发挥作用。
•建立漏洞报告奖励程序。DevOps组织通常会积极拥抱开源并公开发布大量源代码。对于独立安全研究人员来说,这是巨大的资源,他们会测试你的应用,并向你报告他们在安全性上的发现以换取几千美元的报酬。
完善一个持续安全程序需要好几年的时间,但这些时间投入会让安全团队变成一个组织产品策略中不可或缺的一部分。在第13章中,我们将讨论如何在三年时间内实施一个成功的安全程序,并为本书画上句号。通过跨团队的紧密合作及对安全事件的妥善处理和技术指导,安全团队将从他们的伙伴那里收获保障客户安全的信任。成功的持续安全策略的核心就是:将安全人员及其工具和知识尽可能地与DevOps中其他人拉近距离。