可视化Elasticsearch中网络发现文档周度变更的最优方案
网络发现扫描差异分析最优实现方案
一、索引结构调整建议
在现有字段基础上做少量优化即可满足需求,不需要大规模改动原有结构:
- 保留原有
run_id字段,固定生成规则为扫描当日的yyyyMMdd格式,确保同一次周度扫描的所有文档共享同一个run_id,方便按批次过滤 - 新增
last_seen日期类型字段,和原有datetime值对应,显式声明为date类型优化聚合查询性能 - 可选优化:如果单周扫描IP量超过10万,建议按周做分片索引,比如命名为
device_discovery-2024w25(w后面跟当年周数),跨周对比的时候直接查两个索引即可,性能远高于单索引按条件过滤
注意:确保
ip_addr、run_id、dns等需要精确匹配/聚合的字段有keyword类型子字段,避免text类型分词导致查询结果异常。
二、核心需求实现逻辑
1. 新增存活IP识别
直接用Elasticsearch原生聚合即可实现,不需要拉取全量数据到本地计算:
{ "size": 0, "query": { "bool": { "filter": [ {"terms": {"run_id.keyword": ["上周扫描run_id", "本周扫描run_id"]}} ] } }, "aggs": { "all_ips": { "terms": {"field": "ip_addr.keyword", "size": 10000}, // size调整为大于你的总IP数即可 "aggs": { "scan_count": {"cardinality": {"field": "run_id.keyword"}}, "new_ip_filter": { "bucket_selector": { "buckets_path": {"count": "scan_count"}, "script": "params.count == 1 && doc['run_id.keyword'].value == '本周扫描run_id'" } } } } } }
返回的all_ips聚合桶中的IP就是本周新增的存活IP。
2. 同一IP属性变更检测
两种方案按需选择:
- 优先选方案(写入时预计算,查询性能高):写入本周扫描数据时,先查询该IP上周扫描的属性值,本地比对后给本次文档新增两个字段:
ip_status:keyword类型,可选值为new/changed/unchangedchanged_fields:数组类型,存储变更的字段名和新旧值,示例:["dns:old.domain.com->new.domain.com", "segmento_name:Testing->Production"]
后续查询变更IP直接过滤ip_status: changed即可,无需额外计算。
- 轻量方案(无需修改写入逻辑):用
top_hits聚合取每个IP两次扫描的明细数据,在可视化层做比对:
{ "size": 0, "query": {"terms": {"run_id.keyword": ["上周run_id", "本周run_id"]}}, "aggs": { "ips": { "terms": {"field": "ip_addr.keyword", "size": 10000}, "aggs": { "scan_details": { "top_hits": { "size": 2, "sort": [{"datetime": "desc"}], "_source": ["dns", "segmento_name", "source_server", "red_addr_cidr"] // 填入需要比对的属性字段 } } } } } }
拿到每个IP的两次扫描结果后,直接做字段值比对即可得到变更内容。
三、可视化实现
如果使用Kibana做可视化,直接配置两个仪表板面板即可:
- 新增IP面板:用新增IP聚合结果做数据表,展示新增IP、所属网段、扫描时间、关联DNS等信息
- 变更IP面板:如果用预计算方案,直接过滤
ip_status: changed的文档做表格,展示IP、变更字段、新旧值;如果用轻量方案,可以导出聚合结果做CSV比对,或者用自定义可视化组件做字段差异高亮。
内容的提问来源于stack exchange,提问作者MauJFernandez
相关产品推荐
相关产品推荐

