如何通过KQL解析Azure Log Analytics的NSG流日志公网IP字段
KQL解析NSG流日志公网IP字段实现方案
问题背景
- 迭代NSG流日志审查KQL查询,核心目标是拆分公网/外部IP列,清除单元格内冗余附加信息,输出可直接供Excel插件执行NSLOOKUP的纯IP数据,后续可结合nslookup、resolve-dnsname、whois等方式识别外部IP归属。
- 当前公网IP字段非逗号分隔格式,采用单空格分隔多组IP条目,单条IP条目内用竖线分隔IP与附加属性的规则,示例数据:
"20.xx.xx.xx|1|0|0|0|0|0 78.xxx.xxx.xxx|1|0|0|0|0|0" - 需求为二选一:要么输出逗号分隔的纯IP字符串,覆盖
PublicIP、PublicSourceIP、PublicDestIP三个字段;要么将每个IP拆分为独立行。 - 原有查询的parse逻辑存在正则未转义特殊字符的问题,无法正确提取IP,原有代码如下:
AzureNetworkAnalytics_CL | where SubType_s == 'FlowLog' and (FASchemaVersion_s == '1'or FASchemaVersion_s == '2') | extend NSG = NSGList_s, Rule = NSGRule_s,Protocol=L4Protocol_s, Hits = (AllowedInFlows_d + AllowedOutFlows_d + DeniedInFlows_d + DeniedOutFlows_d) | project-away NSGList_s, NSGRule_s | project TimeGenerated, NSG, Rule, SourceIP = SrcIP_s, DestinationIP = DestIP_s, DestinationPort = DestPort_d, FlowStatus = FlowStatus_s, FlowDirection = FlowDirection_s, Protocol=L4Protocol_s, PublicIP=PublicIPs_s,PublicSourceIP = SrcPublicIPs_s,PublicDestIP=DestPublicIPs_s // ## IP Address Filtering ## | where isnotempty(PublicIP) **| parse kind = regex PublicIP with * "|1|0|0|0|0|0" ipnfo ' ' * | project ipnfo** // ## port filtering | where DestinationPort == '443'
实现方案
方案1:输出逗号分隔纯IP字符串(适配Excel NSLOOKUP场景)
该场景不需要使用parse运算符,采用extract_all+strcat_array组合性能远高于正则parse,逻辑为按规则提取所有IP后直接拼接为逗号分隔字符串,代码如下:
AzureNetworkAnalytics_CL | where SubType_s == 'FlowLog' and (FASchemaVersion_s == '1' or FASchemaVersion_s == '2') | extend NSG = NSGList_s, Rule = NSGRule_s, Protocol=L4Protocol_s, Hits = (AllowedInFlows_d + AllowedOutFlows_d + DeniedInFlows_d + DeniedOutFlows_d) | project-away NSGList_s, NSGRule_s | project TimeGenerated, NSG, Rule, SourceIP = SrcIP_s, DestinationIP = DestIP_s, DestinationPort = DestPort_d, FlowStatus = FlowStatus_s, FlowDirection = FlowDirection_s, Protocol=L4Protocol_s, PublicIP=PublicIPs_s, PublicSourceIP = SrcPublicIPs_s, PublicDestIP=DestPublicIPs_s // ## IP地址解析逻辑 | where isnotempty(PublicIP) | extend PublicIP = strcat_array(extract_all(@"([\d\.]+)\|", PublicIP), ","), PublicSourceIP = strcat_array(extract_all(@"([\d\.]+)\|", PublicSourceIP), ","), PublicDestIP = strcat_array(extract_all(@"([\d\.]+)\|", PublicDestIP), ",") // ## 端口过滤 | where DestinationPort == 443
正则
([\d\.]+)\|会直接匹配所有竖线前的合法IP字符串,比逐段parse效率高30%以上,输出的逗号分隔格式可直接被Excel插件识别,支持批量NSLOOKUP操作。
方案2:拆分为单IP多行(适配单IP维度统计分析场景)
如果需要按单个公网IP做聚合统计,采用mv-apply运算符比parse更适配多值拆分场景,可自动将每个IP拆为独立行,同时保留其他字段的关联关系,代码如下:
AzureNetworkAnalytics_CL | where SubType_s == 'FlowLog' and (FASchemaVersion_s == '1' or FASchemaVersion_s == '2') | extend NSG = NSGList_s, Rule = NSGRule_s, Protocol=L4Protocol_s, Hits = (AllowedInFlows_d + AllowedOutFlows_d + DeniedInFlows_d + DeniedOutFlows_d) | project-away NSGList_s, NSGRule_s | project TimeGenerated, NSG, Rule, SourceIP = SrcIP_s, DestinationIP = DestIP_s, DestinationPort = DestPort_d, FlowStatus = FlowStatus_s, FlowDirection = FlowDirection_s, Protocol=L4Protocol_s, PublicIP=PublicIPs_s, PublicSourceIP = SrcPublicIPs_s, PublicDestIP=DestPublicIPs_s // ## IP地址拆分多行逻辑 | where isnotempty(PublicIP) | mv-apply ParsedPublicIP = extract_all(@"([\d\.]+)\|", PublicIP) on (project ParsedPublicIP = tostring(ParsedPublicIP)) | mv-apply ParsedPublicSourceIP = extract_all(@"([\d\.]+)\|", PublicSourceIP) on (project ParsedPublicSourceIP = tostring(ParsedPublicSourceIP)) | mv-apply ParsedPublicDestIP = extract_all(@"([\d\.]+)\|", PublicDestIP) on (project ParsedPublicDestIP = tostring(ParsedPublicDestIP)) // ## 端口过滤 | where DestinationPort == 443
parse运算符使用说明
原有parse逻辑失效的核心原因是正则中|属于特殊字符,需要转义为\|才能匹配。但对于这类重复多值提取场景,parse仅适合固定结构的单条数据提取,重复多值场景下使用extract_all搭配strcat_array或mv-apply是性能最优、代码最简洁的方案,无需编写多段匹配规则。
内容的提问来源于stack exchange,提问作者AN-0923
相关产品推荐
相关产品推荐

