做网络排查的时候,你有没有过这样的困惑:
- •
tcpdump明明抓到包了,为什么应用没收到? - • 应用发送成功了,为什么
tcpdump抓不到出站包? - • 为什么添加了
iptables规则,抓包结果好像没变化?
如果你有这些疑问,那今天这篇文章就是为你准备的。我们来好好聊聊Linux内核中数据包的完整旅程,特别是tcpdump抓包点和iptables钩子之间的“爱恨情仇”。
读完这篇文章,你将彻底搞懂一张数据包流程图,以后排错定位,心里倍儿有底。
01 数据包的“三趟旅程”
在Linux世界里,数据包的处理可以分为三种典型场景,就像一个人出门的三种方式:
- • 入站本地交付:就像你收快递(别人发给你,本机应用处理)。
- • 出站本地发起:就像你寄快递(本机应用发出,发给外部)。
- • 三层转发:就像快递驿站代收代发(本机作为路由器转发别人的包)。
我们先从最经典的“收快递”开始。
02 入站(收快递):Wire → 应用
当一个包从网线到达我们的主机,它经历了哪些关卡呢?
简化路径如下:
Wire → NIC → 【tcpdump入站抓包点】 → Netfilter PREROUTING → 路由决策(判断是本机的) → Netfilter INPUT → 应用
用流程图来理解,大概是这样(请自行脑补一张“安检在前,登记在后”的流水线示意图):
【图1:入站流程图】
关键点来了,请记住:
入站方向,tcpdump先抓包,iptables后过滤。
也就是说,只要包到了你的网卡,无论你后面用INPUT链怎么拦截,tcpdump都能看到这个包。
这就是“抓得到包,但应用收不到”的根本原因——包被INPUT链安检员(iptables)给扣下了!
03 出站(寄快递):应用 → Wire
当你本机的应用(比如一个Web服务想要回复客户请求)向外发送数据时,旅程完全反过来。
简化路径:
应用 → 路由决策 → Netfilter OUTPUT → Netfilter POSTROUTING → 【tcpdump出站抓包点】 → NIC → Wire
再画个图感受一下:
【图2:出站流程图】
这里的核心区别是:
出站方向,iptables先过滤,tcpdump后抓包。
你的包必须先通过OUTPUT和POSTROUTING两道安检门的检查,来到出口时,tcpdump摄像头才会给它拍照。
所以,如果你的应用发送了数据,但tcpdump啥也没抓到,不用多想了,大概率是包在OUTPUT或POSTROUTING链上就被“就地正法”了。反之,如果tcpdump抓到了包,那说明本机的一切规则都已顺利通过,包已经成功交给了网卡。如果对端还是没收到,问题就在外部的链路上了。
04 转发(代收代发):Wire → Wire
当你的Linux主机配置了ip_forward=1,充当路由器、网关时,包就会走“转发”通道。
简化路径:
Wire(入) → NIC(入) → tcpdump入站 → PREROUTING → 路由决策(不是本机) → FORWARD → POSTROUTING → tcpdump出站 → NIC(出) → Wire(出)
注意看,转发流量不会经过INPUT和OUTPUT链。所以,如果你想控制穿过这台主机的流量,记得规则要写在FORWARD链上,写在其他链上可就“管不住”了。
05 一张图总结核心逻辑
我们把三种场景的钩子顺序总结成一张表,方便你随时查阅:
| | |
|---|
| 入站 | tcpdump → PREROUTING → INPUT | |
| 出站 | OUTPUT → POSTROUTING → tcpdump | |
| 转发 | tcpdump → PREROUTING → FORWARD → POSTROUTING → tcpdump | |
06 排障黄金法则,照着查就对了
基于上面的逻辑,你可以总结出两条最实用的排查法则:
1. 入站不通怎么办?
- •
tcpdump抓不到包 → 问题在主机之外。检查物理线路、交换机、路由器、防火墙以及对端是否真的发出来了。 - •
tcpdump抓得到包,应用收不到 → 问题在本机。检查iptables的INPUT链规则,再看应用端口有没有正常监听(ss -tlnp),最后别忘了SELinux。
2. 出站不通怎么办?
- •
tcpdump抓不到包 → 问题在本机。检查iptables的OUTPUT链和POSTROUTING链(尤其是SNAT规则),再看本机的路由表是否正确(ip route get <目标IP>)。 - •
tcpdump抓得到包,但对方收不到 → 问题在主机之外。包已经从你的网卡出去了,去排查你的网关、中间链路、对端防火墙吧。
好了,今天的分享就到这里。
Linux内核网络栈的设计非常精妙,理解了这些“钩子”和“抓包点”的相对位置,就等于拥有了一张精确的网络排障地图。下次遇到问题,不用再靠猜了,照着地图走一遍,问题根源一目了然。
你在实际工作中,有没有遇到过“tcpdump抓到了包但应用没收到的”诡异问题?最后是怎么解决的?欢迎在留言区分享你的排查故事,我们一起聊聊!