「Network」- 关于TCPDUMP和IPTABLES的先后顺序

问题背景

当 Host-A 无法访问 Host-B 时,我们可以在 Host-B 上使用tcpdump抓包,检查 Host-B 是否收到了数据包。

而 Host-B 上通常都配置了防火墙,那在 Host-B 上数据包是先被 tcpdump 捕获呢,还是先被 iptables 过滤调了?

实际情况

事实上它们的关系是这样子的:

Wire -> NIC -> tcpdump -> netfilter -> applications -> netfilter -> tcpdump -> NIC -> Wire

因此,使用tcpdump后,可以看到流入网卡的全部数据包,也可以看到流出网卡的所有数据包,但是不一定能看到应用程序返回的数据包。

详细说明

在Linux中,当「网络栈」中接收到「常规数据包」时,「内核」首先检查是否存在对「常规数据包」感兴趣的「数据包套接字」,如果有,则将「常规数据包」转发到该「数据包套接字」。如果使用了选项ETH_P_ALL,则所有协议都通过数据包套接字。

命令tcpdump基于libpcap库,而该库用于创建「数据包套接字」。libpcap使用ETH_P_ALL选项实现一个这样的「数据包套接字」,将「常规数据包」保留一个副本供自己分析使用,并将「常规数据包」复制回「网络栈」中,然后内核就可以以通常的方式处理它,这包括首先将它传递给netfilter(iptables的内核空间对应物)。同样的事情,在发送数据包的情况下,以相反的顺序发生(即,第一个netfilter,然后通过「数据包套接字」)。

所以在某些rootkit中,可以使用libpacp来绕过防火墙。

参考文献

Will tcpdump see packets that are being dropped by iptables?
Does tcpdump bypass iptables?
Iptables FORWARD chain traffic not seen by tcpdump
Debugging iptables rules with tcpdump and wireshark