安全日志搜集与标准化

在一些安全系统中,需要将各种安全设备的日志搜集上来后,再进行标准化以便进行分析。

在设计这类系统时,有以下知识与经验可以借鉴。

保留原始日志#

在日志中通过一个字段(比如:“rawEvent”)来存储原始的日志内容,有助于回溯原始的日志内容,帮助发现日志处理过程中有哪些问题。

必要时也可以通过这个字段恢复原始日志并重新进行日志处理,当然如果系统中有 Hadoop 或 Kafka 长期存留日志的话也可以达到同样的效果。

在日志处理过程中增加处理器的标识#

在日志的处理过程中可能会经过:生成,转发,搜集,解析,入库,归并等过程,在每个处理过程中增加本过程的标识,可以方便发现问题。

每个处理过程至少都应该增加开始处理的时间,这样可以方便的统计各个过程的时间消耗。

通过增加过程标识(例如:探针ID,搜集器ID,解析规则ID等),可以清楚的看出来整个日志的流转过程。

日志解析#

如何对日志进行解析?第一个想到的可能是正则表达式,如果日志有很多字段,捕获这些字段的正则表达式则会比较繁琐, 如果再加上对每个字段的校验的话,解析一条日志的正则表达式将会非常难以阅读和维护。

Grok 是一个可以简化这一过程的工具,可以将其理解为正则表达式的宏。例如解析一个ipv4的字段并存储在变量中,正则的写法是:

(?<ClientIp>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)

用 Grok 的写法是:

%{IPv4:ClientIp}

由于 Grok 内置了常见字段的解析,所以编写时只要使用就可以了。

例如要解析下面的日志:

55.3.244.1 GET /index.html 15824 0.043

可以使用下面的写法:

%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}

具体的介绍可以参考:

https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html#plugins-filters-grok

https://logz.io/blog/logstash-grok/

日志标准化#

如果要将不同的安全设备日志放到一起进行分析,则需要对日志进行标准化处理,使其字段都统一成一个标准。

若是没有丰富的安全设备日志处理经验,很可能无法设计出一套合理的标准化字段,想办法站在巨人的肩膀上则可以规避很多坑。

目前我看到有两种公开的日志标准化方案:

CEF (Common Event Format)#

该标准由 ArcSight 提出,算是一个在国外被广泛使用的标准,奇怪的是关于标准的说明很难找,我只找到下面两个地址:

https://www.microfocus.com/documentation/arcsight/arcsight-smartconnectors-8.3/cef-implementation-standard/#CEF/AS_smartconn_Intro.htm?TocPath=_____1

https://raffy.ch/blog/wp-content/uploads/2007/06/CEF.pdf

CEF标准规定了简单的几个必要的字段以及不少扩展字段,其字段的 key name 是为了传输时简化而缩写的,在日志解析入库后还是应该考虑使用字段的 full name 。

其字段以扁平化的列表形式定义,字段中主要有几个分类:device,source,destination,file,oldFile,request 。

其中的 source 和 destination 是一个泛化的概念,例如在网络时间中可能会有:sourceAddress,sourcePort,destinationAddress,destinationPort 字段, 而在主机的事件中,可能会有:sourceProcessId,sourceProcessName,destinationProcessId,destinationProcessName 字段。

如果事件中只涉及一个进程,使用 source 还是 destination 就要靠实现者酌情处理了。

但在文件信息上,其由使用了 file 和 oldFile 两个分类,给人的感觉有点不一致。

CEF 解析后表示一个五元组的示例:

{
  "sourceAddress": "10.42.42.42",
  "sourcePort": 38842
  "destinationAddress": "10.42.42.1",
  "destinationPort": 443,
  "transportProtocol": "TCP"
}

ECS (Elastic Common Schema)#

由 Elastic 开发的用于在 Elasticsearch 中标准化的存储事件数据的规范:

https://www.elastic.co/guide/en/ecs/8.7/ecs-reference.html

与 CEF 最大的不同是 ECS 对各种对象都进行了定义,而且使用了嵌套的结构来表达关联的信息。

例如 ECS 定义了 process 对象的字段,而 process.parent 可以是另一个 process 对象来描述其父进程的信息。

ECS 表示一个五元组的示例:

{
  "source": {
      "address": "10.42.42.42",
      "ip": "10.42.42.42",
      "port": 38842
    },
  "destination": {
      "address": "10.42.42.1",
      "ip": "10.42.42.1",
      "port": 443
  },
  "network": {
      "transport": "tcp"
  }
}
comments powered by Disqus