零长度出口数据包的 TCP 校验和错误(使用 iptables 捕获)

零长度出口数据包的 TCP 校验和错误(使用 iptables 捕获)

我在主机之间发送 TCP 数据(拓扑是使用网络命名空间和 veth 对创建的)。对于主机,我使用 NFLOG 和 tcpdump 将其入口和出口数据包保存到 pcap 文件,并在主机上执行以下命令:

# we turn off checksum offload:
sudo ethtool -K veth0 tx off sg off tso off ufo off

# we log packets with nflog:
sudo iptables -A OUTPUT -j NFLOG --nflog-group 17
sudo iptables -A INPUT  -j NFLOG --nflog-group 17

# we write the packets:
sudo tcpdump -i nflog:17 -w mypcap.pcap

所以对于所有的外向的TCP 数据包Len 的校验和总是错误的。对于拓扑中的所有主机都是如此出口交通。对于传入流量则不存在这样的问题。这是因为,正如我所检查的(通过在主机接口上而不是通过 NFLOG 定期使用 tcpdump 进行捕获),当出口流量离开主机接口时,校验和已经被纠正。

发送方 (11.0.0.5) 处的 Pcap,使用 NLOG 捕获:

在此输入图像描述

发送方的 Pcap(11.0.0.5),在发送方接口定期捕获:

在此输入图像描述

接收器 (11.0.0.1) 处的 Pcap,使用 NLOG 捕获:

在此输入图像描述

接收器 (11.0.0.1) 处的 Pcap,在接收器接口上定期捕获:

在此输入图像描述

因此,如上图所示,对于从 iptables NFLOG 捕获的 pcap,对于所有 Len 等于 0 的出口 TCP pcaket,TCP 校验和是错误的。可能是什么原因?

感谢您的关注!

答案1

我已经找到了问题的解决方案。可以使用 iptables NFQUEUE 代替 NFLOG。除了解决 TCP 校验和问题外,此方法的优点还在于捕获的数据包没有“Linux Netfilter NFLOG”链路层标头,即生成的 pcap 文件中的数据包只是原始 ip 数据包。

sudo iptables -A INPUT  -p tcp -s $receiver-ip -d $sender-ip   -j NFQUEUE --queue-num 17
sudo iptables -A OUTPUT -p tcp -s $sender-ip   -d $receiver-ip -j NFQUEUE --queue-num 17
sudo iptables -A INPUT  -p udp -s $receiver-ip -d $sender-ip   -j NFQUEUE --queue-num 17
sudo iptables -A OUTPUT -p udp -s $sender-ip   -d $receiver-ip -j NFQUEUE --queue-num 17

sudo tcpdump -i nfqueue:17 -w mypcap.pcap

为了解决这个问题,我花了很长时间寻找解决方案:tcpdump 记录中未看到 Tc qdisc 延迟。首先,该解决方案对我来说看起来相当不错:没有链路层标头,这使得转储文件更小,TCP 校验和问题得到解决。但事实证明,在高发送速率(当拓扑的 veth 对链路上未安装网络速率/延迟时为 3Gbps)时,仅记录一半的流量。也就是说,如果我记录在接口捕获数据包的发送方的入口和出口流量,我会得到 1.7 GB 的转储,而如果我记录从内核 iptables 捕获的流量,转储大约为 900 MB。 NFLOG 和 NFQUEUE 解决方案都会出现发送速率受到限制的问题。

相关内容