共计 8898 个字符,预计需要花费 23 分钟才能阅读完成。
文章首发于:前线 Zone 社区
作者:李祥乾
我明天次要分享云原生时代下的 DevSecOps,分享一下咱们客户在云原生时代下的继续平安实际。
大略摘要:
- 平安可能对于很多业务开发与运维来说,是“麻烦”与“被动”。
- 相比传统,云原生架构具备了一系列个性,使平安可能更低摩擦地内生于企业流程之中,内生于 DevOps 之中。
- 心愿与大家探讨的是,在云原生架构下,在继续减速的业务迭代和 CI/CD 中,如何实际继续平安(Continous Security)。
我目前在探真科技,咱们是一家做云原生平安的公司,是个 To B 的企业,我之前工作经验次要是互联网工作经验,波及的畛域是 IT 平安、业务平安,也做过一段时间的基础架构。
我的大略内容分为四个局部:
01:新的云原生,新的危险
02:平安落地的难处
03:云原生下的零摩擦实际
04:继续平安,做一个小结
首先新的云原生,新的危险。
首先云原生架构自身的特点,这外面列的几点,有些是来自于社区外面的一些分享,有些是咱们认为比拟重要的。
第一点标准化,标准化是一个十分重要的特点,对甲方乙方都很重要,传统的架构下各个公司的 DevSecOps 流程或者说开发和运维流程,概念上都差不多,然而具体到施行和实现上就千差万别。
然而新的云原生时代,其实 Kubernetes 或 docker 等围绕着 Kubernetes 这样一个社区,这部分的流程曾经造成了比拟好的标准化,所有的企业都须要去做构建镜像,须要镜像存储,须要 CI/CD,须要 Kubernetes 或者是 Kubernetes 衍生的一些商业化版本,相干的运维操作其实也在 API 层面和概念层面都实现了标准化,这样有十分好的益处,就是社区外面的一些其余企业十分好的实际,都可能比拟的摩擦的、比拟疾速的,在咱们本人的流程和环境外面去做试验、落地,不像之前须要一些特地多的适配老本、金融老本。
自云原生社区成熟以来,Kubernetes 这样的容器编排软件成熟以来,像 AiOps 这样的概念才真正的发达起来,对于咱们这种做企业服务的公司来说,咱们的一些平安能力和平安服务可能相对来说比拟低成本的在不同的企业做可复制性的计划。
不可变基础架构,咱们认为对平安来说也是一个十分重要的特点,对平安能力真正落地是一个比拟好的根底。
微服务化和继续交付,非常容易了解。
Operator 化是社区外面比拟有名的张磊老师在他的分享外面提到的,Operator 化的模式是 K8S 的一个重要的模式,是一种自定义资源和扩大 K8S 的一种十分重要的形式,也是实现很多扩大性能的一个重要的根底。
云原生下其实存在的平安危险是涵盖了传统架构下的平安危险,诸如 WebShell、病毒、木马、反弹 Shell,这些问题在新的架构下依然存在,相同云原生的指标外围指标是降本提效,因为降本提效就是更快的集成和交付带来的危险、供应链的危险,破绽危险的管制老本其实是加倍晋升的,因为单位工夫内交付的镜像,交付的新服务的速率都变大了,管制这些危险会与交付速度之间存在的抵触也会加强,因为原来大家都慢,多花点工夫解决问题,这些问题也不是什么问题。
云原生架构下次要基于容器的更灵便的隔离技术、容器网络这种软件定义网络,在物理层面下面减少了一层更灵便的虚拟化技术。其实这种虚拟化技术自身,比传统的虚拟机的隔离,它存在逃逸或者提权的危险会变得更大,像 docker,runc 包含 k8s 都暴露出了很多容器逃逸的破绽。
最近有一个比拟新的破绽,是用 Linux 的一些机制去逃逸 Linux NameSpace 来实现逃逸,也是最近比拟新的破绽,在这种隔离机制下,很多传统平安计划和能力是无奈失效的,比如说传统的网络防火墙,在容器网络下其实 pod 的迁徙是很频繁的,同时他的 IP 是动态分配的,传统基于 IP 的一些策略统统都会生效。更简单的代码必定会带来更多的 bug,破绽就是这些外围组件的缺破绽和缺点的危险也大幅晋升了。
最初一个问题就是微服务化后,服务的数量,还有这些服务之间的调用关系的复杂度是呈几何比例去晋升的,对于安全策略的治理,平安运维老本,如何感知这些流量和变动,存在着微小的挑战。
从典型的 DevOps 流程看危险,比如说代码仓库层面,代码自身可能就会蕴含很多敏感的数据,比如说数据库明码,密钥,业务本人写的代码会存在破绽和 bug,可能会被攻击者利用。
当开发人员开始测试环境测试的时候,从 Jenkins 或者 gitlab ci 这样的 CI/CD 工具外面会去拉取代码,去做构建镜像。一些蕴含着病毒和木马的镜像可能会在这个阶段就被推送到仓库。
仓库外面存储的所有沉闷的镜像,这些沉闷的镜像可能有几万个,甚至十几万个镜像,而后镜像可能还蕴含着几十万个破绽,这种破绽的治理老本对于平安和业务来说还是很高的,这么多破绽不大可能全修复了,老本太高,然而优先修复哪个就是问题?
接下来开发可能会通过多轮的代码提交、镜像测试,而后在测试环境外面做部署,做联调;而后交给 QA 验收之后,这个镜像会被 mirror 到网络隔离的另一个环境,比方生产环境的仓库,而后再去做部署交付。
在这个镜像的散发流程中,还存在一个危险,就是镜像可能会被篡改,可能会被替换掉。相当于是我可能在 CI/CD 阶段或者仓库阶段扫描,扫描认为他是个平安镜像,然而这个平安镜像在接下来的散发流程外面被篡改了,篡改之后的镜像可能会引入危险,然而相当于之前的措施就生效了。
在部署交付阶段,这个镜像也可能会被居心叵测的人去替换掉,比如说节点镜像的缓存就是一个可能被脱漏的点,就存在着肯定的危险镜像流入线上的一种可能性。在镜像的运行过程中,这些镜像破绽可能会被攻击者利用,这些破绽的攻打是否被检测到和治理,这方面也是平安须要解决的问题。
其实这种灵活性,减速的 CI/CD,减速的迭代为平安带来的并不是只有懊恼。
如果从辩证的角度看这种灵活性,减速的业务迭代,是减速了继续集成和继续交付。
然而平安的经营和安全策略也须要去减速迭代。
平安须要实现更加灵便和深刻对危险和对集群资产的感知能力。
平安须要利用数据和机器学习来升高平安经营老本,进步经营效率。其实就是为平安人员缩小重复性的配置,进步他们的平安经营效率,让平安人员继续的关注在最须要关注的平安问题上。
平安须要更加灵便的策略执行和迭代,把固化的代码逻辑外面的策略变成数据、变成规定,这样的话数据是可继续迭代更新的,而后就可能蹭个热度,就是“低代码”。
咱们心愿的云原生平安,更心愿他的解释是云上的原生平安,而不是原生环境下的一个平安,就是 Security in Cloud Native。
第二局部是在平安的具体落地中和咱们在落地实际中遇到的一些相对来说比拟艰难的中央,平安落地难处在哪?
从业务视角来看,首先的观点可能是平安会让 DevOps 变慢。比如说零信赖须要去频繁的做健全、去做审批,比如说在 Google 的 BeyondCorp 这样的计划,整个落地耗时了六到七年。其余的企业对零信赖的认知可能还参差不齐,这个落地难度其实还是很高,或者说零信赖到底要不要落地?
对微隔离来说,微服务这么多,网络策略配置是很简单的,一旦少配一个,漏配一个,就可能会造成业务上的损失,而后他带来的报警也是很多,这个在咱们跟客户的落地实际中也是咱们遇到的问题。咱们在和 Tigera 做技术交换的时候,他们也提到,企业版的微隔离在企业从开始落地到根本实现一个闭环均匀工夫也差不对须要半年多,这其实是一个比拟大的老本。
镜像平安,我认为可能是更广泛,更容易了解的例子。镜像必定是很多,破绽必定比镜像多的更多,修复也修复不过去,扫描可能也比较慢。
你可能还会发现很多破绽是没法修复的,尽管他可能是高危破绽,然而官网还没有公布修复的补丁。
平安团队可能发现的问题,然而他们不肯定能帮忙业务开发和运维解决问题。
这个是咱们在一个金融客户外面的例子,在初期的扫描外面,他们沉闷的镜像规模在 14000 多左右,然而蕴含高危和重大破绽的镜像至多在一半以上,甚至到了百分之七十、八十。
也有用开源扫描器扫描过破绽,然而除了高危破绽有能力推动过几次,推动整体平安基线晋升是比拟艰难的。服务太多,镜像太多,收益不显性,边际老本越来越高。
相比于业务迭代的需要中,平安的需要必定不能 override 业务迭代需要,企业的外围能源还是业务的迭代,平安其实是管制业务的危险。
我感觉平安有两种逻辑:
一种是基于事中与预先的反抗与博弈逻辑。产生安全事件,须要紧急响应或者突发破绽的时候,比如说去年的 Log4j 这种时候,平安人须要跟攻击者,或者说潜在的危险去做继续的反抗和博弈。
这种肯定水平上说是“擦屁股”,呈现问题了要去遏制危险,预先我要通过复盘去防止的危险。他的外围逻辑其实是危险管制,平安永远没法毁灭危险,绝对危险可能老本会很高。对于攻击者来说它也存在老本,这个最终我认为是老本的反抗,就是平安团队须要通过正当的老本去将危险管制到肯定水平下,在这个水平下攻击者须要付出,可能他不违心接受老本去取得一些利益,而后达到这个均衡之后,是这种反抗和博弈逻辑所谋求的一个指标。
另一种是基于事先和以 ROI 为核心的预防逻辑,就是 Return On Investment,看中的其实是投入产出比,当企业产生过几次平安危险之后,企业必定会器重这种平安防护体系,包含这种纵深进攻的建设,去做流程平安,晋升整个企业的平安水位线。
平安的指标和业务还有运维(DevOps)的指标是统一的,其实都是业务持续性治理,指标其实都是让业务持续性的高可用的运行在线上,保障业务的持续性运行,防止危险,比如说数据泄露的危险,PR、GR 的危险。不会有任何公司会为了进步防御能力去穷尽所有,去修复所有的破绽,这样边际老本会越来越高,最终的逻辑都是基于 ROL 逻辑,让业务迭代更平安,寻求一个均衡。
咱们认为云原生平安的一个核心理念应该是零摩擦 Zero Friction,而后这个 Zero Friction 次要诞生于零信赖网络的落地实际中。
这个外面的零等同于零信赖的零,是有限趋近的意思,对于零信赖来说不可能什么都不信赖,信赖要有 root 根信赖。对于零摩擦来说,也不可能没有任何平安计划是齐全没有摩擦的,重点是均衡平安的收益和业务收益。
具体来说就是:
在升高平安危险的指标的前提下,做到平安经营老本的升高,经营效率的晋升,进步用户体验。
可能更好的适应不同企业的流程和文化,升高理论用户在落地平安实际时候与其它部门和其它需要的摩擦。
平安不能只发现问题,还须要解决问题和治理问题。
接下来咱们联合跟客户的一些落地的实际,来分享一些云原生在 DevOps 里的落地实际。
可信镜像的含意,首先可信镜像是通过比拟全面和深刻的扫描,咱们能确认它的危险是在企业用户和平安团队所认可的平安规范之内的镜像。
能够信赖的镜像,就是在整个散发过程中,从镜像的生命周期的诞生,到它最终落地到运行在线上成为一个容器,直到这个容器被销毁,整个过程中这个镜像是没有被篡改和替换的,来保障散发流程的平安,这样的景象咱们认为是一个可信镜像。
所有的镜像基本上都是在一个 CI/CD 工具,比如说给了 GitLab CI,或者 Jenkins 外面去做镜像构建,在这个时候就须要去对这个镜像去做镜像的扫描,同时这个扫描的效率还足够高,如果每次镜像构建都须要去运行一个小时的话,业务无奈承受的,镜像扫描须要高效。
对于满足平安规范,扫描出的危险后果是满足平安规范的镜像,这个镜像去做签名,而后去阻断或者说预警这种不满足平安规范镜像,这样能保障推送到仓库里的镜像,它是一个满足平安规范的镜像。
接下来镜像的旅程外面,可能会从测试环境 M irror 到生产环境,在它真正被部署到生产集群的时候,或者部署到测试集群的时候,咱们这个阶段须要去校验,因为只有平安的镜像,同时在这个散发流程外面没有被篡改过的镜像,能力胜利的实现校验的签名,这个阶段就能够阻断那些不平安和不可信的镜像,这些镜像是无奈部署到生产集群上的,同时这个阻断能力要笼罩没有通过平安的 pipeline 构建的镜像。
同时还有一个须要留神,K8S 的每个节点上他都会有一个镜像缓存,来进步容器的一个拉起的效率. 如果具备肯定权限的话,也是存在一些镜像被篡改或替换的可能,所以须要去实时监控,咱们节点镜像的状况去做扫描,同时监控线上运行容器的一些异样,可能会被替换的异样,来保障整个的镜像的全生命周期外面,他的平安是能失去保障和关注的。
第二个点镜像危险闭环治理,这外面列举了一些镜像的危险,对于破绽来说其实蕴含三种类型的破绽。
第一种类型:这个破绽是曾经公开公布的,同时他是个可修复的破绽,就是官网曾经公布了修复补丁的破绽,这样的破绽大部分平安团队都晓得怎么去解决,怎么去做。
第二种类型:尽管它是公开公布的破绽,然而官网并没有公布修复的补丁,这种破绽其实也很常见,大家在日常的扫描实际外面也常常会遇到,有很多破绽尽管扫描进去,然而没有官网补丁,拿他也没什么方法。
第三种类型:0day 破绽,不是所有破绽被发现了都会被公开,有很多平安厂商或者很多国家安全部门都会有一些私藏的破绽,这些未发现的破绽或者未公开破绽,他可能不存在补丁,或者存在补丁也不晓得。
第四种危险:病毒,木马,Webshell 等歹意文件,这种危险其实实践上也应该依照前三个分类去做分类,那这里就简略一点。
第五种危险:敏感文件,在代码层面的敏感数据其实在镜像扫描外面无奈去扫描的,然而比如说在配置文件外面蕴含了数据库的明码,蕴含了一些要害的密钥,其实是能够在镜像扫描这个过程中被检测进去的,这种保留在配置文件外面的数据库明码和密钥,其实是有很大的危险被泄露进去,因为这个镜像外面是能够间接读这个配置文件的,尤其是在互联网公司,其实曾经呈现了十分多的开发人员把本人在公司外面奉献的一些仓库代码上传到 GitHub,而后就无心中把公司的数据库明码也上传上去了。
Root 权限运行的镜像,这个在平安的倡议里也是尽可能的不要用 root 权限去运行。
针对镜像危险的一个检测技术,其实目前其实最常见的就是动态扫描,目前开源的一些动态的扫描技术,比如说 Clair 这些技术,它的检测原理,第一步其实是要去检测和发现镜像里蕴含的公开的软件包,程序依赖的第三方库和依赖,比如说去扫描 jar 包,二进制等尽可能全面的制品,去扫描出程序依赖一些第三方的 lib,比方 Fastjson 等。
首先一个能力就是须要理解你这个镜像外面的软件制品有哪些,依赖第三方库有哪些?他们的版本是什么?而后你还须要一个尽可能全面的公开破绽数据库,去用镜像的软件制品这笔数据,去跟公有破绽数据库比对,而后这个其实是十分依赖破绽数据库的更新。
第二个就是无奈扫描本人企业外面构建一些私有制品,一些本人的业务代码是没法去做破绽扫描和检测的,你须要去继续去更新你的破绽库,可能你的扫描技术也须要去做一些迭代,去笼罩到更多语言,尤其是企业所使用的一些编程语言的构建进去的制品。
比如说你用了一个比拟小众的语言,扫描软件如果没法去解析这个语言,无奈去解析出你这个制品外面依赖了哪些第三方仓库的话,就没法对他去做扫描。
对这种未知破绽,未知破绽的含意就是破绽数据库外面没有的破绽,还没有收录到破绽数据库的破绽是没有能力去做检测的。
基于这种状况,咱们在局部客户外面实现了动静扫描的机制,类比于 PC 下面的病毒扫描,如果只依赖文件的 hash 比对和特色匹配,则检测能力无限。同时你须要在运行时须要时刻监控注册表、要害目录的异样行为,与常见病毒的行为特色比对,能力实现比拟全面的扫描。
动态扫描的长处其实就是扫描的很快,对于这些有余来说,其实咱们会把这个镜像依照模仿生产环境的配置,去在一个沙箱容器外面去做运行,通过咱们运行检测的能力去检测,当这个镜像在容器外面运行起来的时候,存在一些危险行为。
第二点就是会通过施行一些尝试性的 POC 破绽利用攻打去检测一些常见的攻打威逼,能不能无效达到一些成果,通过这些形式来做一个经营时的动静扫描。
镜像风险管理的第三点就是对可修复破绽的风险管理,这个其实是方才提到的这种 ROI 的逻辑,我当初有 15000 个镜像,我可能有几十万个破绽,我是不可能轻易排个序,每个镜像的所有破绽都去修复。
破绽自身的原信息外面其实是蕴含它的危险级别的,就是有些破绽是高危的,有些破绽是低危险的,有些破绽是可疏忽的。
同时这个镜像用来运行的服务的重要性也有所区别,比如说我这个服务只是一个在内网应用的,面向员工的一个,比如说内容治理平台,其实相对来说,他的优先级可能会须要低一点,但如果服务是面向外网 API 服务,同时是十分外围的,比如说账户服务,有可能是企业外面每个对外的 APP 或者网页都须要去拜访的 API,这个服务的它的重要性和优先级就会很高,它蕴含破绽可能就须要优先去解决。
同时一个破绽的覆盖率各有差异;修复覆盖面广的破绽,修复根底镜像的破绽事倍功半。
镜像危险对可修复的风险管理应该是一个修复打算,通过咱们对集群和镜像的感知能力去剖析破绽的一个轻重缓急,来制订一个排序和修复打算,来让平安人员可能更高的关注到最重要、最须要紧急修复和修复它产生的收益最大的破绽,而后继续去优化,晋升整个镜像平安层面的一个水平线。
针对那些高危破绽、0day 破绽,我是不是就没有方法?
举个例子,去年底的 log4j 的破绽,基本上影响了企业的全副 Java 服务,都会被这个破绽所影响。过后很多企业都火烧火燎熬夜的形式去降级服务,去修复破绽,影响范畴十分大。
即便官网曾经公布了修复补丁的版本,它的施行老本和它的施行周期是十分大的,在这个施行周期外面,对于攻击者来说它是一个已知破绽,然而企业并不能霎时地修复或者避免破绽,利用的机制可能利用起来的话,其实是被攻打的一个微小的危险。
热补丁其实是一种咱们在一些企业落地这种机制,就是无需更新软件,通过更新代码或者部署新的服务的形式,即可即时公开发补丁到须要补丁的“节点”,防止破绽被利用。
一些常见的的修复形式,比如说通过 WAF 上线规定,通过所有流量的入口去检测有没有申请,有没有流量再利用这个破绽。
WAF 是比拟广泛的平安解决方案,他的上线规定老本相对来说比拟低,同时也很快,也能够认为是一种热补丁计划,然而 WAF 自身也存在着很多被绕过的可能性,同时 WAF 是没法进攻一些集群外部的危险。
还有一种比拟常见的解决方案,就是通过 RASP 的形式,RASP 会对企业本身的过程注入代码去监控危险,去施行一些拦挡,它是一种紧贴着业务的一种模式,能尽可能的防止被绕过,然而他对业务的侵入性也相对来说比拟大,同时他是针对特定能解决的语言能力施行的,比如说常见的 Java、Go 可能存在的计划,但并不是一个通用计划,同时它的性能开销也存在着一些问题。
咱们的平安规范是能够继续去迭代的,来保障一个继续的平安,当平安刚开始发挥作用的时候,你面临的可能是一个有几万镜像,有几十万个破绽的十分难搞的场面,然而如果能通过正当的镜像危险剖析,可能对现状有比拟全面的感知,咱们基于这个现状制订的修复打算外面,来制订一个对现阶段来说是可实现、可落地的平安规范。
平安规范的含意就是比方一个镜像须要检测进去的危险中须要满足什么样的条件,他能力被推送镜像仓库,能力被部署上线。比如说破绽的评分必须高于 90 分,或者说不蕴含哪些特定的破绽,或者说必须没有病毒和木马,一系列的 policy 去实现这个平安规范,同时平安规范能够从一个比拟低的水位线开始,基于这个平安规范去利用全流程的可信镜像体系,去保障在这个平安规范施行之后,陆续的企业在线的容器,都能运行在满足平安规范的镜像之上。
基于这种持续性的迭代去更新平安规范,逐渐把水平线进步,直到进步到一个绝对正当的业务迭代均衡的水位线。如果说边际老本再往下做,我的边际老本就变得比拟高,或者收益就不显著了,就能够稳固一下工夫。尤其是一些新的破绽公布或者破绽更新之后,这个规范都能够持续性的去做更新,去晋升,来保障企业整个镜像平安层面上的一个水平线的稳固。
云原生架构下另一个能够利用的十分重要的个性,就是它的不可变性。
在传统架构下,我的一个服务可能有 10 个 workload,这是个 Workload 运行在十个虚拟机或者是十个物理机上,这十个虚拟机和物理机它所依赖的软件包可能大致相同,然而具体的版本和状况都有可能呈现一些差异性,不过在内核版本和 OS 版本上也可能存在一些不影响业务运行的差异性,业务自身的过程可能还存在一些非凡状况。
我可能要在其中地挑出一两个 workload,我去更新到一个 debug 版本来做一些测试。这个利用自身的代码版本无奈保障这十个 workload 是完全一致的。
同时在传统架构下,在运行中的工作负载的主题下来下载一些新的软件,去更新这个软件版本,这种运维操作还是比拟常见的。
然而在云原生架构下,它的不可变性,就能保障这个服务 10 个 pod 都是用同样镜像构建的,他能保障我环境软件的版本与预期是统一的。
在云原生的最佳实际外面,十分不举荐进入到容器外面去更新软件、下载软件、批改软件,最佳实际必定是去更新镜像的定义,去实现软件更新,软件更新能保障利用到服务的所有 workload 上。
这种不可变性为平安能力带来一些新的可能性,比方咱们在镜像构建阶段,就能够对这个镜像可能蕴含的所有可执行的二进制文件,都能为他制订一个二进制画像,在运行阶段去检测一些未知二进制的执行,去检测一些被篡改二进制,这样就无效防止攻击者去下载可执行文件,通过破绽去运行一些未知的二进制,或者说被篡改的容器里的二进制,这样来实现一个偏移的检测和阻断。
基于 DevOps 流程,能够去对容器的各种类型的行为,比如说文件读写,网络去做一个行为画像的学习,基于这些行为画像去做检测和阻断。
而后依据这个服务的镜像版本的更新和环境变量的更新,像状态机一样继续去做新的增量学习,去更新这个行为画像,来保障实时性和有效性。
最初就是云原生平安的指标,心愿在更加疾速的 CI/CD 中,建设继续平安能力,并且可能在企业中低摩擦地实际继续平安;不仅仅能发现问题,而且可能解决问题,实现平安的闭环。