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
解析結果
最終運行結果如下圖所示: