【作者】付广平,任职民生银行云技术管理中心,负责云基础架构、运维以及云计算相关技术研究。毕业于北京邮电大学,从2013开始从事OpenStack相关工作,参与了OpenStack Nova、Cinder、Cloud Custodian等项目社区开发,公众号int32bit作者。对AWS公有云、Docker、Kubernetes等技术也有一定的了解。 1 云资源安全合规基线需求和问题 云平台通过自服务接口提供了快速的资源供给方式,用户通过云平台console或者云管平台可以灵活按需快速构建云资源,甚至可以在几分钟构建自己的虚拟数据中心,资源的快速构建已不是什么难事,真正的难事在于如何有效治理好云资源,安全合规治理、标签治理、配置与安全基线检查等都不是什么容易的事。 如果前面有云管则可以挡一道,做一些配置限制、基线检查以及自动调整,但同时也失去了部分灵活性,并且也难以做到覆盖所有规范点。部分企业采用保姆式,云基础资源的申请均由云部门统一管理,包括创建和更新,通过一系列流程完成云资源最终交付,业务部门只需要能够通过堡垒机访问即可,这样其实工作都压在了云部门,交付也失去了敏捷性。 无论采用哪种方式,管理员都避免不了对云资源进行审计和检查,云基础资源管理员往往需要花费大量的时间去检查资源是否满足安全合规性、是否符合监管要求、是否遵循安全配置基线,常做的工作如检查资源的标签是否完备并且符合规范、安全组是否开放了高危端口、虚拟机是否使用了满足要求的黄金AMI、业务有没有考虑跨多AZ、磁盘是否加密、虚拟机是否直接挂弹性IP等等,虚拟机资源甚至还需要类似主机IDS工具做进一步OS级别的基线检查。 通常我们有如下几种方法来完成如上工作:
第一种方法没什么可说的,一两个账户可以这么玩,几十上百个账户基本不可行。第二种方法最大的问题是脚本开发和维护比较难,除非自己实现一套规则引擎框架,否则一个规则一个脚本,根本无法维护。 因此我们主要讨论第三种方案,以AWS为例简要介绍如何利用AWS托管服务做基线自动检查与配置。 2 安全基线自动化检查与配置相关服务简介2.1 操作记录审计服务安全基线自动化配置和检查从用户操作的时间点就已经开始了,云平台每一次在处理API调用时都会记录谁在什么时候执行了什么操作,每一次操作都会产生一个事件,事件中还会包含API调用的请求参数、创建的资源对象等信息。 这个功能不仅是监管以及安全审计要求,也是真正实现基于事件驱动的基线检查持续性和实时性的基础。 CloudTrail是AWS的审计服务,记录了所有通过AWS管理控制台、AWS开发工具包、命令行工具和其他AWS服务执行的任何操作。 2.2 事件与性能监控服务光产生了操作记录事件还不行,要实现基线自动化配置和检查,还需要把这些事件监控起来,因此需要监控服务。监控服务不仅仅包括监控其他服务的性能指标,还包括监控所有的事件和日志。由于监控指标和事件往往都会很多,因此监控服务还需要支持根据一定的条件进行数据过滤,传统的监控服务如Zabbix、Prometheus都支持。 Cloudwatch是AWS的监控服务,支持根据规则过滤和监视各种事件。 2.3 Serverless计算事件产生了并且也监控起来了,剩下最后一步就是真正的action。你可以订阅这些事件或者轮询发生的事件,然后自己起一个虚拟机部署handler服务来处理消费这些事件。但我认为最适合用来做action的是serverless计算,又称函数计算。 这是因为:
AWS Lambda服务是AWS的函数计算服务,支持各种事件触发,其中包括Cloudwatch。 3 安全基线自动化检查与配置实现方案3.1 手动拼积木有了前面的基础,充分利用和集成云平台已有的托管服务,很容易就可以实现安全基线自动化检查与配置工作了。 以AWS安全组规则为例,只需要开启Cloudtrail功能,并在Cloudwatch中配置规则Rule监听 AuthorizeSecurityGroupIngress事件,然后Target配置触发Lambda函数,Lambda函数拿到事件,找到安全组规则对应的资源对象,检查是否满足要求,不满足要求则进行通知告警,通过lambda能做权限范围以内的任何事。 另外以一个AWS上常见的问题为例,我们知道AWS的EC2、EBS等资源是不记录创建用户的,如果一个账户有多个用户,在EC2列表中根本查不到这个虚拟机到底是谁创建的,只能通过cloudtrail在海量日志中慢慢去找了。 解决的办法其实也很简单,通过cloudwatch监听cloudtrail的RunInstances事件并触发lambda函数调用,这个lambda函数负责把event取出来,根据event的记录的用户名把标签CreatorName打到EC2实例上即可。 我们发现这种方案的工作量主要集中在Lambda函数的代码开发。 3.2 使用云平台托管服务很多云平台都提供了专门的配置基线检查托管服务,比如OpenStack Congress服务、AWS的Config服务,使用这些托管的服务,利用其内置的规则能够省去写lambda代码。 以AWS Config为例,目前国内AWS已经支持83条托管规则,包括:
但是AWS Config服务只能做合规性配置基线检查,不能做任何操作。另外如果托管的规则不能满足需求,Config还支持触发自定义Lambda函数。 3.3 使用Policy As Service服务前面介绍的方法配置都不是什么难事,难就难在需要自己写lambda函数,规则多了工作量还是挺大的,并且规则多了代码维护起来也特别麻烦。 如果能把规则逻辑从代码中抽象出来,用户只需要声明或者定义规则,不需要每个规则都要自己写lambda函数告诉平台怎么一步步处理,而只需要复用一套通用规则引擎,则显然无论工作量还是管理难度都会大大减少。 这就是我们将要介绍的Policy as Service服务,我们只需要根据规则声明Policy,无需关心具体怎么实现的,只要关心最终状态是否满足我们声明的规则即可。声明式编程在其他地方也被广泛使用,比如Kubernetes通过YAML文件声明资源,Docker Compose也是,Terraform也是如此。 Congress是针对OpenStack基于Policy声明的安全合规配置基线检查工具。CapitalOne开源的cloud custodian(简称c7n)也是基于policy声明的云资源配置基线检查工具,目前支持AWS、Azure以及GCP,未来可能还会支持Kubernetes。 本文接下来简单介绍下cloud custodian项目。 4 cloud custodian项目简介相比前面的介绍的方法需要自己写lambda函数或者脚本,c7n是声明式的,这很符合现代的使用模式。 c7n policy包含3个主要部分:
4.1 resourcec7n支持AWS 162种资源类型,通过 custodian schema可以列出所有的resource类型:
4.2 filters不同的resource支持不同的filter type,其中value type可以说是最朴素也是最通用的filter type了,直接读取resource的属性值进行匹配。 比如我们通常会制作自己的黄金AMI,我们要求业务必须使用黄金AMI启动虚拟机,通过如下filters可以找出所有不合规的虚拟机列表:
比如过滤所有运行状态为running的AWS ec2虚拟机,filters可以简化为:
如果匹配所有没有打Custodian标签的资源列表可以写成 'tag:Custodian':present,其中 present是一个特殊的操作符,表示该属性值不存在,更多的操作符可以参考官方文档Generic Filters。 除了value的filter type,针对特定的resource类型,还有许多非常有用的filter type,通过 custodian schema aws.ec2.filters可以查看AWS ec2支持的所有filters type,比如instance-age type可以基于实例创建时长进行过滤:
4.3 actions和filters一样,不同的resource type支持不同的action,以ec2为例支持的actions包括但不限于如下:
4.4 一个完整的例子有了resource、filters、actions我们就可以确定针对哪种资源满足什么条件执行什么动作了。 还是以前面的黄金AMI为例,假设我们针对没有按照要求使用管理员规定的黄金AMI的不合规虚拟机执行关机操作,
4.5 modecustodian是一次运行的Job任务,和Terraform一样运行完任务就结束了,没有运行任何后台服务。因此需要每次在虚拟机上敲命令行手动执行,当然聪明点的做法是写一个cron job,每隔一段时间自动跑一遍。 如果c7n只支持这种模式那就没啥用了,显然c7n不会做得这么低端。 其实c7n最强大的功能角色是充当粘合剂,把云平台的各种配置功能粘合在一起,集成云平台已有的托管工具。 以AWS为例,由于c7n是一次运行的无状态Job任务,那其实根本就不需要在虚拟机上本地运行浪费虚拟机浪费钱,现在都流行serverless了,lambda再合适不过了。 谁来触发lambda,当然event最合适,因此使用cloudwatch触发最合适。event谁来产生,cloudtrail会记录AWS的所有API调用event,因此cloudtrail最合适做event的记录和发布了。 AWS支持cloudwatch、cloudtail、config-rule等各种mode。 还是以AWS自动给资源打上User标签的问题为例,前面已经介绍了实现方案。现在的问题是如果有很多账户,每个账户都手动配置一遍显然非常繁琐且耗时间。当然可以把lambda函数提前放到S3上,然后通过Terraform配置lambda、cloudwatch、cloudtrail,不过这种方式单说lambda函数不说,光Terraform代码没有几百行肯定是搞不定的。 而使用c7n则只需要写一条policy,不到20行代码:
执行这个policy后会自动生成lambda函数,代码是自动生成的(其实就是c7n的源码): 触发器为CloudWatch Events,可以查看其配置如下: 除了事件驱动,基于时间轮询也是没有问题的,对应c7n mode为periodic,实现方式则通过cloudwatch的Schedule方式触发lambda函数。 比如每小时检查下是否存在安全组暴露了高危端口到互联网:
5 总结本文首先介绍了云平台和资源的安全合规配置基线的需求和问题,然后介绍了如何集成云平台已有的托管服务实现云平台和资源的安全合规自动配置和检查,最后以custodian为例介绍基于Policy规则声明式配置和检查安全合规基线。
|
|