python解析netflow数据到csv
本文主要讲解了linux下通过tcpdump抓取netflow数据包,并将其导入到wireshark进行解析,然后通过wireshark导出数据为json文件,再通过python脚本将其解析为csv文件以便做数据分析。
使用linux自带的tcpdump抓包
在linux的shell下使用tcpdump包抓取指定端口下的数据包,netflow流量的端口默认为9996端口。
tcpdump udp port 9996 -w netflow_data.cap
在shell打上该命令linux便会开始抓包,按
Ctrl+C
则会停止抓取并将数据写入netflow_data.cap
文件,由于netflow的数据量特别大,所以如果没有过滤出指定ip的netflow流量,建议不要取太长时间(毫不夸张的说,一个大型企业的netflow流量10分钟的netflow数据往往可以使这个文件达到好几个G,解析成json文件后甚至达到几十G,这已经远远超出了一般程序可以解析处理的范围)。可以先使用
tcpdump udp port 9996 | grep xxx.xxx.xxx.xxx
测试检查是否可以获取对应的数据,如果长时间没有响应,这表明数据数据包可能没有到达本端,需要检查设备配置或者防火墙策略。
在linux下使用该命令可以查看对应端口下的数据包,通过grep
可以过滤出自己的想要查看的ip
将抓好的包导入wireshark
抓取下来的包直接用wireshark打开(windows版和Mac版都可以)。如下图所示:
如下图所示,随便点击一个数据包
将数据导出为json文件
在wireshark中导出数据到json文件,以便于我们使用python对数据进行解析。
解析数据到csv
将导出好的json文件上传到安装了python环境的终端上(例如Linux或Mac),与如下脚本(脚本名称netflow_to_csv.py
)放置在同一目录下
# _*_ coding: utf-8 _*_
import json
data_file = './data.json' # wireshark导出数据
output_file = './netflow.csv' # 解析后文件名
with open(data_file, 'r') as f:
data_list = json.loads(f.read())
def get_the_flow_list(data_item):
'''
["Flow 1": {
"cflow.srcaddr": "xxx.xxx.xxx.xxx",
"cflow.dstaddr": "xxx.xxx.xxx.xxx",
"cflow.protocol": "2",
"cflow.srcport": "0",
"cflow.dstport": "17",
"cflow.inputint": "5",
"cflow.outputint": "0",
"cflow.octets": "36",
"cflow.packets": "1"
},
"Flow 2": {
"cflow.srcaddr": "xxx.xxx.xxx.xxx",
"cflow.dstaddr": "xxx.xxx.xxx.xxx",
"cflow.protocol": "2",
"cflow.srcport": "0",
"cflow.dstport": "17",
"cflow.inputint": "5",
"cflow.outputint": "0",
"cflow.octets": "36",
"cflow.packets": "1"
}
]
'''
cflow = data_item.get('_source').get('layers').get('cflow')
flowSet_k = [k for k,v in cflow.items() if 'FlowSet' in k][0]
flow_data_list = []
# flow_list = [{f:v} for f,v in cflow.get(flowSet_k).items() if 'Flow ' in f]
for k,v in cflow.get(flowSet_k).items():
if 'Flow ' not in k:
continue
srcaddr = v.get("cflow.srcaddr")
dstaddr = v.get("cflow.dstaddr")
protocol = v.get("cflow.protocol")
srcport = v.get("cflow.srcport")
dstport = v.get("cflow.dstport")
inputint = v.get("cflow.inputint")
outputint = v.get("cflow.outputint")
octets = v.get("cflow.octets")
packets = v.get("cflow.packets")
flow_data_list.append((k, srcaddr, dstaddr, protocol, srcport, dstport, inputint, outputint, octets, packets))
return flow_data_list
def domain():
with open(output_file, 'w') as f:
title = 'No,Flow_id,srcaddr,dstaddr,protocol,srcport,dstport,inputint,outputint,octets,packets\n'
f.write(title)
i = 0
for data_item in data_list:
i = i + 1
try:
flow_list = get_the_flow_list(data_item)
for flow_item in flow_list:
line = '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n' % (i, flow_item[0], flow_item[1], flow_item[2], flow_item[3], flow_item[4], flow_item[5], flow_item[6], flow_item[7], flow_item[8], flow_item[9])
f.write(line)
except Exception as e:
print 'template'
print e
continue
if __name__ == '__main__':
domain()
运行解析脚本
在shell下运行如下命令即可。
python netflow_to_csv.py
解析结果
最终运行结果如下图所示: