NetFlow是思科设备上做流量分析的标准技术,华为上叫NetStream,原理都一样:设备对经过的每个流(由源IP、目的IP、协议号、源端口、目的端口、入接口这六个字段定义一条流)做统计,记录包数和字节数,然后导出给分析器。
日常运维中NetFlow最大的用途就是回答"谁在占带宽"这个问题。出口带宽跑满了,想知道是哪个IP、在用什么协议、连到哪里,靠接口流量计数器是看不出来的,得看NetFlow数据。
设备上开启NetFlow导出之后(配置这里不展开,不同厂商命令不一样),数据会以UDP包的形式发到指定的采集器。采集器可以是商业软件(比如SolarWinds NTFA),也可以自己写。
Python读取NetFlow数据最简单的方式是直接解析设备导出的原始UDP包。有一个现成的库:
pip install netflow
不过更实用的做法是让设备把NetFlow数据导出为文本格式,或者用nfdump工具先把原始数据转成可读文本,再用Python分析。nfdump是开源的NetFlow分析工具,安装后在命令行用nfdump读取NetFlow文件:
nfdump -r nfcapd.202505141000 -o csv > flow.csv
转成CSV之后,Python分析就自由了:
importpandasaspd
fromcollectionsimportCounter
defanalyze_netflow(csv_file, top_n=20):
"""分析NetFlow导出的CSV,找出流量最大的IP和端口"""
# nfdump导出的列名可能因版本而异,先看一眼
df = pd.read_csv(csv_file)
# 如果列名不规范,重命名
if'ts'indf.columns:
df.columns = ['start', 'duration', 'proto', 'src_ip', 'src_port',
'dst_ip', 'dst_port', 'packets', 'bytes', 'flows']
print(f"总流量:{df['bytes'].sum()/1024/1024/1024:.2f} GB")
print(f"总流数:{len(df)}")
# 按源IP统计流量
print(f"\n流量最大的源IP(Top {top_n}):")
src_traffic = df.groupby('src_ip')['bytes'].sum().sort_values(ascending=False)
forip, bytes_totalinsrc_traffic.head(top_n).items():
print(f" {ip:<18} {bytes_total/1024/1024:.1f} MB")
# 按目的端口统计(看哪个端口流量最大)
print(f"\n流量最大的目的端口(Top 10):")
port_traffic = df.groupby('dst_port')['bytes'].sum().sort_values(ascending=False)
forport, bytes_totalinport_traffic.head(10).items():
print(f" 端口 {port:<8} {bytes_total/1024/1024:.1f} MB")
# 按协议统计
print(f"\n协议分布:")
proto_traffic = df.groupby('proto')['bytes'].sum().sort_values(ascending=False)
forproto, bytes_totalinproto_traffic.head(10).items():
print(f" {proto:<8} {bytes_total/1024/1024:.1f} MB")
if__name__ == "__main__":
analyze_netflow("flow.csv")
运行效果大概是这样:
总流量:128.45 GB
总流数:987654
流量最大的源IP(Top 20):
192.168.1.100 45230.2 MB
192.168.1.200 8912.5 MB
10.0.0.5 3456.1 MB
流量最大的目的端口(Top 10):
端口 443 67890.3 MB
端口 80 23456.7 MB
端口 3306 5678.2 MB
协议分布:
TCP 120000.5 MB
UDP 8234.1 MB
看到这种结果,一眼就能判断问题在哪里。比如192.168.1.100这一个IP就占了45GB流量,目的端口是443和3306,大概率是在做数据库同步或者下载大文件。接着去那台机器上确认就行。
没有NetFlow的环境也有替代方案。在出口交换机做端口镜像,接一台Linux跑nfdump的nfcapd守护进程采集,效果一样。或者用软流量的方式:在Linux路由器上跑softflowd,把NetFlow数据导出到分析器。
如果设备不支持NetFlow(比如一些低端交换机),还有一种笨办法但确实管用:用Python的pyshark在镜像口抓包10分钟,然后统计源IP和字节数。虽然没有NetFlow精确,但应急够用了。