当网络抽风时,我是如何用 tcpdump 揪出真凶的
大家好,我是老王。上周我们线上服务突然出现间歇性连接超时,作为团队里最会”抓包”的男人(自封的),我自然扛起了排查的大旗。今天就跟大家分享几个我用 tcpdump 实战排查网络问题的硬核技巧。
为什么我总带着 tcpdump 这把”瑞士军刀”
记得刚入行时遇到网络问题就抓瞎,直到有天 mentor 甩给我一句 tcpdump -i eth0 -w dump.pcap
。八年过去了,这个命令依然是我排查网络问题的首选武器。相比 wireshark 的图形界面,tcpdump 的轻量级特性让它成为服务器环境下的不二之选。
上周的问题是这样的:Nginx 日志里突然出现大量 499 状态码,但下游服务坚称自己很健康。这时候就该祭出我们的三板斧了:
tcpdump -i any -s 0 -w /tmp/trouble.pcap 'port 80 or port 443'
# -i any 监听所有网卡
# -s 0 抓完整数据包
# 只抓业务相关端口减少干扰
过滤技巧:从大海里捞出你要的针
第一次抓包我就犯了个错误 – 直接全量抓取,结果 5 分钟就生成了 2GB 的 pcap 文件。后来我学聪明了,用这些过滤条件精准打击:
# 只看某个IP的流量
tcpdump host 192.168.1.100
# 组合条件抓特定会话
tcpdump 'tcp port 8080 and (src host 10.0.0.1 or dst host 10.0.0.1)'
# 抓取异常状态包
tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'
特别是最后这个 TCP 状态位过滤,帮我发现了大量异常的 FIN 包,正是问题的关键线索。
读懂 TCP 对话:网络世界的唇语解读
抓到的包就像加密电报,需要翻译才能读懂。这里分享我的看包心得:
- 三次握手异常:看到 SYN 没响应?可能是防火墙拦截
- 快速重传:重复的 ACK 号暗示网络丢包
- 零窗口:接收方处理不过来会发 window=0
上周的问题最终定位到是某个微服务异常关闭连接时,没有正确完成四次挥手。通过下面这个命令,我清晰地看到了异常断开的 TCP 流:
tcpdump -nn -r trouble.pcap 'tcp[13] & 1 != 0' | awk '{print $3,$5,$6}'
高级玩法:当普通抓包不够用时
有些疑难杂症需要特殊处理:
# 抓取HTTP明文(千万别在生产环境用!)
tcpdump -A -s0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
# 统计TCP错误包
tcpdump -qnn -r packet.pcap 'tcp[tcpflags] & (tcp-rst|tcp-ack) == tcp-rst' | wc -l
# 实时监控特定连接
tcpdump -l -i eth0 'host 10.0.0.5 and port 3306' | grep -i 'error'
最后提醒大家,抓包时一定要注意:生产环境慎用 -A 参数,我曾经不小心把包含敏感信息的抓包结果发到了技术群,那场面…(手动狗头)
写在最后
经过这次排查,我又一次被 tcpdump 的强大所折服。虽然现在有各种 APM 监控工具,但掌握这种底层排查技能,就像医生会看X光片一样重要。下次遇到网络问题,不妨试试这个”网络听诊器”,你可能会发现意想不到的真相。
如果大家有更有趣的抓包技巧,欢迎在评论区交流~
学到了,tcpdump 果然是排查网络问题的神器啊!👍
看完文章默默打开了终端试了下,果然抓到了我们内网的异常包!感谢分享
FIN包那个过滤条件太有用了,我们之前排查类似问题浪费了好多时间。。
生产环境千万别用-A是真的,上次有个菜鸟把数据库密码都抓出来了,简直社死现场🤦♀️
老哥写得很实在啊,不过想问下如果抓取量很大怎么优化性能?
第一次看到把tcpdump讲得这么清楚的,适合像我这样的小白入门!
代码格式舒服,命令都是实战总结的干货,收藏了!
文章里的技巧都很实用,就是缺个案例分析,要是能再详细点就更好了
这几天刚好在搞网络问题,立马实践了一下,配合wireshark分析太方便了!