2.3 技术:工具与自动化
前面介绍了实现DevSecOps需要基于敏捷开发和持续交付的方法论,并且整个DevSecOps的过程涵盖了软件开发的整个生命周期(图2-8)。本节主要针对DevSecOps涵盖的整个开发、测试、运维过程,简单介绍各个领域常见的开源工具,它们将帮助团队实现DevSecOps落地,从而实现更快、质量更好和更安全的业务交付。
图2-8 研发流程生命周期
2.3.1 项目管理工具
目前市场上最流行的项目管理工具是Atlassian开发的Jira。它支持迭代和看板的敏捷开发模式。Jira中的Workflow功能提供了一种可视化方式,帮助团队更加容易并且自动地管理流程。Service Desk功能提供了一种对业务和产品进行技术支持的工单系统。Jira有着丰富的插件市场,可以与Jenkins、GitHub等工具进行集成,从而可以将代码仓库、构建和相关的任务或缺陷进行关联,并且可以通过插件进行数据的收集和统计,帮助产品/项目经理分析项目数据。
2.3.2 源代码管理工具
Git是一个开源的分布式版本管理工具。作为分布式版本控制工具,Git没有中央服务器的概念,开发人员可以把代码完整地镜像到本地,从而摆脱了对网络的依赖。另外,Git提供了一些特有的分支功能(如主分支、发布分支、开发分支、功能分支、缺陷修复分支等)以及不同的分支策略。目前市场上比较流行的基于Git的开源和商用代码托管工具有GitHub、GitLab和Bitbucket(之前称Stash)。
GitHub是一个基于网页端的开源源代码管理工具。它有支持公共的和有限私有项目的开源版本。到目前为止,GitHub可能拥有最多的代码仓库和3800多万个项目(其中有近2000万个开源项目)。在2018年被微软收购之后,GitHub可以更好地支持微软的产品。GitLab和GitHub做的事非常相似,但是GitLab可以创建私人的免费仓库。所以从私有性上来看,GitLab是一个更好的选择。但对于开源项目而言,GitHub依然是代码托管的首选。
2.3.3 静态代码扫描工具
目前市场上最流行的开源代码扫描工具是SonarQube,另外FindBugs(Java)、FxCop (.NET)、CppCheck(C++)、Pylint(Python)等开源工具可以对单一开发语言进行支持。
SonarQube是一个代码质量管理开源平台,用于管理源代码的质量。同时SonarQube还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用SonarQube。此外,SonarQube的插件还可以对Java以外的其他编程语言提供支持。通过插件形式,可以支持包括Java、C#、C/C++、PL/SQL、Cobol、JavaScript等二十几种编程语言的代码质量管理与检测。SonarQube在进行代码质量管理时,会从七个维度来分析项目的质量:不遵循代码标准;潜在的缺陷;糟糕的复杂度分布;重复;注释不足;缺乏单元测试;糟糕的设计。
FindBugs是一个在Java程序中查找Bug的程序,它查找Bug模式的实例,也就是可能出错的代码实例,FindBugs是检查Java字节码,也就是*.class文件。其实准确地说,它是寻找代码缺陷的,很多我们写得不好或可以优化的地方,它都能检查出来。例如,未关闭的数据库连接,缺少必要的null check,多余的null check,多余的if后置条件,等等。而且我们还可以自己配置检查规则,也可以自己实现独有的校验规则(用户自定义特定的Bug模式需要继承它的接口。编写自己的校验类属于高级技巧)。
FxCop是一个代码分析工具,它依照微软.NET框架的设计规范对托管代码assembly(可称为程序集,assembly实际上指的就是.NET中的.exe或者.dll文件)进行扫描。大多数代码分析工具扫描你的源代码,但是FxCop直接对你编译好的制品进行处理。.NET的每个assembly都有其metadata(可称为元数据,metadata是关于一个assembly中各元素的类型信息库,它本身也存放在这个assembly中),它对assembly以及assembly内用到的所有类型进行描述。FxCop会使用这个metadata获知代码内部的运行状况。
CppCheck是一个C/C++代码缺陷静态检查工具。不同于C/C++编译器及其他分析工具,CppCheck只检查编译器检查不出来的Bug,不检查语法错误。所谓静态代码检查就是使用一个工具检查我们写的代码是否安全和健壮,是否有隐藏的问题。CppCheck检查的信息包括:代码中的错误项,包括内存泄漏等;为了避免产生Bug而提供的编程改进意见;编码风格,提示你哪些函数没有使用、哪些为多余代码等;提示跨平台时容易出现的问题等。
2.3.4 静态应用安全测试工具
Checkmarx提供了一个全面的白盒代码安全审计解决方案,帮助企业在软件开发过程中查找、识别、追踪绝大部分主流编码中的技术漏洞和逻辑漏洞,帮助企业以低成本控制应用程序安全风险。CxSAST无须搭建软件项目源代码的构建环境即可对代码进行数据流分析。通过与各种SDLC组件的紧密集成,CxSAST可实现分析过程的完全自动化,并为审计员和开发人员提供对结果和补救建议的即时访问。其优点是规则自定义、集成性强,但缺点也非常明显:误报率很高(业界30%左右),而且随着代码量的增加,扫描速度逐渐变慢。
Fortify SCA是一个静态的白盒软件源代码安全测试工具。它通过内置的五大主要分析引擎——数据流、语义、结构、控制流、配置流,对应用软件的源代码进行静态分析,分析过程中利用它特有的软件安全漏洞规则集进行全面匹配、查找,从而将源代码中存在的安全漏洞扫描出来,并给予整理报告。其优点是速度快、精确率高,但Fortify SCA的集成性很差,需要做二次开发。
2.3.5 持续集成工具
Jenkins是最流行的开源的持续集成工具。Jenkins的功能非常强大,并且有很强大的社区和生态提供成百上千的插件来丰富其功能。Jenkins通过master实现中央控制和触发,利用slave在构建机执行操作命令,从而达到主从模式的管理体系。2016年,Jenkins颁布了它的全新版本Jenkins 2。它的亮点是将老版本中流水线插件的功能集成到Jenkins里,使其可视化,并且提出了一个新概念“Pipeline as Code”,通过脚本(Groovy)的形式对流水线进行配置。这种方式极大提高了流水线配置的灵活性,并且更受程序员欢迎,对于DevOps中“左移”的概念起到了非常好的支持。另外,Jenkins的商用版CloudBee在其基础上进行了扩展,不仅引入了“Operating Center”功能来管理多个Jenkins master,形成cluster管理模式,极大扩展了Jenkins的服务能力,另外也提供了流水线“Pipeline as Code”的模板功能,使用更加方便。
TeamCity是JetBrain公司的一款持续集成工具,有免费版(TeamCity Professional)和商用版两个版本。免费版支持3个agent和100个配置项目。对比Jenkins,TeamCity没有功能强大的“Pipeline as Code”和丰富的插件生态来扩展功能。但TeamCity有更加友好的界面以及内部集成的一些功能(比如MSTest、Nunit、Nuget),可以更好地支撑.NET开发,所以更受.NET开发人员青睐。
2.3.6 构建工具
Maven是最流行的Java构建配置和依赖管理工具。它使用了基于XML格式的POM(Project Object Model)文件,在类似模板化的命令下进行构建的配置管理,以及对于构建所需要的第三方依赖的管理。由于Maven操作简单、易学习,所以在Java开发中非常流行。然而,也由于POM文件是基于XML格式的,从而也限制了其灵活性。Gradle和Maven一样都是支持Java的构建工具,但是Gradle不是基于XML文件,而是基于Groovy的DSL(Domain Specific Language)进行配置管理。由于它是基于脚本编程而不完全是配置文件,执行速度快并且更加灵活,所以比较受程序员欢迎。
Maven和Gradle虽然流行,却都是用来支持Java开发的构建工具。对于.NET开发来说,MSBuild(Microsoft Build)却是首选。MSBuild也是基于XML文件的,并且独立于Microsoft Visual Studio。MSBuild平台主要涉及执行引擎、构造工程和任务,最核心的就是执行引擎,用来构造工程规范、解释构造工程和执行构造动作。
2.3.7 制品管理工具
目前市场上比较流行的开源制品库主要是Sonatype Nexus和Jfrog Artifactory。Nexus和Artifactory都提供了支持大部分开发语言的构建包(Maven、NuGet和NPM等)和容器镜像的制品管理仓库,从而形成统一的制品源,并且可以与主流持续集成工具(Jenkins等)实现很好的自动化集成。最后它们可以通过定义不同成熟度存储库,将制品在不同的成熟度存储库间移动,以及通过元数据属性,更好地管理和维护制品的生命周期。
2.3.8 第三方安全扫描工具
市场上几款主流的第三方安全扫描工具包括开源的Dependency-Check、商用工具Sonatype IQ Server和Jfrog X-ray。Dependency-Check是OWASP(Open Web Application Security Project)的一个实用开源程序,用于识别项目依赖项并检查是否存在任何已知的、公开披露的漏洞;目前已支持Java、.NET、Ruby、Node.js、Python等语言编写的程序,并为C/C++构建系统(autoconf和cmake)提供了有限的支持;另外,作为一款开源工具,在多年来的发展中已经支持与许多主流软件进行集成,比如Jenkins等;具备使用方便、落地简单等优势。Dependency-Check的依赖性检查可用于扫描应用程序(及其依赖库),执行检查时会将Common Platform Enumeration(CPE)国家漏洞数据库及NPM Public Advisories库下载到本地,再通过核心引擎中的一系列分析器检查项目依赖性,收集有关依赖项的信息,然后根据收集的依赖项信息与本地的CPE&NPM库数据进行对比,如果检查发现扫描的组件存在已知的易受攻击的漏洞则标识,最后生成报告进行展示。
2.3.9 自动化测试工具
自动化测试工具分为几大类:单元测试、功能测试和性能测试。单元测试针对不同开发语言,可以使用不同的开源单元测试框架。比如最流行的是支持Java的JUnit、支持C#开发的NUnit、支持C++开发的CppUnit,以及其他的xUnit成员,丰富了单元测试框架对各种不同语言的支持。为了统计单元测试的代码覆盖率,通常需要引用额外工具,比如Java常用的覆盖率统计工具是JaCoCo,C#常用的覆盖率统计工具是NCover、DotCover等。有些开发语言,比如Go,内置了单元测试统计功能,所以不需要额外工具支持。
功能和接口测试方面有很多测试工具。根据Survey on Test Automation Challenges的调研结果显示,Selenium是排名第一的开源UI自动化测试工具,被84%的测试人员在项目中使用。相比其他测试工具,Selenium是基于编程和脚本的自动化测试工具,并且支持多种开发语言(比如Java、Groovy、Python和Ruby等),这使得Selenium使用起来更加灵活,被程序员所青睐,所以非常符合DevOps左移的理念。
JMeter是一款开源的用做性能测试的自动化工具。它可以用来测试静态和动态资源的性能,也可以用于模拟大量负载来测试一台服务器、网络或者对象的健壮性或者分析不同负载下的整体性能。同时,JMeter可以对应用程序进行回归测试,通过测试脚本验证程序是否可以返回期望值。但是JMeter无法验证JS程序,也无法验证页面UI,所以须与Selenium配合来完成对相关网页应用的测试。
2.3.10 动态安全测试工具
动态安全测试工具通过模拟黑客的攻击行为对站点进行测试,从而检测是否存在安全漏洞。OWASP ZAP是一款OWASP社区提供的开源的网页安全扫描工具。OWASP ZAP的使用非常简单,只需要将URL地址填入,点击按钮就可以发起对输入网站的安全漏洞扫描,并将扫描结果(包括漏洞名称、风险级别等)展示在工具界面。OWASP ZAP可以与Jenkins进行集成以实现自动化动态安全扫描。其他常见的商用DAST软件有IBM AppScan、Webinspect、Burp Suite和AWVS。
2.3.11 交互式安全测试工具
交互式安全测试工具通过在测试环境进行插桩或者端口截流的方式,分析应用是否存在安全漏洞。国外比较成熟的工具是Contrast Security,其社区版(Contrast Security-Community)提供了一款免费的交互式安全测试解决方案。它具备与商业版同样的功能,但被限制了支持的开发语言(只支持Java和.NET Core),并且只允许安装在一台应用上。Contrast Security-Community可以通过测试环境的插桩,在程序应用时对其控制器、业务逻辑、数据层等的上下文信息进行截取分析,进而得到比SAST和DAST更加精准的安全漏洞收集和判断。
2.3.12 自动化配置/发布工具
自从基础设施即代码(Infrastructure as Code)这个概念出现以来,自动化配置/发布工具就得到了大范围的推广和应用。对于传统虚拟机和物理机的配置和部署,比较流行的有Ansible、Chef、Puppet和Salt。
Puppet是市面上最流行的自动化配置/部署工具之一。它通过在目标服务器安装代理,使用简单直观的CLI输入命令下载和安装模块。Puppet得益于一大批基于Ruby的模块和配置菜单,通过编写Ruby脚本更改配置文件,因此需要一定的编程能力。Chef和Puppet类似,通过在管理的节点上安装代理进行环境配置和部署的实现。
与Puppet和Chef不同,Ansible不是通过安装代理的方式对目标服务器进行任务执行的,而是通过SSH与目标服务器建立连接来执行所有功能,所以是一种轻量级环境配置工具。Ansible通过playbook进行YAML代码编写来实现配置管理,同时通过inventory进行集群服务器发布的控制。Salt和Ansible类似,也是基于CLI的工具,采用推送的方式实现客户端通信、配置安装和管理。
2.3.13 日志分析工具
目前市场上比较流行的开源日志分析工具是ELK(Elasticsearch, Logstash, Kibana),另外一款非常流行的商用日志分析工具是Splunk。
ELK是三个开源工具的组合,并且也是最流行的开源日志分析工具,用来解决日志收集、搜索、聚合和分析。
1)Elasticsearch是一套基于Lucene的搜索引擎工具,解决系统日志的搜索问题。
2)Logstash用来做数据源的收集。
3)Kibana是一套可视化工具,可以将日志分析后的数据进行展示。
Splunk是一个可扩展且可靠的数据平台,用于调查、监控、分析和处理企业的各类系统数据。如今的Splunk已经不仅限于对日志数据进行分析处理,其基于现代数据平台,在云上及线下帮助IT、安全和开发运维专业人员从任何来源获取任何数据,以便对其数据进行调查、监控、分析和快速采取行动。同时其支持集成AI和机器学习,以及具备为任何情况做好准备的云技术支持。
2.3.14 监控工具
Prometheus是一款CNCF(Cloud Native Computing Foundation)开源项目和分布式开源监控工具。它主要用于对基础设施的监控,包括服务器、数据库和VPS等。Prometheus通过对配置中定义的某些端点执行HTTP调用来检索。其主要功能仍然是时间序列数据库,并对它实现了可视化和数据分析,通过自定义方式进行警告。
另外一款开源的分布式监控工具是Zabbix,它以图形化方式展示和操作界面,是由Alexei Vladishev开发的一种网络监视、管理系统,基于Server-Client架构,可用于监视各种网络服务、服务器和网络机器等的状态。入门容易、上手简单、功能强大并且开源免费是用户对Zabbix的最直观评价,Zabbix易于管理和配置,能生成比较漂亮的数据图,其自动发现功能可大大减轻日常管理的工作量,丰富的数据采集方式和API接口可以让用户灵活进行数据采集,而分布式系统架构可以支持监控更多的设备。理论上,通过Zabbix提供的插件式架构,可以满足企业的任何需求。
Prometheus和Zabbix主要关注服务器硬件指标和系统的运行状态等。而属于开源APM系统的SkyWalking更重视程序内部执行过程指标和服务之间链路调用情况的监控,从而更有利于深入代码,找到请求响应“慢”的根本问题,与Prometheus和Zabbix是互补关系。另外,SkyWalking的设计更加适合微服务、云原生架构和基于容器的应用。
Riemann提供了一个单一直接的工具来监控分布式应用程序和基础设施。该开源软件使开发人员可定义需要监控的各种类型的事件以及流,可在发生特定类型的事件时生成警报。开发人员还可配置流以发送电子邮件通知或通过Slack发送有关事件的警报。其拥有高定制化、事件处理低延迟、持多种语言的客户端、监控数据图形化、告警方式多样化等优点。但同样存在必须时间同步、内存消耗大、不支持集群等不足。
Sensu是一个全栈监控工具,通过统一的平台,可以监控服务、应用程序、服务器和业务KPI报告。它的监控不需要单独的工作流程并且它支持所有流行的操作系统,如Windows、Linux等。如果你想以一种简单而有效的方式监控云基础设施,Sensu是一个不错的选择。它可以与你的组织已经使用的许多现代DevOps组件集成,比如Slack、HipChat或IRC,它甚至可以用PagerDuty发送移动或寻呼机的警报。
2.3.15 DevSecOps工具链
技术和工具是实现DevSecOps的基础。利用工具的最终目的是通过在SDLC各个阶段形成工具链(图2-9),减少手动操作,实现流程管理和自动化的落地,最终提高交付速度、质量和安全。在推动DevSecOps需要考虑的流程、工具和文化中,一般都是工具先行。因为工具的使用不仅效果明显,而且见效快(一般来说,三个月内研发效能就可以有明显的提高)。
图2-9 DevSecOps工具链
通过项目管理工具,使得敏捷中的迭代和看板可以在团队进行落地。电子看板不仅可视化了任务及其阶段和状态,而且可以协助团队进行历史数据的分析,方便团队开展回顾会议进行持续反馈改进。源代码管理工具对作为统一代码源的源代码进行版本管理。持续集成作为DevSecOps的基础,其工具作为核心需要与其他工具进行集成,通过自动触发实现持续构建、持续单元测试、持续代码质量和安全测试、持续功能和安全测试、持续发布等,从而实现以自动化为基础的快速反馈。通过左移,SAST、DAST、IAST和SCA工具都被集成到持续集成工具中,在开发和测试阶段进行安全测试,帮助团队提前发现安全漏洞并修复,从而减少了返工成本和提高了交付速度。SCM和制品库的使用建立了统一的代码源、制品源和配置管理源,方便管理和提高了效率,并且避免了开发中的冲突。单元测试以及自动化功能和性能测试工具帮助团队减少了人工测试,通过更有效的自动化测试减少了人为失误,提高了交付速度。环境配置和部署工具可以快速、大批量地自动生成应用运行需要的环境并将应用进行上线部署。上线后,监控工具实时跟踪应用、基础设施的状态,保证服务的稳定性。当问题出现时,日志分析工具帮助团队发现问题的根源从而进行问题修复。总之,流程通过工具实现落地。DevSecOps工具不仅通过自动化和更有效的管理模式帮助开发团队实现高质量、更安全的快速交付,而且帮助团队节省了成本。表2-3列举了市场上流行的DevSecOps开源和商用工具。
表2-3 DevSecOps开源和商业工具列表