1
patrickyoung 196 天前 via Android
tshark 或者 zed datalake
|
2
patrickyoung 196 天前 via Android
还有 packetbeat
|
3
ChristopherY OP @patrickyoung 最主要的还是想 Python 自己写函数去分析某个 pcap 文件,比如根据 src 、dst 、协议类型、mpdu id 或者 length 来筛选,然后进一步分析 pcap 文件。tshark 读取速度好像也一般,有没有最佳实践
|
4
Rehtt 196 天前 via Android
有没有可能因为解析的字段比较少所以速度就快
|
5
keakon 196 天前
不要用 Python 干这种事啊,换成 C 、Go 之类的去做,轻松快几个数量级。
|
6
ChristopherY OP @keakon 确实,想追求速度还得是 c 或 go
|
7
ChristopherY OP @Rehtt 是这样的,所以追求速度还是得用别的语言了
|
8
qazwsxkevin 196 天前
不知道要研究这份东西多久,如果经常发生,周期长,复盘次数多,不如写个脚本导入 mysql 吧,
记得以前看文档,pcap 有工具可以转 json ,然后想办法再进 mysql 试试, 在数据库表里里 fliter 东西,出结果范围快得不要不要的... 要不就如 5 楼所说,c++撸一个 |
9
QuinceyWu 196 天前
我最近也在做类似的事情:使用 scapy 实时解析 udp 的报文,udp 报文会分片,所以我起了一个线程和队列去做接收和解析的逻辑
|
10
lysShub 196 天前
解析出来的字段是啥意思? pcap 里面存的不就是原始的 eth 数据包吗,好像还附带有 ts ,if 几个信息
|
11
ChristopherY OP @lysShub 就是根据帧的格式,把原始数据解析成对应的字段信息。
|
12
ChristopherY OP @qazwsxkevin 我也见过用数据库先建索引的,这种貌似是反复读取最好的方法了。不过对于 wifi7 这种协议,可能需要自己手动写解析函数了?
|
13
leonshaw 196 天前 via Android
自己写,只处理需要的协议和字段。wifi7 是物理层,跟抓包没关系。
|
14
kuanat 196 天前 via Android
https://github.com/google/gopacket
我之前在 go 经验的帖子里写过,这个库配合一些手动内存管理的技巧,在 10Gbps 网络上做实时处理没什么问题。 如果是 pcap 离线文件,直接按照示例写就好了。 |
15
kuanat 196 天前
还有楼上说得不对,网络包是一层一层嵌套的,必须从外向内解析。
当然理论上可以通过某层协议的标志从二进制的某个偏移开始解析,无视下层协议,但是这样做会损失很多信息,也不保证解析结果正确,与最初的目的不符。 gopacket 这个库是可以自己写未知协议扩展的,比如原版里面没有 pppoe/ppp 的支持,我在自己的项目里加上了,可能也就二三十行代码。就是写清楚字节流多少偏移对应该协议的某个字段。如果是那种非定长编码的格式,需要先解析头部的长度信息,再解析对应的字段。 |
16
lysShub 196 天前
@ChristopherY 只要不解应用层的,还是挺简单的,go 可以用 gvisor.dev/gvisor/pkg/tcpip/header
|
17
chengzishuai1 196 天前
gopacket 呢?
|
18
ChristopherY OP @kuanat 如果用 go 可以的话,那用 c 经典的库 libpcap 是不是也可以的,这方面有没有造好的轮子
|
19
ChristopherY OP @chengzishuai1 go 的库之前倒没试过,主要是用 c 和 Python 。看起来用 go 比较方便
|
20
xgdgsc 195 天前 via Android
cpp 或者 julia
|
21
levelworm 195 天前
@ChristopherY 很好奇 parsing 的瓶颈在哪里?如果从钻研技术角度来说(也就是不用外界的 library ),能不能用 C 来解决这部分瓶颈,然后和 Python 联动?
|
22
ChristopherY OP @levelworm 核心点在于把 pcap 文件的 raw data 根据不同层的协议解析成对应的字段信息。用 Python 现有的库都比较慢(可能是没找到合适的库)。所以确实最佳实践应该是用 c 的 libpcap 库来解析,然后再用 python 自定义函数进一步处理想要统计的信息吧。
|
23
kuanat 195 天前
@ChristopherY #18
用什么都可以,取决于你哪种语言比较熟练。C 版本的 libpcap 我没用过,考虑到是 tcpdump 在维护的,肯定是没问题的。Go 版本虽然两年没更新了,但协议这个东西又不会变…… 另外我觉得你其实考虑复杂了,gopacket/libpcap 都是强在抓包,至于你是不是用它做解析不关键,用它做解析的原因就是它们把协议相关的数据结构都定义好了。 换个表达方式,你现在以字节形式读取到某个包(忽略到 pcap 文件格式解析),它一定是代表着某个多层嵌套的数据结构: [ L1_Header : L1_Payload [ L2_Header : L2_Payload [ L3_Header : L3_Payload [ ... ] ] ] 然后假设 L1 是来自三层的,然后有 IP/ICMP/IGMP 几种协议,就拿 IP/ICMP/IGMP 的数据结构去套上面的字节流,匹配到就可以拆包了,L1_Payload 就是 [] 里面 L2/L3... 的内容,继续下一层解析就是了。 像 dpkt 这种数据不足,肯定是各种协议 Header 的数据结构定义不完善。scapy 我用过但是印象不深了,我估计慢的主要原因是它没法做到像 C/Go 这样可以手动分配内存,然后 one pass 把多层结构一次解析出来。但是 scapy 大概每次都要遍历匹配所有协议,来判断下一层是什么。 这个解析过程本质上和按照某个特定格式读取二进制文件没什么区别。 提高解析效率除了解析单个包层面的优化,主要是靠多线程。特别是实时抓包实时处理,靠内核 AF_PACKET 机制扇出,分配个多个线程来解析。如果是单线程肯定会非常慢。 |
24
daxin945 195 天前
要是我的话 肯定图方便直接上 suricata 然后解 json 日志了
|
25
wsseo 195 天前
github 上,gopacket/gopacket 在维护,是 fork 谷歌的 gopacket
|
27
kuanat 194 天前 via Android
https://github.com/google/gopacket
我之前在 go 经验的帖子里写过,这个库配合一些手动内存管理的技巧,在 10Gbps 网络上做实时处理没什么问题。 如果是 pcap 离线文件,直接按照示例写就好了。 |
28
kuanat 194 天前 via Android
@playboy0 #26
老 E5 单核 2G ,单个核心处理能力最高 100k pps 左右,包含业务逻辑。单纯解析时间中位数在 20us 左右。 由于整个内核 AF_PACKET 扇出数量和并发线程数是一致的,加上解析过程是 zerocopy ,几乎不会触发 gc ,内存占用没有印象了,应该非常稳定。 |
30
kuanat 193 天前
@playboy0 #29
流量来源是分光设备,旁路直接进服务器的光口网卡。什么都不用配置,网卡开启 promiscuous 混杂模式抓包就行了。端口镜像应该一样的道理。 这个项目是挺久之前的了,某集团安全审计相关,要做全协议流量分析。内部接入比较复杂,有类似 PPPOE/PPP 之类的认证,VLAN 既有二层也有三层。所以直接从出口分光出来做的。 这个事情本身不是我负责的,我就是去救火的。因为这个事情后来又做了针对某些协议的 DPI ,这玩意后来对外好像卖了接近一千万…… 原本有个 DPDK 的方案,是很早之前从别的地方采购的,没人能维护。配套服务器是双路 E5 ,核心倒是多,只是频率很低,系统又是 CentOS 7 。基本上就是抱着死马当活马医的想法,姑且用 Go 一试。 系统太老了不想维护,所以 PF_RING 指望不上,就拿 AF_PACKET 替代了,实际测试下来没啥问题。这个做到后面发现 AF_PACKET/MMAP 其实和 PF_RING 原理几乎一样的。如果现在做的话,可能都是用 AF_XDP 了,性能估计还能翻番。 当时还用的是 google/gopacket 而不是后来有人维护的 gopacket/gopacket 。不过影响不大,整个库的基础功能很完善了,除了当时没有的几个协议做了一下解析实现。 技术上这个只要懂原理的话没什么难度,内核里用 BPF 去抓包,MMAP 内存在内核和应用之间共享,AF_PACKET 设定好扇出,把网卡的数据写入 MMAP 的内存,用户空间的应用通过 ZeroCopy 方式读就可以了。核心部分代码可能没有一百行。 |