零長度出口數據包的 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
因此,對於所有Len為零的****傳出TCP 數據包,校驗和總是錯誤的。對於出口流量拓撲中的所有主機都是如此。對於傳入的流量,沒有這樣的問題。這是因為,正如我所檢查的(通過使用 tcpdump 定期通過主機介面而不是通過 NFLOG 進行擷取),當出口流量離開主機介面時,校驗和已經被糾正。
發送方 (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 校驗和是錯誤的。可能是什麼原因?
感謝您的關注!
我找到了解決問題的方法。可以使用 iptables NFQUEUE 代替 NFLOG。除了解決 TCP 校驗和的問題外,這種方法的優點還在於擷取的數據包沒有“Linux Netfilter NFLOG” Link-Layer 標頭,即生成的 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
我一直在尋找解決這個問題的方法很長時間:Tc qdisc delay not seen in tcpdump recording。首先,解決方案在我看來相當不錯:沒有使轉儲文件變小的 Link-Layer 標頭,TCP 校驗和問題得到解決。但事實證明,對於大發送速率(當拓撲的 veth-pair 鏈路上沒有安裝網路速率/延遲時為 3Gbps)只有一半的流量被記錄。也就是說,如果我在發送方擷取數據包的介面處記錄入口和出口流量,我會得到例如 1.7 GB 的轉儲,而如果我記錄從核心的 iptables 擷取的流量,則轉儲約為 900 兆字節。NFLOG 和 NFQUEUE 解決方案都會出現發送速率受限的問題。