tcpdump 抓 HTTP/gRPC 包实战
更新时间:2026-09-18。
tcpdump是最通用的抓包工具,存成 pcap 后可在 Wireshark 里做精细分析。基础见 tcpdump 抓包,只想快速读明文流可看 tcpflow。
一、过滤与保存
bash
# 抓某主机 8080 流量,-s0 不截断包,-A 直接看 ASCII 明文
sudo tcpdump -i any -s0 -A 'host 10.0.0.21 and tcp port 8080'
# 存 pcap 供 Wireshark 分析(生产推荐:先存后分析,开销更低、信息全)
sudo tcpdump -i eth0 -s0 -w /tmp/app.pcap 'tcp port 8080'
# 只抓三次握手/SYN(排查连接建立、队列溢出)
sudo tcpdump -i any 'tcp[tcpflags] & tcp-syn != 0'
# 抓 gRPC(默认 9090)或按应用端口
sudo tcpdump -i any -s0 -w grpc.pcap 'tcp port 9090'BPF 常用:host/net/port/portrange、src/dst、tcp/udp、and/or/not、tcp[tcpflags]。表达式先在小范围验证,避免抓全量。
二、明文 HTTP
-A 下 HTTP/1 明文可直接看到请求行、Header、Body 与响应。注意一个连接上多个请求(keep-alive)交织时,Wireshark 的 Follow TCP Stream 更好读。
三、HTTPS 与 TLS
网络上抓到的 443 是密文。要看明文有两条路:
- 拿到会话密钥:让客户端用
SSLKEYLOGFILE=/tmp/keys.log(curl/浏览器/很多库支持),Wireshark 里配置该文件即可解密(TLS 1.2/1.3 均可,前提能抓到对应流量)。 - 在客户端侧用中间人代理(mitmproxy/Burp),适合测试环境。
四、gRPC / HTTP/2
gRPC 基于 HTTP/2 + protobuf,抓包要点:
- 看到的是 HTTP/2 二进制帧(
HEADERS、DATA、SETTINGS、WINDOW_UPDATE),不是 HTTP/1 文本;Wireshark 需正确识别为 HTTP/2(默认在 h2 先验端口或「Decode As → HTTP2」)。 - 请求路径形如
/user.UserService/GetUser,在:path伪头里。 - gRPC 状态码在响应尾部(
grpc-status、grpc-message,HTTP/2 trailing HEADERS),只看初始 200 会误判成功——HTTP 状态 200 但grpc-status != 0仍是业务错误。 - DATA 帧里的 protobuf body 是二进制,需配合
.proto才能解读字段。 - h2c(明文 HTTP/2)可直接看帧结构,h2(TLS)同样需要密钥解密。
常见坑
- 网卡选错:多网卡/容器环境要用
ip addr确认流量实际走的接口(或-i any);容器内抓要进入对应 netns。 - 抓太多把磁盘/CPU 打满:用精确 BPF(主机+端口)、限制轮转
-W/-C,短时抓。 - 包被截断:没加
-s0时默认快照长度可能切掉 payload,存 pcap 务必-s0。 - 以为 200 就是成功:gRPC 成败看 trailing
grpc-status,不是 HTTP 状态码。 - 端口不固定:很多服务随机端口/服务网格,先据连接(
ss -ntp)确认真实端口。 - 时钟与时序:跨机排查注意两端时钟对齐,Wireshark 看 RTT/重传才有意义。
总结
tcpdump 用 host/port 及 tcpflags 等 BPF 表达式精确过滤、用 -s0 加 -w 存 pcap 交给 Wireshark 做时序与 Follow Stream 分析,明文 HTTP/1 可直接 -A 读,HTTPS 必须靠客户端导出的 SSLKEYLOGFILE 在 Wireshark 解密或用中间人代理;gRPC 是 HTTP/2 二进制帧,要让 Wireshark 识别为 HTTP2、在 :path 伪头看方法,并特别注意成功与否取决于响应尾部的 grpc-status 而非 HTTP 200,protobuf body 还需 proto 才能解字段;排障时要先按 ss 确认真实端口和网卡(容器需进入对应网络命名空间)、用强过滤与轮转文件控制开销,避免抓全量打爆磁盘。