随着互联网越来越受器重,前端开发不再是简略的实现一个界面,应用 Javascript 让页面有肯定的交互特效。在同一个期间的迭代里,咱们可能须要同时开发浏览器利用、桌面端,甚至是 App、小程序等等。导致了咱们迫切的须要思考一种新的形式,优化咱们前端的开发工作。而 CI/CD 是工程化的重要环节之一。
为什么须要 CI/CD?
咱们每次我的项目迭代过程中都会听到的各种埋怨:来自测试的埋怨、开发的埋怨,甚至是技术主管、运维的埋怨 ……
工夫一长,很可能会导致同一个项目组的成员关系越来越差,我的项目的品质也不会好。我的项目迭代过程中常随同着以下 5 大现状:
或者有人会说:我的项目发版一年只有那么几次,比起我的项目疾速的迭代,搭建 CI/CD 零碎只是一件必要然而不紧急的事件。
咱们先来看看 GitLab 2020 DevSecOps 的考察数据统计:
频繁的发版,可能导致咱们每天都得耗在发版里,基本没有工夫做新的迭代。这尚且是 2020 年的数据统计,如今已是 2022 年,发版只可能更加频繁。
那么,搭建 CI/CD 零碎还是一件不紧急的事件吗?
什么是 CI/CD?
CI/CD 起源于 70 年代,软件工程的概念被提出,通知咱们不仅须要会开发软件,还须要零碎的、标准的开发和保护软件,这标记着工程化意识的沉睡。直到几十年后,2015 年比尔团队的《凤凰我的项目: 一个 IT 运维的传奇故事》这本书才介绍了 CI/CD 的雏形。现今,CI/CD 已被宽泛地提起以及利用。
从字面意思了解,CI/CD 是由两局部组成的。CI 指代继续集成,是指咱们 Push 代码后对代码进行的一系列质保实际。通过继续集成,咱们能够更早地辨认和修复谬误以及平安问题。CD 是由继续交付和继续部署组成。简略了解是上线过程的一组实际,缩小人为误操作的危险。简略的了解就是,CI/CD 是继续集成和继续交付联合的一组实际。
传统上咱们将新代码从提交到生产中所需的大部分或全部都是人工干预,例如构建、测试和部署,以及基础设施的配置等等。而 CI/CD,是将所有都自动化了。应用 CI/CD 管道,开发人员只需将更改后的代码 Push 上代码仓库,而后 CI/CD 管道会主动构建和测试,最初进行交付和部署。
深刻理解 CI/CD
回顾残缺的 CI/CD 过程图,咱们能够发现版本控制和自动化测试是整个 CI/CD 管道中重要的两个环节。
版本控制在 CI/CD 中次要用于触发 CI/CD 流水线,它还有个分支管理策略,用于针对不同的环境的非凡场景做隔离解决。
自动化测试次要是应用自动化的伎俩去执行测试,包含单元、集成、性能和验收等等。它可确保假如某一环节测试失败了,则阻止将性能部署到生产中,并且晋升了咱们代码自身的品质等等作用。
以下是 CI/CD 搭建的根本准则:
搭建 PC 我的项目的 CI/CD 管道
怎么去搭建 PC 也就是 electron 我的项目的 CI/CD 管道呢?
以 Eolink Apikit 我的项目作为示例,以下是搭建 CI/CD 零碎的步骤:
对 Web 利用来说,绝对好一些,市面上很多现成的 CI/CD 计划可能参考。然而 PC 因为存在各种难点,例如须要绑定机器资源、代码签名等等,导致了它的 CI/CD 构建在肯定水平上难以解决,并且市面上相干的材料也比拟少,于是咱们花了半个月工夫,一一去攻破难点,造成了当初的计划。
Eolink Apikit 我的项目的痛点,除了后面提到的不足可见性不存在之外,其余四个痛点:我的项目交付周期长、我的项目品质参差不齐、反复的执行测试、部署等操作以、发版等待时间过长,都一一具备。
难点
在 Eolink 的我的项目中,自动化测试是由三个环节组成,别离是:
因为单元测试、品质 & 平安检测因为都是对代码的扫描以及测试,所以不存在体现不统一的状况。而端到端测试,它跟操作系统是有肯定关系的,例如 Windows 下,敞开按钮在右上角,而 Macos 是在左上角。
那么,咱们是怎么解决的呢?过后咱们是在端到端测试的入口配置中引入了 Os 这个库,通过配置 TestMatch 这个字段解决的,例如以后运行端到端测试的操作系统是 Windows 时,咱们的 TestMatch 设置匹配文件名的规定为 *.windows.spec.ts。这样,对于依赖操作系统的用例场景,咱们就能够疾速的独立解决了。
为什么咱们不倡议间接在具体的用例脚本外面引入 Os 包呢?因为其实咱们绝大部分的场景用例都是通用的。所以针对它们,咱们应该间接在 CI/CD 管道机器上运行。
而针对非凡的场景用例,咱们在构建完代码后,将它们和构建包一起散发到对应的操作系统,之后再在构建程序前跑一下就能够了。
针对第二个难点“代码签名须要物理硬件”,咱们先看一下不进行代码签名会怎么样?
下面两张图就是假如没有进行代码签名,Macos 和 Windows 各自的体现。虽说能够疏忽,然而总归对公司形象不太敌对。Macos 代码签名证书是电子凭证的,所以咱们构建应用程序的时候只须要存在证书文件,应用 P12 & 密钥就能够了。
Windows 才是问题的所在,首先咱们选用的 Windows 签名证书是 EV 代码签名,相较于规范代码签名,它不须要当应用程序下载量达到某一个值时才能够失效,并且能够间接对内核模式驱动签名。
不过坑就随之而来了,它的证书是存储在一个称为 Yubikey 的硬件里的。如果你要随时随地签名,那么你就须要时时刻刻把你的 Yubikey 带上。
这也有方法解决,我调研了很多 EV 签名的公司,发现 ssl.com 是能够进行云签名的。然而,也因为是独此一家,它的费用比拟高,100$ 每个月。假如你不介意,这也是个不错的抉择。
难点三“构建利用和操作系统强绑定”,次要因为咱们的 PC 框架是 electron,假如咱们须要打 Windows 应用程序,就得先领有一台 Window 操作系统的物理机器,再在外面打包咱们的 electron 我的项目。Macos、Linux 也是以此类推,得在对应的操作系统上打包,否则就会报错。
难点四的“通信”问题,次要是因为咱们物理机器和 CI/CD 管道所在的服务器不是同一台服务器所导致的。最初是通过将打包的物理机器和 CI/CD 管道环境用 Openvpn 造成内网解决。
难点五“Web 利用和 PC 利用代码平滑同步”,则是因为 Eolink apikit 我的项目是同时存在 Web 和 PC 两个利用的,它们的代码大部分雷同,只有个别体验可能不太一样。因而,咱们不能齐全应用一套代码,这就不属于 CI/CD 的领域了。
解决方案
次要问题在工具选型上,市面上的 CI/CD 工具很多,然而依据咱们想要的状态,可间接归为两类,Github action 以及其余。
Github action 为什么能够独占一类呢?Github action 是 Microsoft 的一个较新的 CI/CD 平台,反对运行在 Linux、MacOS、Windows,甚至是 ARM 运行器上。它之所以能够独占一类是因为它奇妙的使用了 Matrix,也就是矩阵策略。后面咱们提到“应用程序构建和操作系统强绑定”这一难点,Github action 让咱们能够间接忽视它。Github action 的 Job 是反对绑定一个叫 Os 的变量的,表白的意思是你能够是在这款操作系统上运行你的工作,能够设定为 Macos、Windows、Linux 等等。
最近一项新的 API 开源我的项目的 Eoapi,它的 CI/CD 流水线就是应用 Github action 搭建的。
然而 Eolink Apikit 我的项目并不应用 Github action,为什么呢?最次要的的起因就是 Windows 签名硬件这个坑。其余的 CI/CD 工具根本是大同小异,抉择用哪个取决于开发团队的需要,毕竟适宜本人的才是最好的。Eolink apikit 我的项目应用的代码仓库管理工具是 Gitlab,秉着一路走到底的准则,抉择的 CI/CD 工具也是 Gitlab。
上图是 Eolink apikit 最终设计的管道流程,当开发 Push 代码后,将会主动触发 CI/CD 流水线,依据咱们设定好的分支管理策略将流拆成两条。针对长期分支,开发可能会常常 Push。这种时候,咱们就不在流水线上做任何测试覆盖率的要求。针对其余分支,咱们将主动结构和单元测试、品质检测并行执行。在这个过程中,单元测试覆盖率是要求 80%,质检须要各个指标为 0。前面就是惯例的端到端测试,覆盖率同为 80%。都没问题的话,就间接将编译好的代码和针对操作系统的用例分发给各个操作系统,以及最初上传代码。过程中假如呈现任意谬误,就会马上进行前面的流程。主动触发告警,并将相干的错误信息发送给提交者。
从以上「流水线执行后的预览成果」图咱们能够看到具体的执行步骤,如果还没执行完,还能够看到以后哪些 Job 正在执行,哪些 Job 在 Pending。点击每个 Job,能够看到具体的 Job 执行信息,产生谬误还能够针对这个 Job 进行重试。
最初,咱们告警零碎接入的是飞书机器人。假如执行过程中产生任意谬误,都会通过飞书机器人发送告诉给相应人,让他们马上回来调整。
对于 electron CI/CD 管道的搭建,总结了几条倡议,分享给大家:
CI/CD 管道平安的实际
咱们为什么须要关注 CI/CD 管道平安呢?
从数据中,咱们能够看到 2021 年世界上的软件供应链攻打减少了 6 倍多(650%)。同时 Gartner 也预测,到 2025 年寰球会有将近 45% 的企业遭逢攻打。
CI/CD 管道攻打就属于供应链攻打。CI/CD 是咱们软件开发周期的重要组成部分,假如咱们疏忽它的平安,就有可能被人为攻打管道破绽,间接窃取咱们的敏感信息,甚至是交付恶意代码。典型的案例有 2020 年 12 月的 Solar Winds 供应链攻打事件,以及去年的攻击者入侵了数千名开发人员应用的 Bash 上传器的 Codecov 供应链攻打事件等等。诸多案例通知了咱们,进步 CI/CD 管道的安全性火烧眉毛。
应该怎么做能力防止呢?关键在于咱们须要晓得具体有哪些可能性危险,能力去逐个攻破。在此,咱们联合信息安全三要素进行初步的剖析,能够理解到 CI/CD 管道波及敏感数据泄露是造成危险的次要因素,如 IP、密钥透露或者是破绽的披露,而源码被植入后门、歹意挖矿或者是其余歹意行为是供应链攻打的次要一环。
咱们总结出了十大 CI/CD 平安危险:
危险 1
不欠缺的流量管制机制导致的危险。咱们搭建 CI/CD 关注的更多是怎么提效,往往会疏忽它的平安。例如攻击者会利用 CI 中分支爱护规定的破绽,绕过审查去公布恶意代码。典型的案例是去年 4 月份在 PHP github 仓库中植入后门的事件,以及上年 10 月份攻击者应用 GitHub Actions 破绽绕过审查机制的事件。
咱们应该怎么去防备呢?老话说得好,吃哪补哪,所以针对这个危险最好的形式是建设欠缺的管道流量管制机制,以确保没有人或者软件可能在没有验证的状况下通过管道传送歹意的代码或者软件。例如,咱们能够在受爱护的分支上配置分支爱护规定,所有用户提交的代码都得通过它去做审查能力去公布。
危险 2
假如咱们的 CI/CD 环境存在很多身份凭证,不论是授予机器的还是人的。一旦治理好,比方为了后期缩小沟通老本,咱们将所有账号都赋予管理员权限,就有可能被攻击者利用,想干什么就干什么。
典型案例是 2019 年 Stack Overflow TeamCity 产生了一起安全事件,过后呈现了一个没有人意识的账号,取得了 Stack Exchange 网络中所有站点的审核者和开发人员级别的拜访权限。官网追踪后,发现是因为新注册的账号在拜访零碎时会被主动调配管理员权限。
由此可见,咱们须要防止创立本地账号。或者,咱们能够应用像 Idap 这种集中式企业工具创立和治理账号。有人会说我不论,我就得创立本地账号。那么咱们就须要确保可能定时清理账号,以及所有账号的安全策略须要与企业策略是统一的。
危险 3
置信绝大部分团队都为我的项目援用过一些第三方开源组件,因为比起本人去实现,第三方开源组件有时候会思考得更加全面一些,并且间接援用也更快。然而,咱们千万不要去滥用它。
首先,咱们没法保障引入的第三方开源组件是没有破绽的。像上年的 Apache 日志控件被爆出近程代码执行破绽,连这么稳固的包都可能有破绽,其余的又怎么能确保齐全平安呢。
其次,咱们没法晓得第三方开源资源的奉献策略是怎么样的,是否做了平安检测。这导致攻击者有可能领有拜访开源组件仓库的权限,能够间接为开源组件增加歹意后门程序,并对外公布。
这样,很容易引发大规模的供应链攻打。攻击者能够利用该后门对 CI/CD 环境进行探测,进而导致整个环境失陷。
最初,在 CI/CD 管道中,咱们通常会引入一些第三方工具对我的项目进行治理。例如 Nodejs 我的项目中,通常会引入 Npm 仓库,若我的项目间接从 Npm 地方仓库去拉组件,就无奈确定是否会引入了含有破绽的组件,进而可能导致组件破绽被攻击者利用。
针对这种危险,咱们倡议首先梳理我的项目中所有依赖的开源组件,能够通过 SBOM 进行梳理,并采纳软件成分剖析工具对咱们引入的开源资源进行破绽扫描。当我的项目中引入了新的开源资源时,也可能具备针对性的平安管控措施。
危险 4
咱们称为 PPE,是“中毒”管道的执行所导致的,次要是中了攻击者恶意代码或者歹意命令的毒。
依据“中毒”的伎俩,PPE 分为以下三种类型:
第一种是攻击者间接批改有权限拜访的管道配置文件,在管道运行中触发歹意命令来达到攻打咱们的成果,咱们又称之为间接 PPE (D-PPE);
第二种是攻击者通过向管道配置中所援用的文件注入恶意代码,来间接的毒害管道;
最初一种是攻击者假如须要通过获取身份凭证来拜访管道配置文件,那么他能够通过毁坏公共我的项目达到攻打公有我的项目的成果,从而开掘更多的敏感信息。
典型案例是上年 GitHub Actions 通过蕴含恶意代码的拉取申请滥用来开掘加密货币事件。具体的解决方案是须要从之前对代码的审查,改良为当初同时须要对管道配置文件也进行审查,甚至是定时监控管道的运行状况。
危险 5
基于管道的访问控制有余所导致的危险。它的存在将导致攻击者间接将一段恶意代码注入到管道执行节点的上下文中,这样,恶意代码就能够具备运行管道阶段的齐全权限,能够拜访机密信息、拜访底层主机,甚至拜访连贯到相干管道的任何零碎。毋容置疑的将会导致咱们秘密数据泄露、CI 环境内的横向挪动,以及被恶意软件部署到咱们管道中,甚至是公布到生产环境中。
Codecov 事件中,就是因为疏于防范导致 Codecov 最终被毁坏并用于从构建中窃取客户的环境变量。咱们要怎么躲避它呢?重点就是做好权限治理,例如 CI/CD 管道作业在控制器节点上的权限应该设置无限。
危险 6
假如咱们曾经领有了身份和拜访认证机制了,然而凭证治理不得当也是会导致危险的。例如,开发将蕴含凭证的代码推送到代码仓库中,不论是无意还是无心的,这都将会导致咱们将凭证裸露给对代码仓库具备拜访权限的人。即便前面咱们发现不对,马上将它从被推送到的分支上删除,他们还是会在提交历史记录中呈现。调试时将凭证打印到控制台中,可能会使凭证以明文形式在日志中公开,任何有权拜访构建后果的人都能够查看。这些日志前面也可能会流入到日志管理系统中,从而扩充了凭证的裸露面。
回看 Codecov 攻打事件,攻击者就是通过毁坏 CI 中的凭证,去窃取了存储为环境变量的数千个凭证。解决方案中最重要的就是,不要在 CI/CD 环境中存储任何敏感的信息,至于其余都是主要的。
危险 7
CI/CD 环境中不平安配置的零碎导致的危险。攻击者利用有破绽零碎的安全漏洞来取得对系统未经受权的拜访,或者更糟的状况是,毁坏了零碎并拜访其余底层操作系统。
都有哪些不平安的操作系统呢?例如应用过期版本或短少重要安全补丁的自我管理系统。或者是对底层操作系统具备管理权限的自托管零碎。SolarWinds 构建零碎的入侵就是典型的案例。
除了以上的防备伎俩,还须要去定时为零碎打补丁。
危险 8
和第三方开源资源滥用一样,属于无监管应用导致的危险。不足对第三方服务的治理,会重大影响企业在其 CI/CD 系统维护管道中对于角色访问控制的操作,企业也会变得很被动,安全性得取决于它们施行的第三方。而第三方的最小特权,加上围绕第三方施行过程的最小治理和渎职考察,都会显著减少企业的攻击面。
鉴于 CI/CD 零碎和环境的高度互联性,假如第三方的破绽被利用,造成的危害是远远超出第三方所连贯的零碎范畴的侵害的。例如,具备写入权限的第三方存储库,攻击者能够将恶意代码推送到存储库,第三方存储库反过来又会触发构建,并在构建零碎上运行攻击者的恶意代码。
这个危险防备伎俩很简略,次要是围绕第三方服务的治理管制,咱们应在第三方应用生命周期的每个阶段去施行。
危险 9
CI/CD 流程是由多个步骤组成的,最终负责将代码从仓库一路带到生产环境。每个步骤都可能有多个资源,最终软件包依赖于散布在不同步骤中的多个起源,它们是由多个贡献者提供的,从而让攻击者有可能通过这些入口点去篡改最终的软件。如果被篡改的软件胜利地渗透到交付过程中,而不引起任何的狐疑或者没有遇到任何平安检测,它很可能就会间接以非法资源的名义持续流经咱们的管道,始终公布到咱们的生产环境中。这就是不正确的软件完整性验证导致的危险。
避免不正确的软件完整性验证危险须要一系列措施,逾越软件交付链中的不同零碎和阶段。
危险 10
弱小的日志零碎是可能帮忙企业筹备、检测以及考察相干安全事件的,然而如果它不够弱小,那就会引来危险。随着攻击者逐步将注意力转移到工程环境破绽中,那些无奈确保围绕这些环境进行适当的日志记录和可见性管制的企业,就有可能无奈检测到违规的行为。
解决方案有哪些呢?尽管工作站、服务器以及业务应用程序通常在企业的日志记录和可见性程序中失去深刻介绍,但工程环境中的零碎和流程通常并非如此。
鉴于利用工程环境和流程的潜在攻打向量的数量,咱们必须建设适当的能力以在这些攻打产生时立刻检测到它们。其中许多载体波及利用针对不同零碎的程序化拜访,面临这一挑战的要害就是围绕人工和机器拜访创立弱小的可见性。
鉴于 CI/CD 攻打向量的复杂性,零碎的审计日志(用户拜访、用户创立、权限批改)和利用日志(将事件推送到存储库、执行)须要具备等同的重要性构建以及上传软件。
总结: 继续集成、自动化测试和继续部署
最初还须要留神的是,随着业务越发简单,零碎架构从单体走向微服务,CI/CD 管道的复杂性也会相应增多,每个阶段都可能会产生大量的敏感数据,这些敏感数据往往会成为微小的攻打杠杆。试想一旦攻击者拿到了源码仓库的拜访凭证,那么整个 CI/CD 环境都可能受到失陷。
在 Gitlab 的 CI/CD 起因统计报告的最初有这样一句话:
咱们之所以这么频繁的公布程序,是因为采纳了 DevOps 办法,并且次要归功于 CI/CD 中的继续集成、自动化测试和继续部署。
当然,平安也责无旁贷。