传统安全 SDL
传统的基于瀑布和敏捷开发的研发模式下,有很多软件安全开发的管理理论方法,比如 BSIMM(Building Security In Maturity Model)、SAMM(SoftwareAssurance Maturity Model)等。其中,一个行之有效并且大量地被 IT/互联网行业所使用的最佳安全实践被微软发明并向业界推荐,名称为安全开发生命周期(Security Development Lifecycle,俗称“SDL”),这套方法论和其中的最佳实践已经成为一些行业事实上的标准,国内外各大 IT 和互联网公司包括腾讯也都在基于这套理论和实践,结合自己的研发实际情况来进行研发安全管控。如下图可以看到整个过程,需要注意的是,SDL 本身并未关注运维,为了弥补这个缺陷,微软也推出了 OSA(Operational Security Assurance)。 SDL 在研发、测试之外定义了安全的角色,通过流程上的保证,使安全人员及其工作能够嵌入到研发过程中的各个环节,以此来降低产品中出现安全漏洞的风险。
DevOps 对 SDL 的挑战
DevOps 出现之后,问题也来了。传统意义上的 DevOps 只关注开发、测试、运维及其之间的协作,安全(Security)是被排除在外的。随着业务的复杂度以及商业价值的增加,安全问题也已然成为企业发展战略的关键组成部分。DevOps 中频繁的交付以及其他行为方式的改变事实上已经成为了双刃剑,对旧有的 SDL 这类研发安全管控思想、流程和工具形成了很大的挑战,也让研发安全问题越发不可控。DevOps 对传统安全 SDL 的挑战目前看主要体现如下等几个方面: 【弱化的设计过程使安全评估难以展开】 敏捷时代所倡导的“代码即设计”导致了开发人员在设计上花费的时间大大降低。许多 DevOps 团队更是进一步升级了这个思想,比如硅谷创业家 Eric Rise 在其著作《精益创业》一书中提出了“精益创业”(Lean Startup)的理念【附录 5】,其核心思想是,开发产品时先做出一个简单的原型——最小化可行产品(Minimum Viable Product,俗称“MVP”),然后通过 A/B test 等方式收集用户的反馈,快速迭代,不断修正产品,最终适应市场的需求。如果是失败的尝试,则尽快让它停止。这些会导致两个关键的问题,一个是安全人员要不要/有没有必要参与到其中,另一个是安全人员根本无法参与到设计阶段,无法去进行传统的针对设计方案的威胁建模和风险分析消除等工作。 【高速的交付让安全过程无从下手】 敏捷模式的研发过程可以将发布降低为 1~2 周,如果认为这个频次还能够承受的话。DevOps 下更加极端,有个公开的数据可以参考,亚马逊在整个 2014 年部署变更了 5000 万次以上,平均每秒部署 2 次变更。这个强度之下,传统的 SDL 实际上已经无法落地。 【云、微服务、容器等技术需要新的安全能力】 云技术的快速发展,特别是基础架构即服务(IaaS)和平台即服务(PaaS)等的技术,深刻地改变了我们进行系统架构和设计的思维模式。云的环境中包含了众多的开发、运维、管控及安全等的功能和产品,如账户管理、数据存储、加密和密钥管理、审计、故障处理、监控等等的服务和 API。举个例子,现在很多云都有 serverless 的服务,使用它如何来评估安全风险和安全责任呢?使用云,就意味着必须接受共享责任模型(SRM,美国国家安全局的一份报告中提出这个概念),一些云服务厂商称之为“责任共担模式”,需要了解云技术供应商和自己的责任范围以及如何确保云供应商执行了所要求的安全能力。此外,云服务用户会面临一些新的安全风险问题,可以参考 TreacherousTwelve。 微服务是许多成功实施了 DevOps 案例中的一部分,亚马逊和 NetFlix 围绕微服务构建系统和组织方面取得了巨大成功。但是微服务也有一些缺点,如操作复杂(单个微服务很容易理解,但是他们之间的互相关系和治理可能会超出人的理解能力)、攻击面分析困难(单个的攻击面可能很小,但是整个系统的攻击面可能很大,并且基于操作复杂的问题不容易看清楚)、边界不清晰(相比传统的三层结构的 Web 网站,数据流分析难以应用在微服务的架构中,因为不容易确定信任边界)、审计困难(除非使用统一的日志记录和审计机制,否则想要审计系统中众多的微服务是一件非常困难和高成本的事情)等。 容器特别是 docker 的发展和使用,也是 DevOps 的一个重要实践,它改变了传统的部署方式,与微服务等更容易结合。但是容器类技术也会带来另外的问题,比如资产识别问题(可能会遗漏,需要从基于 OS 或虚拟机的力度增加到容器力度,但是容器的使用又很灵活,快速的大量创建和销毁会使之成为很大挑战)、安全系统的兼容(比如一些主机入侵检测系统 HIDS 可能需要能够支持容器)、引入新的安全风险(如 内核溢出、容器逃逸、资源拒绝服务、有漏洞的镜像、泄露密钥等,都需要新的方法来应对,详情参考 Docker 的作者 Adrian Mouat 列出了使用 Docker 时需要注意的五个安全问题)。 【安全的职责分离原则被挑战】 传统思维中,职责分离(SoD,Segregation of Duties)是一个基本的要求。特别是审核和合规领域极其关注这一要求。试想一下,一条流水线可以从代码直接通到服务器上去运行。如何平衡这种便利性和安全性?此外,这一点也可以扩展到变更的安全管理上。每天有那么多变更,怎么来对这些变更进行有效管理?万一有次恶意变更呢(最近一次国内的删库跑路事件)?传统的审批模式因为阻碍自动化已经过时。有关变更的安全管理,有个案例可以很好的说明这一情况,骑士资本集团(KnightCapital Group)的一次失败变更使其在 45 分钟内就亏损了 4.6 亿美元。最终破产而被收购。 诸如此类的挑战,以及 SDL 本身固有的一些问题(如各个角色信息不对称、孤岛效应、意识不足、配合沟通困难、延误放大等)使得在 DevOps 潮流之下 SDL 逐渐变的困难重重。甚至有些悲观的看法认为 SDL 无法适应 DevOps 的出现,事实上已经死亡。微软可能也感受到这一压力,提出了“SecureDevOps”的概念和实践。
安全领域更深的思考
传统的 SDL 类的方式管控多年,但还是会有持续不断的大小公司被入侵和数据泄露等安全事件发生。另外如上所说,面对发展势头猛烈的 DevOps 这种研发思想和实践,传统的 SDL 已经渐感力不从心。无数的事实告诉我们一个道理,安全人员的角色不能仅仅是兜底,况且实际情况是根本无法兜底,所以需要引入一个重要的思维变化,也被如亚马逊首席技术官 Werner Vogels 等人反复在讲,安全需要每个工程师的参与。安全不再是单独安全团队的责任,是整个组织所有人的一致目标和责任,才能更好的对研发过程中的安全问题进行管控。这并不是一个推脱责任的说辞,实际上对安全团队的思维方式、组织形式和安全能力建设等提出了更高的要求。想要每个工程师在安全意识和安全能力上都达到专业安全人员的标准是不可能的,因此如何能够将安全要求和安全能力融合到 DevOps 过程中来,如何让安全赋能从而让整个组织既能够享受 DevOps 带来的好处又能够较好的管控安全风险变成是一个重要问题。这些思考也导致了 DevSecOps 思想的诞生以及一系列的解决方案的尝试。
DevSecOps 诞生
也是因为发现了上述的问题并且做了深入的分析研究之后,2012 年,Gartner 通过一份研究报告“DevOpsSec:Creating the Agile Triangle.”提出了 DevSecOps 的概念(备注:有一些同样意思的名词如 SecDevOps、DevOpsSec 甚至是 RuggedDevOps,本文中统称 DevSecOps)。在这份研究报告中,确定了信息安全专业人员需要积极参与 DevOps 计划并忠实于 DevOps 的精神,拥抱其团队合作、协调、敏捷和共同责任的理念。也即是,完全遵循 DevOps 的思想,将安全无缝集成到其中,使之升级成为 DevSecOps。2016 年,同样是 Gartner 这个研究机构,公开了一份名为“DevSecOpsHow to Seamlessly Integrate Security Into DevOps”的研究报告,更加详细的阐述了 DevSecOps 理念和一些实践。Jim Bird 也在书籍《DevSecOps:Securing Software through Continuous Delivery》归纳总结了不错的思考和实践。想要深入了解 DevSecOps,这几个原汁原味的资料个人非常推荐。做为 Gartner 近年来主推的一个研发安全的概念,它持续地通过研究报告推动着该领域的发展。一个对 DevSecOps 最简单直观的图示如下图: 这一安全研发体系的概念和实践特别是最近几年越发被业界所重视,谷歌趋势可以看到关注度的增加。 所以,问题的关键就变成了如何遵循 DevOps 的思想,将安全无缝地集成其中?以下从原则以及实践两个方面展开详细论述。