当前位置:首页>Linux>网络排障必看:Linux数据包“入站/出站/转发”的奇妙之旅

网络排障必看:Linux数据包“入站/出站/转发”的奇妙之旅

  • 2026-10-11 08:16:37
网络排障必看:Linux数据包“入站/出站/转发”的奇妙之旅

做网络排查的时候,你有没有过这样的困惑:

  • • 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
不经过INPUT/OUTPUT

06 排障黄金法则,照着查就对了

基于上面的逻辑,你可以总结出两条最实用的排查法则:

1. 入站不通怎么办?

  • • tcpdump抓不到包 → 问题在主机之外。检查物理线路、交换机、路由器、防火墙以及对端是否真的发出来了。
  • • tcpdump抓得到包,应用收不到 → 问题在本机。检查iptables的INPUT链规则,再看应用端口有没有正常监听(ss -tlnp),最后别忘了SELinux。

2. 出站不通怎么办?

  • • tcpdump抓不到包 → 问题在本机。检查iptables的OUTPUT链和POSTROUTING链(尤其是SNAT规则),再看本机的路由表是否正确(ip route get <目标IP>)。
  • • tcpdump抓得到包,但对方收不到 → 问题在主机之外。包已经从你的网卡出去了,去排查你的网关、中间链路、对端防火墙吧。

好了,今天的分享就到这里。

Linux内核网络栈的设计非常精妙,理解了这些“钩子”和“抓包点”的相对位置,就等于拥有了一张精确的网络排障地图。下次遇到问题,不用再靠猜了,照着地图走一遍,问题根源一目了然。

你在实际工作中,有没有遇到过“tcpdump抓到了包但应用没收到的”诡异问题?最后是怎么解决的?欢迎在留言区分享你的排查故事,我们一起聊聊!

最新文章

随机文章