云原生安全架构设计最佳实践
云原生发展趋势
2013年Pivotal公司首次提出了云原生概念。而在2015年时,Pivotal公司在其所撰写的书中第一次正式定义了云原生的五个因素:
-
符合云原生应用12因素
-
面向微服务架构
-
自服务敏捷架构
-
基于API的协作
-
具有抗脆弱性
能满足以上五个特性就属于云原生应用。
2015年云原生计算基金会(CNCF)成立,CNCF在成立之初便对云原生进行了定义:
-
应用容器化
-
面向微服务架构
-
应用支持容器的编排调度
只要满足以上三个方向的特性,就属于云原生的应用。
2018年,随着云原生技术的发展,CNCF根据最新的云原生基础架构设施,重新对云原生进行了定义:
-
容器化
-
服务网格
-
微服务
-
不可变的基础设施
-
声明式的API
只要满足以上五个方向的特性就属于云原生应用了。
随着云原生技术的不断变化,容器化使操作系统的功能与特性进一步精简。为满足云原生定义中不可变基础设施的条件,云原生操作系统应运而生。其特点是高度精简的内核,只保留容器相关的依赖库,使用容器客户端作为包管理器。
云原生操作系统的共同理念,是所有进程必须运行在容器中。操作系统的宿主机上不能安装任何应用程序,保证操作系统是完全不可变的,这就是所谓不可变的基础设施,也是操作系统未来的发展趋势。
早期的基础架构是运行在物理机上的,而后随着基础设施的变化,应用开始运行在虚拟机之中。到了容器时代,所有的应用都运行在容器之中。在最新的流行趋势里,目前国内外也有一些云厂商在提供对应的基础设施架构——Serverless无服务器技术。
在物理机时代,基础设施通常以年为运算单位的,当物理机上架到机房后,其会以一年或者五年作为生命周期下架。随后的虚拟机则是以月作为其运算单位。到了容器时代,每次更新都需要重新构建新的容器,因此容器的生命周期是以天为单位的。而在无服务器时代,函数虚拟化则会以分钟为单位。
容器化出现后,容器技术标准化的进程得到了加速。DevOps与容器相辅相成,应用容器平台,就需要演变成为DevOps开发模式以加速发布流程。容器化的便捷推广了DevOps,而容器又依赖DevOps来加快迭代速度,这是目前开发模式的演变趋势。
当以容器为单位时,云原生、服务则为网络边界。在云原生领域中,并没有IP的概念,所有云原生中的IP都是动态的,我们无法在传统的防火墙上配置对应的IP地址。在云原生之中,容器的服务每天都会更新,每次更新IP地址都会是一个新的IP地址,原先配置的网络策略均会失效。
物理机时代,物理机上架比较困难,因此通常会在一个物理机上跑多个应用。而虚拟机时代,为了提高服务的可用性,则通常会将单个服务拆分到单个虚拟机之上。再到现在,随着服务接口越来越多,越来越依赖于微服务化,则需要将接口演变成微服务架构。
以微博为例,当出现热点事件时,物理机与虚拟机都需要以小时为单位的较长时间构建才能够实现业务恢复。而在容器化的场景下,容器启动以秒级为单位,启动速度远快于物理机与虚拟机场景。因此在微博演进为容器架构后,已经很少再会因热点事件而发生崩溃了。当然这其中上K8S平台的自愈能力与动态扩缩容也功不可没。
早期容器运行时使用Docker,因此当时通常将容器与Docker划等号。容器自身分四个模块,Docker也分为四个接口。但由于Docker是一整套开发套件,而K8S在运行时,只会用到runtime侧。因此在运行效率的需求下,K8S在1.20版本时,已逐渐不再对Docker Shim进行支持,而是直接使用了Docker Containerd。
无论Containerd还是Docker,其对安全能力的支持的功能都并不十分完善。而Cri-o技术则可以满足相对安全的需求,无需守护进程,每一个Cri-o的进程都可以拥有一个独立的进程,父进程和子进程,去进行服务地运行。未来容器领域的趋势,是底层基础设施安全,包括安全的技术容器化。
云原生安全风险
目前,云原生领域需要考虑的安全问题主要有以下五个:
-
镜像安全
-
镜像仓库安全
-
集群组件安全
-
容器网络风险
-
微服务风险
其中镜像安全风险是比较广泛的。相较于基础设施安全,云原生领域更加关注性能优化与基础设施容器化。这也导致目前DockerHub镜像之中,51%存在高危漏洞、80%存在中低危漏洞。而在企业构建镜像时,90%的情况下,都需要从DockerHub上下载镜像。
镜像仓库方面,企业不可能将所有的研发的镜像、业务镜像上传到一个公开的镜像仓库中,源代码需要存放在企业仓库。但企业仓库也同样会存在安全漏洞的,这些漏洞被黑客利用后,会直接导致仓库中的镜像被替换。当从节点上去拉镜像的时候,拉同一个镜像可能拉到的是黑客带有木马病毒的镜像,这也是非常危险的。
关于集群组件的风险,目前Docker自身存在111个漏洞、K8S存在65个漏洞、Open Shift存在35个漏洞,其他容器运行时例如Cri-o、Containerd与Kata Container,一共包含45个漏洞。集群组件漏洞相对较少,但也是同样存在的。
当黑客通过上述漏洞入侵到集群中后,会继续访问其他集群内容器。物理防火墙,只能防护集群外流量,集群内的流量K8S有overlay与underlay两种网络架构。但无论是overlay还是underlay,传统防火墙都无法防护集群内的攻击情况,这便是集群内的网络风险。
业务镜像有漏洞还有可能引发另外一个问题,内置式镜像组件漏洞。若开发人员所引用的API或使用的一些开发框架存在漏洞,那么当开发人员将开发组件打包到镜像中时,就会出现这类问题。此前影响甚广的Spring框架0 day漏洞,便是因为基础设施漏洞,影响了国内近90%的企业。这类风险通常是研发所引入的,也就是微服务的风险。
云原生安全架构设计
以前的基础设施,主要由防火墙与物理安全进行维护。而容器的计算环境方面,容器运行时安全、镜像安全,需要专业的容器安全进行防护。容器的应用安全,则需要对应的容器安全进行微服务发现与Serverless防护。
云原生场景下,需要把研发安全体系纳入云原生安全领域之中。这与传统安全有所不同。研发人员必须参与到安全的建设体系之中,在研发过程中时刻关注云原生的数据安全,以及一些安全管理的权限。
在小佑目前的容器安全中有非常多的内置策略与机器行为学习策略、处置策略与事件。其中一个特点功能便是编排文件审计。可以直接对接到开发人员的代码仓库之中,从代码仓库中读取代码仓库已存在的所有的Dockerfile文件、Yaml文件、编排文件。并通过Dockerfile文件推断语法,以发现命令中所存在的问题。
审计完成后,若存在问题,则报告研发人员,并禁止构建镜像。若无安全问题,则直接进行修改反馈,待修改完成后生成镜像。此时还会将镜像逆向为Dockerfile,并对镜像与Dockerfile文件进行对比,若发现Dockerfile文件存在篡改,同样会进行警告。
此外,基于镜像运行的容器业务,也会进行逆向,检测容器所依赖的镜像是否正确,镜像中运行的进程是否与Dockerfile文件中打包的进程名称相同等。若发现有任何不统一均会会进行告警,报告这个业务存在风险。
云原生是不可变的,不可变的基础设施包含了底层操作系统与镜像,因此镜像也是不可变的。Dockerfile文件是什么样的,镜像构建出来一定是对应的。镜像是什么样子,运行的容器则一定不会超出这个范围。
另一个特点功能则是从从代码仓库里面直接读取Yaml编排文件。并对编排文件的权限limit,若发现编排文件中存在废弃语法、错误语法、高危命令等危险参数,都会进行告警。这样做的目的是要把安全、运维与研发联动起来。云原生安全一定是运维人员、开发人员和安全人员联动才能处理,并不是安全部门一个部门的问题。
目前市面上有很多开源的镜像的组件的扫描,镜界容器安全防护平台开源版本与商业版本最大的一个区别是自定义规则和漏洞库。开源的漏洞库是基于开源的CBE漏洞库去实现的,支持中国的CNNVD漏洞库。中国的CNNVD需要合作才能获取,正常的开源厂商是拿不到CNNVD漏洞库的。这是开源和商业最大的本质的区别。
在商业版本中,漏洞的自定义功能,例如可信镜像、基础镜像识别、主机镜像扫描等功能,开源产品是不存在的。镜像仓库存在安全风险,企业内部建设安全能力时,必须对镜像仓库自身的漏洞进行扫描。而整个Harbor的安全漏洞小佑是参与维护的,因此在这方面我们有着一定的优势。
集群组件同样存在风险的,为了发现集群组件的自身风险,首先需要做集群自身的组合,并基于漏洞库和漏洞版本比对。同时,对于API接口漏洞与权限漏洞,它是版本比对不出来的,需要用一些POC检查的方式将整个集群组件漏洞的风险检查出来。
对整个集群自身组件的配置进行扫描,可以扫描配置自身权限。最早期的K8S默认是不开启认证权限,现在则默认https。此外,例如审计日志是否开启等功能,需要基于集群安全,配置合规检查基线去进行扫描。
在云原生微服务化的场景下,服务拆分会导致量级指数增长,这时便需要安全软件对微服务的自动发现,并对服务的类型进行识别,以便使用对应的方式去对服务进行自动的漏洞扫描检测。这是非常节省人力的一种方式。
容器运行后的容器内安全检测,可以通过两种模式进行。一种是机器行为学习,通过把容器内部所有的从镜像开始学习,把容器的行为固化掉,同时对容器的文件读写、进程起停和访问调用进行学习,抓出运行的全部行为,并记录到行为模型之中,然后将其总结为容器的行为模型。容器运行的所有的流量,均认为它是正常的流量,所有排出的均认为是异常流量。
但学习需要时间,若学习过程中出遭遇攻击或执行命令,则结果会出现偏差。对此,可以内置了攻击模型的策略,当发现有行为命中了内置安全策略时,则直接就排除。这样便能结合机器行为学习防御0 day漏洞,同时防范学习过程中出现攻击行为这种情况。加之机器行为学习的黑名单内置策略组合,便能够实现完美的机器运行时安全检测的闭环。这是目前容器安全运行时的最佳实践。
在云原生领域中,云原生的微隔离必须要实现以下功能:首先是访问关系的可视化。由于云原生隔离天生满足零信任的风险。K8S没有IP概念,都是基于Label。而Label是研发人员、业务人员所打的标签,基于标签来动态做微隔离。因此必须要基于学习关系,自动生成容器的策略,并将策略进行预演。
当策略学习完成并确认后后,便会进入预演模式,此时可以设置预演时间。在一定时间内,所有正常流量,并不会被阻断。当发现有流量被策略影响时,则会进行警告。研发人员或者业务人员会人为判断,若业务流量安全,则将机器行为学习模型进行编辑,把其排除到模型之外。
一定时间后,若没有发现任何其他流量,则学习完的策略完全不会影响正常的流量模式,并且可以防御所有的流量攻击,这时点击策略执行,便可在不影响生产业务的情况下,将自动学习到的策略应用到生产环境之中。
最后比较关键的一点,在云原生领域中,云原生安全自身软件的平台须要符合三层架构:第一层是管理层,管理平台必须与任务中心解耦,这样所有的集群才可以汇聚。
当镜像仓库的数据量过大时,则可以直接将扫描集成到仓库镜像之中,扫描的同时直接读存储路径,而不是靠网络带宽去拉镜像。这样能够极大减少了网络占用和磁盘IO的占用,直接进行读取。这是目前容器安全的最优的架构设计。
云原生安全最佳实践
云原生环境下DevSecOps设计主要分为三个部分。第一部分是构建环节。这里小佑科技提供了一个黄金镜像仓库,其中是加固过的所有的技术镜像。研发人员可以直接基于黄金镜像仓库去拉取来构建业务镜像。
小佑与CNNVD有官方合作,其漏洞库更新后会直接进行同步。小佑也会根据每天的漏洞更新来实时的维护自身的黄金镜像仓库。另外,小佑拥有自己的扫描器并有专业的安全研究人员会对最新的漏洞和0 day漏洞进行研究。
推荐企业拆分两个镜像仓库,将生产镜像仓库在集群中设置信任判断。这样可以有效防止黑客进入集群,并直接拉一个自己的业务容器下来。用一个K8S接口去拉所有黑客自己的镜像,能够直接就进行所有的渗透。这种情况下是可以完全避免的。
镜像的扫描阶段是做扫描配置、做业务研发的应用层的扫描配置,如果发现漏洞,则阻止同步。在生产环境中,可以设置一个信任判断,将所有条件集成到信任判断之中,例如是否使用了企业自己的环境镜像仓库,都可以在平台上随意配置。
集群自身的组件与微服务的漏洞的风险评估,也可以使用平台上的一些功能实现。以镜像漏洞扫描和分析为例,可以将镜像分成拆出来,这样就可以识别出来每一个镜像依赖于谁做的。技术影响成分、软件成分分析、源代码扫描和开发安全扫描、应用漏洞扫描等。
当容器安全平台检测到攻击事件后,会从事前、事中、事后做整体的安全防范。事前对整个集群进行评估、加固,加固完成后将所有的行为学习启动。进行到事中环节,进行威胁检查和0 day防御,所有的告警都会实时告警。
当发现攻击,首先阻止镜像运行,在研发阶段可以阻止镜像上传,在仓库阶段可以阻止镜像下载,在生产环境可以阻止镜像运行。在容器运行起来后的镜像,可以自动或者手动执行隔离策略。并设置规则进行自动的处理与手动处理。
对于云原生的网络安全规划,由于不同集群间的网络域是不同的,每个集群之间的物理网络默认情况下,K8S网络插件就是overlay的网络插件,因此网络域天然会基于集群与集群之划分网络安全域。
云原生的微隔离必须支持IP的阻断,既要兼容零信任的和Label的阻断方式,又要支持IP的配置,这就是云原生的安全平台的规划方式。同时,也需要利用好传统的安全防火墙,不只要上专用的云原生安全防火墙,还要去结合传统防火墙进行安全防护。
0day攻击预防,可以基于五个维度进行建模:
-
通过对容器内行为进行学习,建立安全模型
-
当检测到模型外的进程、文件访问、异常网络连接和系统调用时,通过关联分析产品风险事件列表
-
人响应处理,及时阻断异常行为或纠正错误
-
在测试环境中生成模型,直接应用于生产环境,无需重新学习
-
零漏洞,支持0 day风险
进程的启动和停止,在一定的学习周期内,进程所读写的文件,都需要进行学习。例如在学习周期后,突然对这样数据库尝试着暴力破解,在短时间内有大量的网络错误、验证错误的攻击行为,则直接认为不符合学习规范。包括系统调用与配置。
前四个维度,都是学习已经运行的容器行为,最后则是学习未运行之前的行为,并预判运行前的状态。这是学习的五个维度。并且学习是历史容器和所有前面容器都会去记录的,用以0 day攻击的预防。