【Linux】tcpdump实战:从基础抓包到UDP大包深度解析
1. tcpdump基础入门:你的第一行抓包命令
第一次接触tcpdump时,我盯着黑黢黢的终端窗口敲下命令后,突然刷屏的十六进制数据差点让我以为系统崩溃了。其实这就是网络世界的真实模样——所有应用层的光鲜亮丽,底层都是这样赤裸裸的二进制对话。
最基础的抓包命令 只需要指定网卡即可:
sudo tcpdump -i eth0
这里的 -i eth0 表示监听eth0网卡,如果不确定网卡名称,可以用 ifconfig 查看,或者直接用 -i any 监听所有网卡。执行后你会看到实时滚动的数据包信息,每行包含:
- 时间戳(如
10:23:45.678901) - 协议类型(IP/IPv6)
- 源地址和端口(
192.168.1.100.52034) - 目标地址和端口(
203.0.113.5.443) - 标志位(Flags [S]表示SYN包)
- 序列号(seq 123456)
- 数据长度(length 120)
新手常见误区 是直接抓所有包,结果被海量数据淹没。我的建议是:
- 先用
-c 5限制抓包数量(如只抓5个包) - 添加
-nn禁止DNS解析(避免卡顿) - 对HTTP分析可加
-A打印ASCII内容
sudo tcpdump -i any -c 5 -nn -A port 80
典型应用场景 比如发现某服务无法连接时:
- 确认请求是否发出:
tcpdump -i any host 目标IP - 检查防火墙是否拦截:
tcpdump -i any port 目标端口 - 验证DNS解析:
tcpdump -i any port 53
提示:生产环境慎用
-A参数,可能泄露敏感信息。我曾不小心把数据库密码打印到终端上,从此养成了先用-X看十六进制的好习惯。
2. 精准过滤:像外科手术般的抓包技巧
在数据中心排障时,面对每秒数万的数据包,不加过滤的抓包就像在消防栓上接吸管喝水。tcpdump的过滤语法就是你的手术刀,这里分享几个 实战中救命的过滤技巧 :
按协议类型过滤 是最基础的操作:
# 只要TCP流量
sudo tcpdump -i any tcp
# 抓取ICMP(ping包)
sudo tcpdump -i any icmp
# UDP专属通道
sudo tcpdump -i any udp
复合逻辑过滤 才是高级玩法:
# 抓取来自10.0.0.1或去往10.0.0.2的HTTP流量
sudo tcpdump -i any '(src host 10.0.0.1 or dst host 10.0.0.2) and port 80'
# 排除SSH和DNS的干扰
sudo tcpdump -i any 'not (port 22 or port 53)'
特殊场景过滤 示例:
# 抓取分片包(适合排查MTU问题)
sudo tcpdump -i any 'ip[6] & 0x20 != 0'
# 抓取TCP RST异常包
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-rst) != 0'
过滤语法对照表
| 过滤条件 | 含义 | 示例 |
|---|---|---|
| src host | 源IP匹配 | src host 192.168.1.1 |
| dst port | 目标端口匹配 | dst port 443 |
| net | 网段匹配 | net 192.168.0.0/24 |
| proto | 协议匹配 | icmp or arp |
| less/greater | 包大小过滤 | greater 1000 |
有次排查CDN异常,我用 tcpdump -i any 'tcp[13] & 8 != 0' 专抓PSH标志位包,快速定位了TCP推送异常问题。这种基于协议栈深度的过滤,就像给数据包做了X光透视。
3. UDP大包捕获:当数据超过1472字节时
第一次遇到UDP大包丢失时,我盯着 udp-bad-length 的提示百思不得其解。后来才明白这是Linux网络栈的经典陷阱—— MTU限制 。普通UDP抓包只能看到前1472字节(1500MTU - 20IP头 - 8UDP头),超出部分会被分片。
完整捕获4KB大包的正确姿势 :
# 按目标IP抓包(避开端口过滤的分片问题)
sudo tcpdump -i eth0 -X -vvv dst host 10.60.18.80
分片包分析要点 :
- 首包 显示为
udp-bad-length,包含UDP头+部分数据 - 后续分片 标记为
ip-proto-17(17是UDP的IP协议号) - 分片包的IP头会有
MF标志(More Fragments)
典型分片包结构示例 :
10:01:23.456789 IP (tos 0x0, ttl 64, id 12345, offset 0, flags [DF], proto UDP (17), length 1500)
10.23.48.170.12500 > 10.60.18.80.700: [udp sum ok] UDP, bad length 1984 > 1472
10:01:23.456790 IP (tos 0x0, ttl 64, id 12345, offset 1480, flags [none], proto UDP (17), length 1500)
10.23.48.170 > 10.60.18.80: ip-proto-17
10:01:23.456791 IP (tos 0x0, ttl 64, id 12345, offset 2960, flags [none], proto UDP (17), length 1040)
10.23.48.170 > 10.60.18.80: ip-proto-17
警告:虚拟机环境中MTU问题更常见。有次我在KVM环境抓包,发现所有大于1450字节的UDP包都被标记为bad-length,最后发现是虚拟网卡的MTU设置问题。
4. 高级分析:用-X和-w玩转数据包
当基础抓包无法满足需求时,tcpdump还有两个杀手锏参数: -X 和**-w**。前者让你看到原始数据,后者保存证据供后续分析。
十六进制解码实战 :
# 抓取HTTP请求头(-s0表示不截断)
sudo tcpdump -i any -A -s0 'port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
这个看似天书般的命令其实在匹配TCP负载中的"GET "字符串(十六进制47 45 54 20)。同理可以抓:
- HTTP POST:
0x504f5354 - SSH开头:
0x5353482d
文件记录与回放技巧 :
# 保存为pcap文件(可用Wireshark打开)
sudo tcpdump -i any -w debug.pcap port 80
# 从文件读取分析
tcpdump -r debug.pcap -nn 'host 8.8.8.8'
自动分割大文件 的运维技巧:
# 每3600秒(1小时)或200MB轮转一个文件
sudo tcpdump -i any -G 3600 -C 200 -w %Y%m%d-%H%M%S.pcap
有次分析物联网设备异常,我用 tcpdump -X | grep -B10 -A10 "异常特征" 在几千条日志中快速锁定了固件bug。后来这个案例让我养成了 关键操作必录pcap 的习惯——就像外科医生必须保留手术录像一样。
5. 实战案例:从抓包到解决问题的完整过程
去年处理过一个经典案例:某视频会议系统在跨国传输时频繁卡顿。通过tcpdump我们最终定位是UDP分片重组超时问题,以下是 详细排查过程 :
第一阶段:基础抓包
# 在发送端抓包(限制每秒100个包避免卡死)
sudo tcpdump -i eth0 -c 100 -nn udp and host 203.0.113.25
发现大量 udp-bad-length 提示,确认存在大包分片
第二阶段:深入分析分片
# 抓取全部分片包并按IP ID排序
sudo tcpdump -i eth0 -vvv -nn 'ip[6:2] & 0x1fff != 0' | sort -k 9
观察到分片ID为12345的包只有前两个分片到达,第三个分片丢失
第三阶段:路径MTU检测
# 发送不同大小包测试MTU
ping -M do -s 1472 203.0.113.25 # 成功
ping -M do -s 1473 203.0.113.25 # 失败
确认路径中存在MTU 1500的限制
最终解决方案 :
- 调整视频流分片大小为1400字节
- 在发送端设置
setsockopt(fd, IP_MTU_DISCOVER, IP_PMTUDISC_PROBE) - 增加接收端分片缓存时间
sysctl -w net.ipv4.ipfrag_time=30
这个案例让我深刻理解到: 抓包只是开始,解读才是艺术 。就像老中医把脉,同样的数据在不同人眼里能看到不同层次的病理特征。
更多推荐





所有评论(0)