tcpdump 实战:用命令行抓包排查网络故障

当你在服务器上遇到接口超时、连接被拒或偶发丢包,而应用日志却一团和气时,tcpdump 就是你的第一把手术刀。作为最经典的命令行抓包工具,tcpdump 能在无图形界面的生产环境直接捕获网卡流量,把”网络故障”从玄学猜测变成可视证据。本文从基础语法讲到三个真实排查场景,帮你用抓包快速定位问题。

一、tcpdump 能解决哪类网络故障

很多”网络问题”其实根本不在网络层,而在应用层或配置层。tcpdump 的价值在于用数据包本身说话,尤其在以下场景不可替代:

  • 接口偶发超时,但服务端日志显示请求根本没进来——抓包能确认包到底到没到。
  • TCP 连接能建立但很快被 RST 断开,需要看是谁先发的断开标志。
  • 怀疑有异常出站流量或扫描行为,需要看实际发出去的包。
  • Nginx、Docker 网络、DNS 等组件的边界问题,用抓包确认流量走向。

它和 Wireshark 图形化抓包 是互补关系:Wireshark 适合在本地分析,而 tcpdump 胜在服务器上”随手就能跑”,尤其当机器没有图形界面、也不方便把流量导出来时。

二、基础语法与权限

tcpdump 需要读取网卡,通常以 root 或具备 CAP_NET_RAW 权限的用户运行。最基本的命令是监听某个网卡并打印摘要:

# 监听所有网卡, numeric 输出(不反向解析主机名),显示详细信息
sudo tcpdump -i any -n -v

# 只看 eth0,且不显示链路层头,输出更紧凑
sudo tcpdump -i eth0 -n -t

# 限制抓取 100 个包后自动退出,避免刷屏
sudo tcpdump -i any -n -c 100

常用参数速记:-i 指定网卡(any 表示全部),-n 不解析域名、-nn 连端口号也不解析成服务名(更快更干净),-v/-vv 提高冗余度,-c 限制包数,-w 写入文件。

一个高频踩坑:明明有流量却”抓不到回包”。通常不是 tcpdump 坏了,而是抓错了网卡——容器里的服务流量走 docker0 或 veth 虚拟网卡,直接抓 eth0 自然看不到;用 -i any 或先 ip addr 确认发包网卡最稳妥。另外,若本机发出的包被网卡开启了 GRO/GSO 卸载而合并,抓包可能看到异常的”超大帧”,属正常现象,不影响分析。

三、过滤表达式:精准抓你想要的包

生产环境流量巨大,不加过滤会瞬间淹没终端。tcpdump 的过滤表达式(BPF)是它的精髓,按”原语”组合即可:

原语含义示例
host匹配源或目的 IP/主机host 10.0.0.5
src / dst限定方向dst host 10.0.0.5
port匹配端口port 8080
net匹配网段net 192.168.1.0/24
tcp / udp / icmp匹配协议tcp
and / or / not逻辑组合host 10.0.0.5 and port 8080

例如只关心发往 8080 端口、且来自特定客户端的 TCP 包:

sudo tcpdump -i eth0 -nn 'host 10.0.0.5 and tcp port 8080'

四、实战一:定位接口连接超时(看三次握手)

最经典的故障:客户端连某个服务一直超时。先抓两端之间的包,重点看 TCP 三次握手是否完成:

# 抓取与目标主机之间的 TCP 握手与断开标志
sudo tcpdump -i eth0 -nn 'host 10.0.0.5 and tcp port 8080 and tcp[tcpflags] & (tcp-syn|tcp-ack|tcp-rst) != 0'

正常情况应看到 SYN → SYN,ACK → ACK 三行。如果只看到客户端发出的 SYN 却没有任何回应,说明包到了服务器但没进程监听该端口,或中间防火墙把包丢了——这时要去查对端服务是否真的在监听(ss -lntp),以及安全组/iptables 规则。若看到 SYN 后有 RST 立即回包,通常是端口无服务或连接被主动拒绝。

这类”包到了但应用没反应”的问题,也常和反向代理层有关,可以参考 Nginx 反向代理完整配置 排查 upstream 是否真正可达。

五、实战二:排查丢包与重传

接口偶发卡顿、响应慢,往往是 TCP 重传在作祟。抓包时关注 RST 和重传:

# 抓取所有 RST 和 SYN 包,快速发现异常断开
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-rst|tcp-syn) != 0'

# 抓取重传(TCP 序号重复出现通常意味着丢包)
sudo tcpdump -i eth0 -nn 'host 10.0.0.5 and (tcp[tcpflags] & tcp-ack != 0)' -v

如果抓包里频繁出现同一序号的重复 ACK 或重传,基本可以判定链路存在丢包,可能是网卡、交换机、云厂商限速或 MTU 不匹配。此时结合 ifconfig 看 RX/TX errors、dropped 计数,以及 mtr 逐跳观察,能进一步收敛根因。确认重传最直观的办法是加 -v 看每段的 seq 与 ack 序号:正常交互里确认号稳步递增,一旦发现某个 seq 被重复发送、且伴随 DUP ACK,就是接收方没收到、发送方在补发,丢包坐实。

六、实战三:揪出异常出站流量

怀疑服务器被植入挖矿或扫描程序时,可以反向抓”不该出去的包”。比如只允许内网通信,却看到大量发往外网的连接:

# 抓所有"目的地不在内网 10.0.0.0/8"的出站 TCP 包
sudo tcpdump -i eth0 -nn 'dst net not 10.0.0.0/8 and tcp'

通过分析这些包的目的 IP 和端口,往往能直接定位到可疑进程(再用 netstat -antp 或 ss -antp 反查 PID)。在容器化环境里,异常流量有时来自某个容器,可结合 Docker Compose 网络模式 理解容器间通信边界。

七、把抓包存下来用 Wireshark 深分析

终端里看摘要不够时,用 -w 存成 pcap 文件,下载到本地用 Wireshark 打开,能看明文协议、TLS 握手、HTTP 内容等:

# 抓取 60 秒后自动停止,写入文件(生产环境避免无限抓包占满磁盘)
sudo tcpdump -i eth0 -nn -G 60 -W 1 -w /tmp/capture_%Y%m%d_%H%M.pcap 'host 10.0.0.5 and port 8080'

# 边抓边用 gzip 压缩,节省空间
sudo tcpdump -i eth0 -nn -w - 'port 443' | gzip > /tmp/cap.pcap.gz

-G 60 -W 1 表示每 60 秒滚动一次、最多保留 1 个文件,是生产环境防磁盘写爆的标配。抓完后用 scp 拉回本地即可。

八、常见坑与排障清单

现象可能原因抓包验证要点
客户端超时无响应服务未监听 / 防火墙丢弃只看到 SYN,无 SYN,ACK
连接秒断端口无服务 / 主动 RSTSYN 之后紧跟 RST
响应慢、卡顿链路丢包 / 重传重复 ACK、重传序号
能 ping 通但端口不通安全组/iptables 限制ICMP 通但 TCP SYN 无回
容器间不通Docker 网络/网段冲突跨网桥无对应 MAC 转发

抓包排查奉行的原则很简单:先确认包到没到,再确认包对不对,最后看是谁先动手断开。有了 tcpdump 这把刀,绝大多数”网络玄学”都能在几分钟内现出原形。如果问题出在域名解析阶段而非 TCP 传输,可以进一步参考 DNS 解析故障排查实战;若是 TCP 连接数打满导致的端口耗尽,可看 TIME_WAIT 过多排查实战 对症下药。

上一篇 Java 引用类型实战:强引用、软引用、弱引用与虚引用
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]