libpcap在libvirt虚拟化环境下捕获数据包不完整的一种情况分析

在虚拟化环境下镜像流量交给suricata分析,遇到了文件还原不完整的问题,同环境下使用tcpdump抓包查看可以看到捕获的数据包存在大包被截断的情况。这里分析一下为什么tcpdump会出现数据包被截断的情况以及什么条件下会触发该情况,suricata的问题不完全一致,但是基本思路是一样的。

虚拟机操作系统:CentOS Linux release 7.5.1804
参考libpcap版本:
Date: Tue Nov 5 00:10:15 2019 -0800, 79817f

数据包截断

tcpdump捕获的文件查看如图,可以看到捕获到的数据包不完整。

tcpdump捕获文件

截断发生条件

因为所处虚拟化环境,外部转发进大数据包的情况比较多样,暂时不考虑外部,仅关注转发进大数据包后本地捕获被截断的情况,这里可以用http下载一个较大文件模拟。

  1. tcpdump参数中指定特定网卡,比如。这里如果指定网卡为any则不会发生截断。
    sudo tcpdump -i eth0 -nn tcp port 9090 -w longin.pcap
  2. 网卡参数中gro、lro、tso、gso等各种offload相关配置均为off状态。suricata在启动时会主动设置相关配置到off。
[huyu@bogon ~]$ ethtool -k eth0 | grep offload
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: off
large-receive-offload: off [fixed]
rx-vlan-offload: off [fixed]
tx-vlan-offload: off [fixed]
l2-fwd-offload: off [fixed]
hw-tc-offload: off [fixed]
rx-udp_tunnel-port-offload: off [fixed]

截断原因

在截断发生条件的判断中已经发现tcpdump中指定网卡与设定为any时表现不同,对比两种参数运行时strace记录的系统调用区别,发现一个系统调用的参数有明显区别。

setsockopt(3, SOL_PACKET, PACKET_RX_RING, {block_size=4096, block_nr=1310, frame_size=1600, frame_nr=2620}, 16) = 0

这里与libpcap捕获数据包的方式有关,其使用AF_PACKET捕获数据包,并使用mmap映射一个环形缓冲区用于保存内核拷贝给它的数据包,参考PACKET_MMAP。
环形缓冲区的参数中需要设置每个数据包的最大尺寸,也就是frame_size,如果设置的尺寸小于数据包实际尺寸,那么内核在拷贝数据包时只能做截断处理。

libpcap中该设置代码位于pcap-linux.c4139行函数create_ring中,在选择frame_size大小的代码中注释也说明了其选择逻辑。

libvirt虚拟化环境下,虚拟机对应的tap设备如果没有关闭gso和tso,虚拟机网卡就会收到大包,这里涉及到linux虚拟网络设备的实现,目前暂不分析。

处理方式

截断发生的条件和原因已经找到,避免截断的方式也就很多样了。需要说一下是,suricata文档中明确说明需要关闭网卡的各种offload特性,是为了避免收到大数据包,因为大数据包会影响其对dsize的判断

展开阅读全文

页面更新:2024-01-27

标签:情况   环境   包被   缓冲区   网卡   虚拟机   尺寸   参数   发生   文件

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top