文章总结: 本文系统解析SIEM(安全信息与事件管理)平台的四层架构:数据来源层涵盖终端、网络、云服务等日志类型;采集层通过代理、API等方式收集数据;处理层进行标准化解析和事件富化;分析引擎通过关联规则实现威胁检测。文档包含C语言代码示例演示日志传输、CEF格式解析及暴力破解检测规则,为安全运营提供实操参考。 综合评分: 87 文章分类: 安全运营,解决方案,技术标准,应用安全,网络安全
SIEM架构解析:从日志采集到威胁响应
原创
钟智强 钟智强
哪吒网络安全
2026年6月17日 11:37 马来西亚
在小说阅读器读本章
去阅读
安全信息与事件管理(SIEM) 是一种平台,用于收集、标准化、关联并分析企业基础设施中的安全日志数据,以检测威胁并支持事件响应。
架构总览
第一层 — 数据来源
| 来源类型 | 示例 | 日志格式 | | — | — | — | | 终端设备 | Windows、Linux、macOS | Windows Event Log、Syslog | | 网络设备 | 防火墙、路由器、交换机 | NetFlow、Syslog、SNMP Trap | | 云 / 应用 | AWS、Azure、Web 服务器 | JSON、CEF、厂商 API | | 身份系统 | Active Directory、LDAP、SSO | Kerberos、LDAP 审计日志 | | 威胁情报 | MISP、VirusTotal、ISAC | STIX 2.x / TAXII 2.x |
第二层 — 采集层
日志通过以下四种机制传输到 SIEM:
-
代理程序(Agent)
— 安装在终端上的轻量级软件(如 Elastic Beats、Splunk UF)
-
无代理(Agentless)
— SIEM 通过 SNMP、WMI 或 SSH 主动轮询设备
-
API 拉取
— 定时调用云服务商的日志接口
-
转发器 / 消息中间件
— Fluentd、Logstash、Kafka 等,用于缓冲和路由高并发日志流
C 代码示例 — 通过 UDP 发送 Syslog 消息(RFC 5424)
#include <stdio.h>#include <string.h>#include <time.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#define SIEM_HOST "192.168.1.100" /* SIEM 采集器 IP */#define SIEM_PORT 514 /* 标准 Syslog 端口 *//* 构建并发送一条 RFC-5424 格式的 Syslog 消息 */int send_syslog_event(const char *hostname, const char *app_name, const char *message){ int sock; struct sockaddr_in dest; char buf[1024]; time_t now = time(NULL); struct tm *t = gmtime(&now); /* PRI = (facility * 8) + severity:14*8+6 = 118(信息级别) */ int pri = 118; snprintf(buf, sizeof(buf), "<%d>1 %04d-%02d-%02dT%02d:%02d:%02dZ %s %s - - - %s", pri, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, hostname, app_name, message); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("socket"); return -1; } memset(&dest, 0, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(SIEM_PORT); dest.sin_addr.s_addr = inet_addr(SIEM_HOST); sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&dest, sizeof(dest)); close(sock); return 0;}int main(void){ /* 模拟两条来自 Web 服务器的安全日志 */ send_syslog_event("web-server-01", "nginx", "User login failed: user=admin src=10.0.0.55"); send_syslog_event("web-server-01", "nginx", "File read: /etc/passwd src=10.0.0.55"); return 0;}
第三层 — 处理层
3a. 标准化与解析
不同来源的原始日志格式各异,SIEM 需将所有字段映射到统一模式(如 CEF 通用事件格式,或厂商自定义的 Splunk CIM)。
#include <stdio.h>#include <string.h>#include <stdlib.h>/* CEF 通用事件格式字段定义 */typedef struct { char timestamp[32]; char src_ip[16]; char dst_ip[16]; int src_port; int dst_port; char action[32]; /* 例如:"ALLOW"、"DENY" */ char severity[8]; /* "LOW"、"MED"、"HIGH" */ char message[256];} CefEvent;/* 将一行防火墙 Syslog 解析为 CEF 结构体 */int parse_firewall_log(const char *raw, CefEvent *out){ memset(out, 0, sizeof(*out)); /* 原始日志示例: "2024-06-15T12:01:05Z DENY src=10.0.0.5:4432 dst=192.168.1.1:22 msg=SSH_attempt" */ if (sscanf(raw, "%31s %31s src=%15[^:]:%d dst=%15[^:]:%d msg=%255s", out->timestamp, out->action, out->src_ip, &out->src_port, out->dst_ip, &out->dst_port, out->message) == 7) { /* 根据目标端口判断严重程度 */ if (out->dst_port == 22 || out->dst_port == 3389) strcpy(out->severity, "HIGH"); else strcpy(out->severity, "LOW"); return 0; } return -1; /* 解析失败 */}int main(void){ const char *raw = "2024-06-15T12:01:05Z DENY " "src=10.0.0.5:4432 dst=192.168.1.1:22 msg=SSH_attempt"; CefEvent ev; if (parse_firewall_log(raw, &ev) == 0) { printf("时间戳 : %s\n", ev.timestamp); printf("动作 : %s\n", ev.action); printf("源地址 : %s:%d\n", ev.src_ip, ev.src_port); printf("目标地址: %s:%d\n", ev.dst_ip, ev.dst_port); printf("严重程度: %s\n", ev.severity); printf("消息 : %s\n", ev.message); } return 0;}
3b. 事件富化
解析后,SIEM 会为事件附加上下文信息:地理位置(GeoIP)、资产归属、用户部门、漏洞评分等。
#include <stdio.h>#include <string.h>/* 地理位置记录 */typedef struct { char ip[16]; char country[32]; char city[32]; } GeoRecord;/* 资产记录 */typedef struct { char ip[16]; char owner[64]; char role[32]; } AssetRecord;/* 简化的内存查找表(生产环境应使用真实数据库或 API) */static GeoRecord geo_db[] = { {"10.0.0.5", "内部网络", "总部"}, {"203.0.113.5", "马来西亚", "吉隆坡"},};static AssetRecord asset_db[] = { {"192.168.1.1", "IT 部门", "网关路由器"}, {"192.168.1.50", "财务部", "工作站"},};const char *geo_lookup(const char *ip, char *city_out){ for (int i = 0; i < 2; i++) { if (strcmp(geo_db[i].ip, ip) == 0) { strcpy(city_out, geo_db[i].city); return geo_db[i].country; } } strcpy(city_out, "未知"); return "未知";}const char *asset_lookup(const char *ip){ for (int i = 0; i < 2; i++) if (strcmp(asset_db[i].ip, ip) == 0) return asset_db[i].role; return "未知资产";}int main(void){ const char *src = "203.0.113.5"; const char *dst = "192.168.1.1"; char city[32]; printf("源 GeoIP : %s,%s\n", geo_lookup(src, city), city); printf("目标资产 : %s\n", asset_lookup(dst)); return 0;}
第四层 — 分析引擎
4a. 关联规则
当事件序列或计数在时间窗口内匹配某种模式时,规则触发告警。
#include <stdio.h>#include <string.h>#include <time.h>#define MAX_EVENTS 1024#define BRUTE_THRESHOLD 5 /* 失败登录次数阈值 */#define WINDOW_SECONDS 60 /* 时间窗口:60 秒 */typedef struct { time_t ts; char src_ip[16]; char event_type[32]; /* "LOGIN_FAIL"、"LOGIN_OK" 等 */} LogEvent;static LogEvent event_store[MAX_EVENTS];static int event_count = 0;void ingest_event(time_t ts, const char *src, const char *type){ if (event_count >= MAX_EVENTS) return; event_store[event_count].ts = ts; strncpy(event_store[event_count].src_ip, src, 15); strncpy(event_store[event_count].event_type, type, 31); event_count++;}/* 规则:暴力破解 — 同一 IP 在 T 秒内出现 N 次 LOGIN_FAIL */void run_brute_force_rule(time_t now){ char seen[64][16]; int seen_count = 0; for (int i = 0; i < event_count; i++) { LogEvent *e = &event_store[i]; if (strcmp(e->event_type, "LOGIN_FAIL") != 0) continue; if ((now - e->ts) > WINDOW_SECONDS) continue; int failures = 0; for (int j = 0; j < event_count; j++) { if (strcmp(event_store[j].event_type, "LOGIN_FAIL") == 0 && strcmp(event_store[j].src_ip, e->src_ip) == 0 && (now - event_store[j].ts) <= WINDOW_SECONDS) failures++; } int already = 0; for (int k = 0; k < seen_count; k++) if (strcmp(seen[k], e->src_ip) == 0) { already = 1; break; } if (failures >= BRUTE_THRESHOLD && !already) { printf("[告警] 检测到暴力破解:src=%s 失败次数=%d\n", e->src_ip, failures); strncpy(seen[seen_count++], e->src_ip, 15); } }}int main(void){ time_t base = time(NULL); ingest_event(base, "10.0.0.5", "LOGIN_FAIL"); ingest_event(base + 5, "10.0.0.5", "LOGIN_FAIL"); ingest_event(base + 10, "10.0.0.5", "LOGIN_FAIL"); ingest_event(base + 15, "10.0.0.5", "LOGIN_FAIL"); ingest_event(base + 20, "10.0.0.5", "LOGIN_FAIL"); ingest_event(base + 25, "10.0.0.5", "LOGIN_OK"); run_brute_force_rule(base + 30); return 0;}
4b. UEBA — 用户与实体行为分析
UEBA 为每个用户 / 实体建立统计基线,并对偏差发出告警(例如:异常时段登录)。
#include <stdio.h>#include <math.h>#include <string.h>/* 基于 Z 分数的登录时段异常检测 */typedef struct { char user[32]; double mean_hour; /* 平均登录时段(0–23) */ double std_hour; /* 标准差 */} UserBaseline;static UserBaseline baselines[] = { {"alice", 9.0, 1.2}, {"bob", 8.5, 0.9},};double z_score(double value, double mean, double std){ if (std < 0.01) return 0.0; return fabs((value - mean) / std);}void check_login(const char *user, int hour){ for (int i = 0; i < 2; i++) { if (strcmp(baselines[i].user, user) == 0) { double z = z_score(hour, baselines[i].mean_hour, baselines[i].std_hour); printf("用户=%-8s 时段=%02d:00 z=%.2f %s\n", user, hour, z, z > 3.0 ? "[告警] 登录时段异常!" : "正常"); return; } } printf("用户=%-8s [告警] 未知用户!\n", user);}int main(void){ check_login("alice", 9); /* 正常 */ check_login("alice", 23); /* 异常 */ check_login("bob", 8); /* 正常 */ check_login("mallory", 2); /* 未知用户 */ return 0;}/* 编译:gcc ueba.c -lm -o ueba */
第五层 — 存储
| 层级 | 保留期限 | 查询速度 | 用途 | | — | — | — | — | | 热层(Hot) | 0–30 天 | 快速(RAM/SSD) | 实时调查、仪表盘 | | 暖层(Warm) | 30–90 天 | 适中 | 事件复盘 | | 冷层(Cold) | 90 天 – 7 年 | 较慢(对象存储) | 合规留存、取证 |
第六层 — 响应层
SOAR 联动(C 风格伪代码)
#include <stdio.h>#include <string.h>typedef enum { SEV_LOW, SEV_MED, SEV_HIGH, SEV_CRITICAL } Severity;typedef struct { char rule_name[64]; char src_ip[16]; Severity severity;} Alert;/* 模拟 SOAR 动作 */void block_ip(const char *ip){ printf(" [SOAR] 防火墙已添加规则:阻断 %s\n", ip); }void isolate_host(const char *ip){ printf(" [SOAR] 主机 %s 已从网络隔离\n", ip); }void create_ticket(const char *rule, const char *ip){ printf(" [SOAR] 工单已创建:规则='%s' 来源=%s\n", rule, ip); }void notify_soc(const char *msg){ printf(" [SOAR] 已通知 SOC:%s\n", msg); }/* SOAR 剧本调度器 */void run_playbook(const Alert *a){ printf("执行剧本,告警:%s\n", a->rule_name); switch (a->severity) { case SEV_CRITICAL: isolate_host(a->src_ip); block_ip(a->src_ip); create_ticket(a->rule_name, a->src_ip); notify_soc("严重告警 — 主机已隔离"); break; case SEV_HIGH: block_ip(a->src_ip); create_ticket(a->rule_name, a->src_ip); break; case SEV_MED: create_ticket(a->rule_name, a->src_ip); break; default: printf(" [SOAR] 仅记录日志(低严重程度)\n"); }}int main(void){ Alert a1 = {"暴力破解-SSH", "10.0.0.5", SEV_HIGH}; Alert a2 = {"勒索软件-C2", "203.0.113.5", SEV_CRITICAL}; run_playbook(&a1); putchar('\n'); run_playbook(&a2); return 0;}
关键标准与框架
| 标准 | 用途 | | — | — | | CEF (通用事件格式) | ArcSight 日志模式 | | LEEF (日志事件扩展格式) | IBM QRadar 日志模式 | | STIX / TAXII | 威胁情报共享 | | MITRE ATT&CK | 攻击战术 / 技术映射 | | PCI DSS | 支付卡合规(要求部署 SIEM) | | ISO/IEC 27001 | 信息安全管理体系 |
主流 SIEM 产品
| 产品 | 厂商 | 备注 | | — | — | — | | Splunk Enterprise Security | Splunk | 市场领导者,SPL 查询语言强大 | | Microsoft Sentinel | Microsoft | 云原生,深度集成 Azure | | IBM QRadar | IBM | 本地/云部署,关联引擎强 | | Elastic SIEM | Elastic | 基于开源 ELK,灵活扩展 | | Chronicle | Google | PB 级规模,按量定价 |
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:哪吒网络安全 钟智强 钟智强《SIEM架构解析:从日志采集到威胁响应》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论