tcpdump 抓包:先缩小范围,再开始看
抓包最大的浪费不是不会看,是一上来就 tcpdump -i any 全量刷屏,
在几千行里找一个问题。这篇的写法都是「先窄后宽」。
一、先确认在哪抓
ip -br addr # 看有哪些接口、各自的地址
ip route get 1.1.1.1 # 看访问外网走哪个接口
- 抓本机进程之间的通信,用
-i lo。它在any上常常看不到,这是最容易卡住的一步。 - 抓对外流量,用具体网卡名(
eth0、ens3)比any准确,也不会抓到无关流量。 -i any方便,但链路层头会显示成Linux cooked,做协议分析时不如指定网卡。
二、权限:为什么普通用户报「Operation not permitted」
抓包需要 CAP_NET_RAW 能力,普通用户默认没有。三种做法:
# 1) 直接 sudo(最省事)
sudo tcpdump -i eth0
# 2) 给二进制加能力(注意:这等于放开了抓包权限,谨慎)
sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/tcpdump
# 3) 抓成文件,改属主后用自己的账号离线分析(推荐)
sudo tcpdump -i eth0 -w /tmp/x.pcap
sudo chown $USER /tmp/x.pcap
第 3 种最稳:线上机器上不放开权限,抓完再回本地用 Wireshark 慢慢看。
三、过滤器:BPF 语法的基础
tcpdump 的过滤表达式就是 BPF,常用的是这几个维度:
-nn # 不做 DNS 反解、端口显示成数字(少了等待,速度明显快)
host 10.0.0.12 # 某个 IP 的收发
src host 10.0.0.12 # 只看来向
dst port 443 # 目标是 443
port 8080 # 源或目标是 8080
net 10.0.0.0/24 # 整段
tcp and not port 22 # 组合,排除自己的 SSH 会话
几个真正常用的组合:
# 只看 TCP 建连(SYN 置位且 ACK 未置位)
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'
# 看有没有被 RST(对端拒绝或端口未开)
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-rst != 0'
# 只看某台后端、并且排除 SSH
sudo tcpdump -i eth0 -nn 'host 10.0.0.12 and tcp and not port 22'
四、输出怎么读
14:32:07.918273 IP 10.0.0.5.51234 > 10.0.0.12.80: Flags [S], seq 1234567, win 64240, length 0
Flags [S]发起连接,[S.]回应,[.]是普通 ACK,[P.]带数据,[F.]关闭,[R]重置。seq是序列号,length 0表示这个包不带负载。- 只看到
[S]没有[S.],说明对端没回——要么没收到,要么被防火墙丢了。 - 看到
[R]立刻回,通常是端口没在监听。
五、看内容:-A 和 -X
sudo tcpdump -i eth0 -nn -A -s0 'tcp port 80' # 按 ASCII 打印负载
sudo tcpdump -i eth0 -nn -X -s0 'tcp port 80' # 十六进制 + ASCII 并排
-s0 表示抓整包(不截断)。不带它的话会有一个默认截断长度,
抓 HTTP 头够用,抓带 body 的请求就会被切掉。
明文协议(HTTP、Redis、MySQL 的旧协议)能这么看; HTTPS 只能看到 TLS 记录层的长度和类型,看不到内容——这是设计如此,不是抓包工具的问题。
六、边抓边注意磁盘
# 循环写文件,每 100MB 一个,最多留 10 个(够回看最近一段)
sudo tcpdump -i eth0 -nn -s0 -w /tmp/cap.pcap -C 100 -W 10 'tcp port 8080'
千兆链路上跑满时,pcap 每分钟能长到几百 MB。不带 -C/-W
就在生产机上一直抓,把磁盘写满只是时间问题。
七、离线分析
tcpdump -nn -r /tmp/cap.pcap 'tcp port 8080' | head -50
tcpdump -nn -tttt -r /tmp/cap.pcap # -tttt 显示完整日期时间
更复杂的需求就拉到本地用 Wireshark 看:Follow TCP Stream 能拼出完整会话, 统计里的「专家信息」会直接标出重传、乱序、零窗口这些异常。
先分清是「包没到」还是「到了但慢」:抓在服务端网卡上能看到 SYN 却看不到后续数据, 问题在对端或中间链路;两个方向都有包但间隔很大,才是服务端自己的处理慢。
一句话总结:先用最窄的过滤器抓一小段,存成 pcap 再慢慢看;抓不到包先确认接口和权限,别急着怀疑网络。