首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >安全监控与分析:从日志采集到威胁狩猎的工程化实践

安全监控与分析:从日志采集到威胁狩猎的工程化实践

原创
作者头像
用户12339161
发布于 2026-09-28 17:24:09
发布于 2026-09-28 17:24:09
850
举报

安全监控与分析(Security Monitoring & Analysis)是 SOC 的核心能力。它不等于"堆 SIEM 买告警",而是一套采集 → 规范化 → 检测 → 关联 → 响应的工程体系。本文从日志管道讲起,覆盖检测规则、告警降噪、异常检测与响应编排,给出可落地的代码。

一、日志采集与统一 Schema

多源日志若不归一化,检测规则无法复用。定义统一事件结构是第一要务。

代码语言:javascript
复制
import json, hashlib
from dataclasses import dataclass, asdict, field
from datetime import datetime, timezone

@dataclass
class SecEvent:
    ts: str
    source: str          # firewall / edr / waf / auth
    host: str
    user: str
    action: str          # login / connect / alert
    src_ip: str
    dst_ip: str
    severity: str        # info / low / medium / high / critical
    raw: dict = field(default_factory=dict)

    def fingerprint(self) -> str:
        raw = f"{self.source}|{self.host}|{self.src_ip}|{self.ts[:19]}"
        return hashlib.sha256(raw.encode()).hexdigest()[:16]

def normalize(source: str, record: dict) -> SecEvent:
    """不同源映射到统一字段"""
    mappers = {
        "firewall": lambda r: dict(
            ts=r["time"], host=r["devname"], user="-", action=r["action"],
            src_ip=r["srcip"], dst_ip=r["dstip"], severity="info"),
        "auth": lambda r: dict(
            ts=r["timestamp"], host=r["hostname"], user=r["user"],
            action=r["event"], src_ip=r.get("ip", "-"), dst_ip="-",
            severity="medium" if r["event"] == "failed" else "info"),
    }
    fields = mappers[source](record)
    return SecEvent(source=source, raw=record, **fields)

统一 Schema 后,规则、存储、可视化、报表全部复用同一套字段,避免"每接一个源就重写一次逻辑"。

二、检测规则引擎:Sigma 风格

检测规则应数据驱动、可版本化、与代码分离。用 YAML 定义规则,Python 执行匹配。

代码语言:javascript
复制
# rules/brute_force.yml
title: 多次登录失败后成功
id: auth-brute-001
level: high
source: auth
condition:
  group_by: [user, src_ip]
  window: 300
  sequence:
    - match: {action: failed, count: ">=5"}
    - match: {action: success}

代码语言:javascript
复制
import yaml, time
from collections import defaultdict

class RuleEngine:
    def __init__(self, rule_path):
        with open(rule_path) as f:
            self.rule = yaml.safe_load(f)
        self.buckets = defaultdict(list)

    def feed(self, ev: SecEvent):
        if ev.source != self.rule["source"]:
            return None
        cond = self.rule["condition"]
        key = tuple(getattr(ev, k) for k in cond["group_by"])
        now = time.time()
        self.buckets[key].append((now, ev.action, ev))

        # 清理窗口外数据
        window = cond["window"]
        self.buckets[key] = [(t, a, e) for t, a, e in self.buckets[key]
                             if now - t <= window]

        seq = cond["sequence"]
        actions = [a for _, a, _ in self.buckets[key]]
        return self._match_sequence(seq, actions)

    def _match_sequence(self, seq, actions):
        """简化版:按顺序检查每步是否满足"""
        i = 0
        for step in seq:
            rule = step["match"]
            count = int(rule.get("count", ">=1").replace(">=", ""))
            hits = sum(1 for a in actions[i:] if a == rule["action"])
            if hits < count:
                return None
            i += hits
        return {"rule": self.rule["title"], "level": self.rule["level"]}

规则即配置,新增检测无需改代码,便于团队协作与审计。

三、告警降噪与关联

原始告警量巨大,必须聚合。核心思路:同实体、同时间窗、多规则命中 → 升级为事件。

