合并前的准备与列结构
把多台主机的时间线合并成一条,是还原横向移动与跨主机攻击链的必要步骤。合并本身不难,难在合并前的规范化:每个来源都要先完成时区换算与偏移修正,再统一列结构(时间、主机、来源、事件、证据引用),最后按时间升序排序。没有这一步的直接拼接,会得到一条看似整齐、实则错位的时间线,结论无法采信。
基本信息
| 列结构 | timestamp_utc, host, source, event, ref |
|---|---|
| 排序键 | timestamp_utc 升序,格式统一为 ISO8601 带 Z 结尾 |
| 时间格式 | 统一为 2026-01-02T03:22:10Z 这类可字符串排序的形式 |
| 主机列 | 必须显式保留,否则无法区分同名事件来自哪台机器 |
| 证据列 | 写清来源文件与行号或事件编号,便于复核 |
| 合并前检查 | 各来源已完成时区换算与偏移修正,且精度一致 |
典型使用场景
- 多台被入侵主机的事件合并,还原攻击者在一台机器上的操作如何跳到下一台
- 把主机日志与设备日志合并,确认外联发生的时间点
- 合并多个来源的同一时间段,验证某条推断是否成立
- 为报告准备一张全局时间线表,作为结论的证据支撑
- 对比处置前后两条时间线,评估清理是否彻底
- 把同一主机不同来源(认证、审计、文件系统)的事件合并成主机级时间线
合并示例
合并示例
# 各主机导出为同结构 CSV,第一行为表头
timestamp_utc,host,source,event,ref
# 拼接:先取 h1 全量(含表头),其余跳过表头
head -1 h1.csv > all.csv
tail -n +2 h1.csv >> all.csv
tail -n +2 h2.csv >> all.csv
# 按第一列升序排序(时间已统一为 UTC 的 ISO8601 格式)
sort -t, -k1,1 all.csv > merged.csv
# 核对行数与时间范围
wc -l merged.csv
head -3 merged.csv; tail -3 merged.csv
# 若来源格式各异,先各自规范化再合并,不要直接拼原始日志合并环节逐项检查
| 环节 | 要求 | 常见问题 |
|---|---|---|
| 时区换算 | 全部换算到 UTC 并保留原始值 | 某台主机未换算,整段偏移 |
| 偏移修正 | 按主机分段修正,注明修正量 | 用同一修正量套用所有主机 |
| 列对齐 | 各来源列语义一致 | 同名列表义不同,排序后含义混乱 |
| 排序 | 按 UTC 时间字符串升序 | 字段内含逗号破坏排序键 |
| 证据引用 | 每行都能追到原始文件与位置 | 只写事件内容,无法复核 |
| 去重 | 重复表头与重复条目清理 | 拼接后残留表头行,排序时跑到中间 |
各来源 CSV 的列语义要先对齐再拼接。不同工具导出的 CSV 列名相近但含义不同(例如同名的时间列可能是本地时间也可能是 UTC),直接拼接会让某一列出现两种含义。
字段内容里含逗号会破坏按逗号分列的排序键。导出时统一加引号,或改用制表符分隔;拼接前先把重复表头清干净。