浅谈安全运营平台中数据分析交互逻辑的设计
0x00 前言
今天本来是打算发另一篇文章的,但是由于这两周一直在敲代码,所以几乎没有时间去打磨里面的内容,于是先鸽了。在调研AWS SecurityHub和Google SCC这两个云平台的SOC的时候,我发现了老外在SOC的建设上和国内的理解有点不太一样,但是背后都是依赖很强大数据处理交互技术和内部的安全专家规则,尤其是Chronicles推出BackStory的时候,我惊讶的不是它的功能,而是他的pb级别日志处理能力,通过查阅各种资料知道,BackStory的高性能并不是简单堆算力实现的,而是通过强大的查询分配引擎选择自动下发最高性能的查询方式实现的,这一点令我很是惊讶,于是花了一些业余时间对这一部分进行了一些研究和分析。考虑到各位大佬都发了年终总结,所以我也可以随便总结一下。
熟悉我的同学可能知道我从下半年开始一直在打招聘广告(不错,这篇文章依旧是一篇广告文),可见人手有多么的缺,从今年下半年开始(准确来说是上半年快要结束的时候)就一直埋头在开发和优化公司的安全运营平台,倒不是说功能难理解和开发,团队的小伙伴们其实花在数据处理和清洗的时间上其实远远超过了很多功能的开发上(大家都是过来人,多多少少对安全运营的业务都有了解),最后通过几轮复盘后发现,实际上我们在运营平台设计的时候只思考了我们需要什么功能,而忽视了背后有些功能是需要很深厚的工程化能力作为支撑的,于是下半年写绩效的时候,我在需要提升的环节里着重强调了工程化这三个字,在我看来工程化这三个字最直接的体现是在持久、低成本和专家经验固化。实际上除了安全攻防专家经验的固化(这一部分实际上是以Playbook的方式固化到SOAR系统里面)之外,更重要的是数据分析能力的固化,所以很荣幸,下半年有了折腾数据平台的机会,自己的研究并实践了一下安全运营平台背后的数据平台的建设,所以这也算是今年收获比较多的一个方面。
0x01 数据交互设计对于安全运营的意义
前面我们说到了我们实际上的安全建模和安全运营工作,很大一部分是面向数据的工作,包括但不限于写规则、查日志、做DFIR、溯源等等,所以现在很多甲方蓝队的同学尤其是做感知和响应的同学与其说是防守能力的建设,不如说是面向数据进行工作。
有些人可能就说了,不就是查个日志么,有这么麻烦么?Elastic三件套直接解决啊。我不否认使用ElasticStack可以解决绝大多数的安全问题(实际上Kibana用的好的话,一样是可以当SIEM去用的),包括我自己一开始都是这么认为(一开始刚加入美团的时候一直不理解为啥要通过HIVE去查日志,内部也有ES这种分析引擎,直到自己亲手解析过日志并且做检索的时候才发现事情不是我以为的那么简单),但是后来发现受制于成本和公司的数据平台技术,且不说ES比较吃资源这种事情,就说需要用到的日志在ES里面能不能存够两周都是一个巨大的挑战(调研了几家同行的操作,基本上安全相关的算力占公司大数据资源的比例其实都也不小)。所以我们需要在计算时间和算力资源之间寻找一个平衡点,这个平衡点就是合适的场景选择合适的计算方法。
除了这个之外,安全运营工作中最常见的两类场景实际上是威胁风险规则编写和安全事件调查,风险规则编写这一部分绝大多数是依赖于实时计算引擎搭配离线分析去实现,而安全事件调查则是从一大堆数据里面去查几条数据,数据量一大就变成了大海里捞针,所以你会发现再查一个case的时候,很多大佬就直接在那边刷起网页了,不是因为他们不敬业,而是日志查询实在是太慢太慢了(有时候一个日志查40多分钟都查不出来,更别说触发了Presto的查询熔断机制直接把任务kill掉了),有的时候为了保证成功率,都是一天一天的导出日志然后丢到一个临时搭建的ES里面去查,所以很多时候事件调查的时间就卡在了这里。这个时候我们根据经验往往会使用ES去维护7天左右的热数据,如果查不到再使用Hive/Presto去做冷数据查询,但是实际情况是,很多人SQL可以写但是写DSL的的时候就懵了,有的时候只能依赖运营手册去解决,这样也会拉低工作效率,也就进一步会影响事件响应的MTTR,指标会很难看。
总结一下,我们通过上面的两个case会发现,很多时候在解决安全运营的实际问题中,消耗时间最多的可能不是去响应告警或者事件本身,而是各种各样的数据操作原因导致的响应时间变长,所以做好数据层级的交互设计可以很明显的缩短响应时间,让指标变漂亮。简单说一下就是好的数据交互设计会提高安全运营的效率。
0x02 安全数据的交互设计与层级划分
我们通过上面的分析,大概得出了高效率的数据交互可以直接提升安全运营的效率,那么如何去设计这一部分呢。从个人的实践经验来看,绝大多数情况都是RD和PM没有对SOP达成一个一致的认知导致的,很多情况下可能是PM对RD说:我需要实现一个功能可以去筛选出来有风险的组件,然后对这些推工单进行修复。RD就直接去实现了这个功能的开发,但是PM没有说清楚我这个功能是为了解决什么问题,很多时候RD会想当然的把效率转换成自动化,能自动化就能提升效率,这个观点在绝大多数场合没啥毛病,但是实际上在有些需要对MTTR有要求并且涉及到大量数据分析的安全业务场景中,可能自动化会适得其反。所以PM在提需求的时候一定要同步到RD这个需求是用来解决什么安全问题的,同时告知RD相关联的一些指标,这样RD才能开发出满足要求的产品,同时RD也要主动询问PM需求是固定的还是一次性的(很多PM不会提需求,导致RD把很多一次性的需求当成了永久性的需求去做了),这些问题会直接影响技术选型等问题。
感觉扯远了,回到安全数据交互的问题,数据交互这个词很好理解,就是用户对数据的操作获得一个期望的结果。影响数据交互效率的两方面一方面是算法的时间和空间复杂度,另一方面是数据分析平台的设计问题。这篇文章主要集中讨论后者。
对数据分析有一定了解的朋友可以跳过以下部分。下面我们花一点篇幅来讨论一下在安全场景中会用到的数据分析模型和思路。
在设计数据交互系统时,首先需要查询和存储这两个层面来考虑,需要考虑的因素包括:数据大小有多大、数据如何使用、数据更新频率。
我们先来从数据大小说起,大概我们画一个图来说明一下,图上的内容根据公司的不同可能内容也不尽相同。
一般情况下这些数据的数据量跟资产和业务复杂度成正比,如果是比较大的公司的话,PB级别可能真的不是什么问题。
至于数据的应用场景,这个则是跟安全的需求强相关的,但是从整体上来看,这类应用场景本质上可以分为两类:联机分析处理(OLAP)和联机事务处理(OLTP),OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,例如从accesslog中查找带有某个特定IP的访问记录。OLAP是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。OLTP一般就是把大数据用于在线业务,比如某个漏洞受影响资产的展示等。这种需求要求有实时性,查询以后需要在秒级别返回,且对于服务稳定性和容错性有一定要求的。另外,读操作的数量远远大于写操作,且增量数据的大小要远远小于历史数据。而OLAP主要是做离线分析,对时效性要求不高,跑几个小时到几天问题都不大,并且机器挂了也没事,大不了重启一下完事。但是这种系统往往数据量非常大,数据的维度特别多,基本都需要把历史数据全部扫描若干遍。在设计OLTP查询模型的时候,往往复杂的地方在于数据分层、分片以及分布式事务上,而在设计OLAP查询模型的时候影响性能的主要是列存储、切分和降维。OLTP做起来相对容易,并且企业产品和开源产品非常多,而OLAP相对起来较为复杂,由于数据的维度非常的多,SQL语言在在这种条件下进行数据分析也会显得力不从心。所以在OLAP的设计中,建模和抽象变得很重要,如何解决数据的语义性和查询的可描述性变得很困难。相比起来,这方面的突破才显得不那么容易。
而对于数据的更新频率,这一部分取决于各家安全产品数据扫描的更新能力和策略,在有些场景下可能更新频率高,有些则更新的频率低。
以上就是我们设计这一部分数据交互的目标:大的目标是提高数据的查询效率,拆解成对应的关键能力就是尽量减少需要分析的数据量和复杂程度、选择合适的分析方法、控制数据的更新频率。
0x03 业务模式vs数据查询场景
通过上面的简单介绍,我们大概确定了我们设计这个数据平台的目标:
(1)尽量缩小需要分析数据量和复杂程度——数据清洗与优化
(2)选择合适的分析方法——拆解安全运营场景中数据分析的方法,通过规则自动下发到对应的处理引擎
(3)控制数据的更新频率——按照数据更新频率对数据储存进行分级,高频更新存放到KV,低频则存放到HDFS
确定了以上三个目标之后,我们把整个数据交互的逻辑拆解成四层,分别对应业务应用的场景、对应数据的处理逻辑、数据的总线和清洗规则、底层原始数据的收集,如下图所示。
其实在设计的时候,我们可以采取从数据和业务场景的两端向中间推进的方法去思考好如何设计数据处理的逻辑和数据清理的规则。我们在梳理资产的时候,最好把所有的安全数据分为正向数据和反向数据两类,比如说软件编译制品相关产生的依赖数据和HIDS的包采集数据就可以互为正反数据,一般会采用前者作为正向数据,后者作为反向数据,设计正反向数据的初衷是为了解决数据覆盖度的问题,防止因为资产变动或者agent覆盖率的问题导致资产数据不全。在将原始数据分类完成后,我们需要将这些安全数据标准化,也就是封装成一个或者几个统一的数据结构,用来满足后续数据分析侧的要求。在将数据格式统一之后,我们需要对日志进行一个全局的过滤和索引,这一部分过滤主要是保证数据的有效性,二来有了数据的索引,裸查询走Ad-Hoc查询也会快一点。数据过滤索引完成的数据通过消息总线(一般都是kafka集群或者是消息队列集群)向上传递,到此,你将会获得一个统一的数据资源池。结果如下图所示。
现在我们有了数据,接下来我们就需要从业务场景倒推分析模式和数据,然后选择效率最高的一个来进行分析。一般情况下,安全运营侧的业务基本上就分成了以下几类:
数据建模类:通过编写实时或者离线的规则完成某一方面风险检测模型的开发
应急响应类:触发了某一起事件,然后需要做一些调查取证的DFIR类工作
风险巡检类:检测某些资产是否存在风险配置和安全漏洞之类的情况
向上管理类:定时定点输出数据给领导提供给上面汇报的工作(领导看见这个别打我)
所以我们可以把以上的需求拆解成若干个查询的动作,然后去分析这个需求的查询行为树(也就是把他们需求以查询行为为维度进行划分),紧接着按照这些查询行为的顺序进行查询任务的分配与调度,然后汇总返回结果(这里可以人工调度也可以走Playbook或者通过AI进行调度,虽然用AI比较玄乎但是感觉未来这一部分用AI会是趋势,但是现在还是老老实实依赖人工或者Playbook吧)。通过以上的汇总,我们可以把这些场景分成四类:
实时计算类场景:数据建模啊、规则啊之类的
一次性场景:做完就完了或者复用程度很低的场景
OLAP类场景:特定规则检索和输出的场景
OLTP类场景:查日志之类的
按照这四类分类后,我们回将任务下发到调度引擎上,通过调度引擎将查询任务下发到对应的查询引擎上,同时等待返回的结果,然后通过调度引擎按照之前既定的规则合成返回结果,返回给业务前端,这样就完成了对业务需求的响应,具体的分层如下面这张图(这张图如果有建设经验的或者是有场景运营经验的,可以发简历给我私信或者发送到lizhongwen02#http://meituan.com,我很希望与你一起共事)。
接下来我们就会发现一个情况,随着用户使用频率的增加,我们需要不断地迭代查询任务下发引擎的分配规则和查询成功率,以及响应时长,即可完成运营时间MTTR的优化,也就是说查询慢这个问题是有解决方案的。
0x04 总结
本来这篇文章是打算放在一篇分析AWS SecurityHub和Google SCC这两个企业级SOC产品的设计逻辑以及产品思路的文章后面,但是那篇文章一直不太满意,所以先把这篇存货发了,希望在设计安全运营平台的数据交互的时候有一些参考的意义。
ref:
OLAP、OLTP的介绍和比较_VICTOR1984的专栏-CSDN博客