Linux tcpdump 抓包与分析技巧

1次阅读

抓包必须加 -s 0 保证完整捕获应用层数据,-nn 禁用解析防卡顿,过滤需明确 src/dst 方向,-c 与 -w 组合实现自动轮转防磁盘打满。

Linux tcpdump 抓包与分析技巧

抓包前必须加 -s 0,否则 http/https 明文可能被截断

默认 tcpdump 只抓前 68 字节,对 TCP 头够用,但对应用层数据(比如 HTTP 请求头、json 响应体)远远不够——你会看到一不完整的 GET /api/… 或乱码,甚至根本看不到 Host、User-Agent 等关键字段。

  • -s 0 表示“抓完整包”,这是分析 Web 流量的底线配置,不是可选项
  • 如果漏掉它,wireshark 里点开 TCP 流时会显示 [Packet size limited during capture],说明数据已被丢弃
  • 在高吞吐场景下,-s 0 会略微增加磁盘 I/O 和内存占用,但相比丢关键信息,这点代价几乎可以忽略

保存 pcap 文件时,别直接用 tcpdump -w file.cap 而不加 -n-nn

默认 tcpdump 会对每个 IP 和端口做反向 DNS 解析和 /etc/services 查找,导致抓包过程卡顿、延迟升高,甚至在无 DNS 环境下阻塞数秒才出第一行;更糟的是,解析失败时可能让输出混乱或中断。

  • -n:禁用主机名解析(IP 直接显示),保留端口服务名(如 http
  • -nn:同时禁用主机名和端口名解析(显示为 192.168.1.100.8080),最干净、最稳定,推荐日常使用
  • 如果你后续要用 Wireshark 分析,它自己会做解析,tcpdump 这边没必要重复干

过滤表达式里写 host A and port 80 不等于只抓 A 的 80 端口流量

这个常见写法实际匹配的是“源或目的为 A,且源或目的端口为 80”的所有包——比如 A 发起的 HTTPS 握手(目标端口 443)不会被捕获,但 A 收到的来自某 CDN 的 HTTP 响应(源端口 80)却会被抓进来,逻辑容易混淆。

  • 要精准抓 A 主机发起的 HTTP 请求,用:src host A and dst port 80
  • 要抓 A 主机收到的 HTTP 响应,用:dst host A and src port 80
  • 想同时覆盖请求+响应,且确保是同一连接,建议用:host A and (port 80 or port 443),再靠 Wireshark 的 “Follow TCP Stream” 后续筛选
  • 注意括号必须用反斜杠转义:and ( port 80 or port 443 ),否则 shell 会报错

后台长期抓包别只靠 nohup,得配 -C-W 防磁盘打满

线上问题复现慢,常需挂几个小时甚至过夜。若只用 nohup tcpdump -w log.cap &,一旦网络突发流量大,单个文件可能飙到几十 GB,轻则填满根分区,重则触发 OOM 或日志轮转失败。

  • -C 100:按 100MB 自动切分(单位是 MB,不是 MiB),生成 log.caplog.cap1log.cap2
  • -W 10:最多保留 10 个分片,旧文件自动覆盖,避免无限增长
  • 组合起来就是:nohup tcpdump -i eth0 -nn -s 0 -C 100 -W 10 -w /var/log/tcpdump/http.cap &
  • 注意:-C-W 必须一起用才有意义,单独 -C 仍可能积累大量文件

Wireshark 里打开 pcap 后,真正难的是判断哪个包是“第一个 SYN”、哪个是“最后 FIN”,而不是怎么抓到它——tcpdump 抓得再全,也替代不了对 TCP 状态机的理解。

text=ZqhQzanResources