为什么 tcpdump 可以看到 TAP 接口上的传入数据包,而 iptables 看不到?

Gil*_*il' 7 linux networking iptables tap tunneling

程序在 Linux TAP接口上注入数据包(这些数据包来自虚拟机)。具体来说,这些是 DHCP 请求(所以它们是 UDP)。我可以看到带有tcpdump但不带有的数据包iptables,并且它们也无法到达本地 DHCP 服务器。为什么不呢,我该如何解决?

更新:我尝试注入指向tap0接口地址的 IP 数据包。我在 中看到来自 VM 的 ARP 请求tcpdump -i tap0,但网络层没有回复。如果我向 VM 发送 ARP 请求,它会看到它们并回复主机(并且回复会显示tcpdump但会丢失)。

另一个观察结果:ifconfig tap0表明对于注入主机的每个数据包,TX 丢弃的数据包计数增加。为什么是TX?

# ifconfig tap0
…
          TX packets:0 errors:0 dropped:958 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
Run Code Online (Sandbox Code Playgroud)

长话短说:在 Linux 主机(运行 Ubuntu 10.04)上,我正在运行一个虚拟机,其中包括模拟以太网卡。它通过与负责将以太网数据包注入和捕获到主机网络堆栈的帮助程序进行通信来实现。虚拟机为ARM芯片模拟器,调用helper程序nicserver;我所知道的只是ARM 文档中的内容

我想在 VM 和主机之间建立以太网链接,在此之上我想要一个 IP 链接。VM 通过 DHCP 获取其 IP 地址。我不希望VM和世界其他地区,仅与主机之间的任何通信,所以我创建了一个虚拟网络接口tap0

tunctl -u gilles
ifconfig tap0 192.168.56.1 netmask 255.255.255.0 up
nicserver -p 7801 -a tap0 &
Run Code Online (Sandbox Code Playgroud)

现在我启动虚拟机,我可以看到它正在发送 DHCP 请求tcpdump -n -i tap0 -vv(DHCP 客户端没有超时,我只是在此处显示一个示例请求):

tcpdump: listening on tap0, link-type EN10MB (Ethernet), capture size 96 bytes
18:29:23.941574 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 576)
    0.0.0.0.68 > 255.255.255.255.67: [no cksum] BOOTP/DHCP, Request from 02:52:56:47:50:03, length 548, xid 0x238a7979, secs 46, Flags [none] (0x0000)
          Client-Ethernet-Address 02:52:56:47:50:03 [|bootp]
Run Code Online (Sandbox Code Playgroud)

我已经在主机上设置了 Dnsmasq 来处理请求,但是它没有看到任何传入的请求。Dnsmasq 服务器甚至看不到传入的请求(我跟踪它)。所以我尝试用 Iptables 观察数据包。(显示所有过滤器/输入规则;没有 mangle 或 nat 规则)。

Chain INPUT (policy ACCEPT 2366K packets, 5334M bytes)
 pkts bytes target     prot opt in     out     source               destination 
  119 39176 LOG        udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 LOG flags 4 level 4 prefix `[DHCP request] '
  119 39176 DROP       udp  --  eth1   *       0.0.0.0/0            0.0.0.0/0           udp dpt:67
    2   490 LOG        udp  --  tap0   *       0.0.0.0/0            0.0.0.0/0           LOG flags 4 level 4 prefix `[in=tap0] '
   26  6370 ACCEPT     udp  --  tap0   *       0.0.0.0/0            0.0.0.0/0   
    0     0 ACCEPT     all  --  tap0   *       0.0.0.0/0            0.0.0.0/0   
 3864  457K ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0   
Run Code Online (Sandbox Code Playgroud)

所有这些传入的 DHCP 请求都处于开启状态eth1(我很小心不要忽略这些,以免激怒我的同事和我的网络管理员)。这些 UDP 数据包tap0来自本地 Samba 服务器。我用 tcpdump 看到的 DHCP 请求数据包似乎没有通过数据包过滤器!

为什么我看到传入广播包tap0tcpdump,但不是iptables(也一起听机器上的程序)?我需要修复什么才能看到这些数据包,就像它们来自以太网接口一样?

wnr*_*rph 1

这是进一步的猜测。希望这对您有所帮助,但也可能是错误的。

tap0 有两端,内核网络栈端和程序接口端。在我看来,如果您使用 Tap0 提供“nicserver”,它不会使用程序接口按照 Tap 设备的预期方式连接到它。相反,nicserver 只会从网络堆栈端写入,并且没有应用程序从程序接口端读取,最终将导致设备队列溢出。这解释了丢弃的数据包。此外,不会传送任何数据包,这可以解释 iptables 结果。

我想如果你让 tcpdump 在 tap0 上捕获,它实际上会附加到 tap0 的程序接口端,瞧,你会看到数据包。我在互联网上搜索,但没有找到证实这种行为的消息来源。要证伪这个理论,请捕获 tap0 并查看它如何影响数据包丢失和 iptables 日志。

最后,一个解决您最初问题的建议:使用环回设备怎么样?就像这样:

nicserver -p 7801 -a lo
Run Code Online (Sandbox Code Playgroud)