日志关联分析基础:从收集到关联

说到DSPM的日志关联,我想先聊聊我个人的理解。

你手头可能有几十个数据源,每个都在往外吐日志。但单看一条日志,就像只看一头大象的尾巴——根本不知道全貌。日志关联分析,说白了就是把分散在各处的“证据”串起来,还原出完整的安全事件。

这个章节,我们来拆解日志关联分析的基础。我会从收集、格式、存储三个角度,讲讲我在实际项目中是怎么做的。

日志收集:别漏了关键的数据源

很多团队一上来就搭关联分析平台,结果发现日志不全。为什么?因为收集阶段就出了问题。

我个人习惯,先画一张数据源地图。把你所有的数据资产列出来,然后给每个资产打标签:会产什么日志?日志在哪?怎么拿到?

典型的数据源可以分类如下:

类别 数据源 日志内容 收集方式
网络设备 防火墙、路由器、交换机 流量日志、访问控制、连接会话 Syslog
主机系统 服务器、容器、工作站 登录事件、进程启动、文件操作 Agent / 审计日志
数据库 MySQL、PostgreSQL、MongoDB 查询语句、权限变更、慢查询 审计插件 / 日志导出
应用层 Web服务、API网关、业务系统 HTTP请求、业务操作、异常堆栈 文件采集 / Logstash
安全设备 IDS/IPS、WAF、DLP 告警事件、规则命中、拦截记录 Syslog / API拉取

这里有个坑,我踩过好几次:很多系统的日志默认只保留7天,甚至3天。等你发现需要回溯分析时,日志已经没了。

小建议:收日志前,先确认日志的保留策略和滚动周期。需要的话,在源头把日志复制一份,确保不丢。

日志格式:标准化是关联的基石

日志收回来之后,你会发现一个问题——十种设备,十种格式。有的用JSON,有的是纯文本,还有的用自定义的二进制格式。

我有个原则:不管源头是什么,进入存储层之前必须统一格式。不然你的关联查询会写到崩溃。

最常见的标准化方案是用Syslog配合CEF或JSON。

举个例子,一条原始日志可能是这样的:

May 27 14:23:10 server01 sshd[12345]: Failed password for root from 192.168.1.100 port 22 ssh2

标准化之后,它变成这个样子:

{
  "timestamp": "2024-05-27T14:23:10+08:00",
  "source_host": "server01",
  "process": "sshd",
  "event_type": "authentication_failure",
  "username": "root",
  "source_ip": "192.168.1.100",
  "protocol": "ssh",
  "message": "Failed password for root from 192.168.1.100 port 22"
}

你看,标准化之后,所有的关键字段都被提取出来,变成了结构化的键值对。这样你写关联规则就容易多了:直接查 `event_type == "authentication_failure"` 就行了。

核心思路:日志格式标准化越早做越好。我见过太多项目在分析阶段才想起做解析,结果搞得查询效率极低。最好在收集端就搞定,比如用 Logstash 或 Fluentd 的 filter 插件。

日志存储:容量和查询速度的平衡

日志存哪儿?这是一个经典的选型问题。

我个人建议,按使用场景分层存储:

  • 热数据(近7天):放在 Elasticsearch 或 ClickHouse 里。查询快,支持全文检索,适合实时分析。
  • 温数据(7-30天):可以放在对象存储(比如 S3 或 MinIO)里,配合 Presto 或 Trino 查询。查询速度慢一点,但成本低了很多。
  • 冷数据(30天以上):压缩后存到廉价的冷存储里,比如 Glacier 或本地归档。平时基本不查,但合规要求必须保留。

这个分层的方式,我在一个日志量每天几个TB的项目里用过,效果还不错。既控制了成本,又保证了关键的查询性能。

注意:千万不要把所有的日志都塞进同一个索引或表。数据量一上来,查询会变成灾难。按时间或数据源分区是必须的。我曾经见过一个同事把所有日志丢到一个 Elasticsearch 索引里,3天后索引直接崩了。

日志关联分析的核心逻辑

日志收好了,格式也统一了,接下来怎么关联?

其实核心就几个套路:

  1. 时间窗口关联:把某个时间窗口内的所有日志串起来。比如“5分钟内,同一IP登录失败5次,然后成功登录”——这很可能是一次暴力破解。
  2. 实体关联:找共同属性。比如多个事件都指向同一个文件、同一个账号、同一个IP。把这些事件放到一起看,才能看出攻击链。
  3. 行为序列关联:把一个用户或设备在一段时间内的操作按时间排列。比如:先SQL注入,然后创建高权限用户,再导出数据。每个操作单独看可能都不敏感,但串起来就是一次完整的攻击。

拿我遇到过的一个真实案例来说吧。有个客户的日志告警每天几千条,但没人认真看。我帮他们做了一个简单的关联规则:如果同一个端口在10分钟内被10个不同源IP探测,标记为扫描行为;如果扫描之后30分钟内有来自同一IP的登录尝试,升级为高危。

就这一条规则,把90%的无意义告警过滤掉了,剩下的才是真正需要关注的行为。

下面这张图展示了从日志收集到关联分析的完整流程,你可以对照着梳理自己手里的环境:

日志关联分析流程 网络设备日志 主机系统日志 数据库审计日志 应用层日志 日志收集层(Syslog / Agent / Logstash / Filebeat) 日志标准化(统一为 JSON / CEF 格式) 热存储(Elasticsearch) 温存储(对象存储+Trino) 冷存储(归档压缩) 关联分析引擎(时间 / 实体 / 行为序列关联) 最终输出风险事件