代码语言:javascript
复制
class Correlator:
    def __init__(self, window=300, threshold=3):
        self.window = window
        self.threshold = threshold
        self.buf = defaultdict(list)

    def add(self, entity: str, alert: dict, ts: float = None):
        ts = ts or time.time()
        self.buf[entity].append((ts, alert))
        self.buf[entity] = [(t, a) for t, a in self.buf[entity]
                            if ts - t <= self.window]

    def incidents(self) -> list[dict]:
        out = []
        for entity, items in self.buf.items():
            if len(items) < self.threshold:
                continue
            levels = [a["level"] for _, a in items]
            level = ("critical" if "critical" in levels else
                     "high" if "high" in levels else "medium")
            out.append({"entity": entity, "count": len(items),
                        "level": level,
                        "rules": sorted({a["rule"] for _, a in items})})
        return out

降噪的本质是把"告警"变成"事件":分析师处理的是有上下文的事件,而非孤立的告警。

四、异常检测:统计基线

规则覆盖已知,基线捕捉未知。用滚动统计识别偏离。

代码语言:javascript
复制
import numpy as np
from collections import deque

class BaselineDetector:
    def __init__(self, window=100, z_threshold=3.5):
        self.history = deque(maxlen=window)
        self.z = z_threshold

    def update(self, value: float) -> float | None:
        """返回 z-score,超过阈值即异常"""
        if len(self.history) < 20:
            self.history.append(value)
            return None
        med = np.median(self.history)
        mad = np.median(np.abs(np.array(self.history) - med)) or 1e-9
        z = 0.6745 * (value - med) / mad
        self.history.append(value)
        return z if abs(z) > self.z else None

用 MAD 而非标准差,对尖刺不敏感,适合流量、登录次数这类波动大的指标。

五、威胁情报富化

告警需附带上下文才能判断。查询 IP 信誉并注入告警:

代码语言:javascript
复制
import httpx
from functools import lru_cache

@lru_cache(maxsize=4096)
def ip_reputation(ip: str) -> dict:
    # 示例:接入任意威胁情报API
    try:
        r = httpx.get(f"https://api.example.com/ip/{ip}", timeout=3)
        return r.json()
    except Exception:
        return {"score": 0, "tags": []}

def enrich(alert: dict) -> dict:
    ip = alert.get("src_ip")
    if ip:
        rep = ip_reputation(ip)
        alert["intel"] = rep
        if rep.get("score", 0) > 80:
            alert["level"] = "critical"
    return alert

富化让分析师的决策从"这个IP是谁"变成"这个IP是已知C2,立即隔离"。

六、响应编排(SOAR)

检测的终点是响应。高危动作必须走审批,低危可自动化。

代码语言:javascript
复制
class Playbook:
    def __init__(self, name, steps):
        self.name = name
        self.steps = steps       # [(action_name, fn, requires_approval)]

    def run(self, alert, auto=True):
        log = []
        for name, fn, need_approval in self.steps:
            if need_approval and not auto:
                log.append(f"[待审批] {name}")
                break
            try:
                result = fn(alert)
                log.append(f"[完成] {name}: {result}")
            except Exception as e:
                log.append(f"[失败] {name}: {e}")
                break
        return log

def block_ip(alert):
    # 实际调用防火墙API封禁
    return f"已封禁 {alert['src_ip']}"

def notify(alert):
    return "已通知值班"

playbook = Playbook("brute_force_response", [
    ("封禁源IP", block_ip, True),      # 需审批
    ("通知值班", notify, False),        # 自动
])

分级响应原则:只读动作自动执行,写动作与破坏性动作必须人工确认,避免误封导致业务中断。

七、工程护栏

  1. 数据脱敏:日志中的密码、Token、身份证入库前过滤。
  2. 完整性保护:日志本地加密 + 远程实时转发,防篡改。
  3. 误报治理:每条规则上线前用历史数据回放,评估误报率。
  4. 权限最小:采集与响应组件以降权运行。
  5. 可追溯:每次检测与响应记录输入、输出、操作人,支持复盘。
  6. 合规边界:监控范围符合法律与公司政策,员工知情同意。

结语

安全监控与分析的专业性,体现在Schema 的统一、规则的数据驱动、告警的关联降噪、检测的分层互补、响应的分级可控。规则覆盖已知,基线捕捉未知,情报提供上下文,编排沉淀动作。把这条链路跑通,SOC 才能从"告警消防队"升级为"主动防御体系"。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、日志采集与统一 Schema
  • 二、检测规则引擎:Sigma 风格
  • 三、告警降噪与关联
  • 四、异常检测:统计基线
  • 五、威胁情报富化
  • 六、响应编排(SOAR)
  • 七、工程护栏
  • 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档