4、Tcpdump命令行实战:常用参数(-i, -n, -X, -w, -r),结合grep/awk分析
说实话,很多搞运维的兄弟,tcpdump 也就停留在「会装、会跑」的阶段。抓出来的包要么看不懂,要么文件大得吓人。今天我就带你把这几个核心参数吃透,顺便聊聊怎么用 grep 和 awk 快速定位问题。
核心思路:抓包不是目的,分析才是。参数选对了,事半功倍;选错了,抓一晚上也白搭。
4.1 参数速览:一张表说清楚
先给你个总览,我平时最常用的就这五个参数。你想想看,是不是每次抓包都离不开它们?
| 参数 | 作用 | 我的使用频率 | 一句话口诀 |
|---|---|---|---|
-i |
指定抓包网卡 | ⭐⭐⭐⭐⭐ | 没它抓不到包 |
-n |
不解析域名/IP | ⭐⭐⭐⭐⭐ | 不加它慢到哭 |
-X |
显示十六进制+ASCII | ⭐⭐⭐⭐ | 看协议细节必备 |
-w |
保存原始包到文件 | ⭐⭐⭐⭐⭐ | 抓大包必须用 |
-r |
读取保存的包文件 | ⭐⭐⭐⭐ | 离线分析全靠它 |
4.2 -i:选对网卡,成功一半
我记得刚入行那会儿,在一台双网卡服务器上抓包,死活抓不到流量。折腾了半天才发现,默认抓的是 lo 回环口。你说冤不冤?
先看看你机器上有哪些网卡:
tcpdump -D
输出会列出所有可用网卡,带编号。比如:
1.eth0 [Up, Running]
2.lo [Up, Running]
3.docker0 [Up]
然后指定你要抓的:
tcpdump -i eth0
小技巧:如果你不确定流量走哪张卡,可以用 tcpdump -i any。但注意,any 模式下不能抓某些特殊协议(比如 VLAN 标签)。我一般只在排查「流量到底走没走」时才用 any。
4.3 -n:别让 DNS 拖慢你
不加 -n 会怎样?tcpdump 会尝试把每个 IP 反解成域名。你想想看,一秒几千个包,每个都去查 DNS……不卡才怪。
我建议你养成习惯,默认就加 -n:
tcpdump -i eth0 -n
对比一下效果:
- 不加 -n:
IP ec2-54-123-45-67.compute-1.amazonaws.com.443 > myhost.local.54321 - 加了 -n:
IP 54.123.45.67.443 > 10.0.0.5.54321
哪个更清爽?一目了然。而且加了 -n 后,抓包性能能提升 30% 以上。我在一次生产环境抓包时,不加 -n 直接导致 tcpdump 丢包 40%,加上后瞬间降到 0%。
4.4 -X:看穿协议细节
-X 是我排查应用层问题时的利器。它同时显示十六进制和 ASCII 内容,特别适合看 HTTP 请求体、SQL 语句或者自定义协议。
tcpdump -i eth0 -n -X port 80
输出大概长这样:
0x0000: 4500 005c 1234 4000 4006 5678 0a00 0005 E..\.4@.@.Vx....
0x0010: 0a00 000a 0050 1f90 0000 0001 0000 0000 .....P..........
0x0020: 504f 5354 202f 6c6f 6769 6e20 4854 5450 POST./login.HTTP
0x0030: 2f31 2e31 0d0a 486f 7374 3a20 6578 616d /1.1..Host:.exam
0x0040: 706c 652e 636f 6d0d 0a55 7365 722d 4167 ple.com..User-Ag
看到右边那列了吗?POST /login HTTP/1.1 清清楚楚。我曾经用这个参数抓到一个诡异的 bug——客户端发了个空密码的登录请求,服务端没做校验直接返回 500。看十六进制一眼就发现了问题。
注意:-X 会输出大量内容,别在生产环境长时间开着。我一般只抓 10-20 个包,确认问题后就关掉。
4.5 -w 和 -r:抓了存,存了看
线上问题往往不是当场能分析的。这时候 -w 就派上用场了:
tcpdump -i eth0 -n -w capture.pcap
抓完以后,用 -r 回放:
tcpdump -r capture.pcap -n
你还可以在回放时加过滤条件,比如只看某个 IP:
tcpdump -r capture.pcap -n host 10.0.0.1
我个人习惯是:先 -w 存原始包,再用 -r 慢慢分析。这样既不影响线上抓包性能,又能反复看。
避坑指南:我曾经在磁盘快满的服务器上直接 -w,结果抓了 5 分钟就把根分区写爆了。建议:
- 用
-C 100限制每个文件 100MB,自动轮转 - 用
-W 10限制最多 10 个文件 - 组合起来:
tcpdump -i eth0 -n -w capture -C 100 -W 10
4.6 组合拳:grep + awk 快速定位
光靠 tcpdump 本身,分析大量包还是费劲。我一般会配合 grep 和 awk 做二次过滤。
4.6.1 用 grep 找关键字
比如你想看所有包含 "error" 的 HTTP 响应:
tcpdump -r capture.pcap -n -X | grep -i "error"
或者只看某个 IP 的流量:
tcpdump -r capture.pcap -n | grep "10.0.0.1"
4.6.2 用 awk 提取字段
awk 擅长处理结构化文本。比如你想统计每个 IP 发了多少包:
tcpdump -r capture.pcap -n | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn
这条命令干了什么?
- 提取第 3 列(源 IP+端口)
- 用 cut 去掉端口号
- 排序、去重、计数
- 按数量倒序排列
输出类似:
523 10.0.0.5
312 10.0.0.1
89 192.168.1.1
一眼就能看出哪个 IP 是「话痨」。
实战案例:有一次线上告警说数据库连接数爆了。我用 tcpdump -i eth0 -n port 3306 | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn 一跑,发现某个应用服务器 IP 的连接数是其他节点的 10 倍。顺藤摸瓜,找到那个应用有个连接池泄漏的 bug。
4.7 知识体系:一张图看懂
下面这张图总结了本章的核心逻辑,从抓包到分析,一条线串起来:
4.8 实战演练:一条命令搞定
最后,给你一个我常用的「一条龙」命令。假设你要排查 Web 服务器响应慢的问题:
tcpdump -i eth0 -n -s 0 -w web_slow.pcap -C 50 -W 5 port 80 &
# 等几分钟后 kill 掉 tcpdump 进程
# 然后分析
tcpdump -r web_slow.pcap -n | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head -10
这条命令:
-s 0:抓完整包(默认只抓前 68 字节)-C 50 -W 5:每个文件 50MB,最多 5 个port 80:只抓 HTTP 流量- 后台运行,不占用终端
嗯,到这里,tcpdump 的常用参数你应该已经掌握了。记住一个原则:先存后看,组合分析。下次遇到性能问题,别急着重启,先抓个包看看。