3. tcpdump 核心用法:从安装到实战抓取 HTTP 流量

说实话,tcpdump 是我日常排错用得最多的工具,没有之一。它轻量、直接,几乎所有的 Linux 发行版都自带或能快速装上。我记得刚入行那会儿,遇到网络问题第一反应是上 Wireshark,后来发现很多服务器根本没有图形界面,才老老实实把 tcpdump 啃透。今天我就把这套心法拆开揉碎了讲给你听。

3.1 安装 tcpdump

大多数系统默认没装,但装起来很简单。我个人习惯先确认一下系统版本,再选对应的安装命令。

系统 安装命令
CentOS / RHEL yum install -y tcpdump
Ubuntu / Debian apt-get install -y tcpdump
Alpine apk add tcpdump
小提示:装完后先跑一下 tcpdump --version,确认版本号。我遇到过几次因为 libpcap 版本太老导致抓包不全的情况,升级一下就好了。

3.2 常用参数:五个核心选项

tcpdump 的参数很多,但日常排错真正高频使用的就五个。你想想看,把这五个记牢了,90% 的场景都能应付。

  • -i:指定网卡。比如 -i eth0,不指定的话默认抓第一个非 lo 的网卡。我习惯显式指定,避免抓到 lo 回环口的数据。
  • -n:不做 DNS 解析。这个参数我几乎每次都加,不加的话 tcpdump 会反向解析 IP 到域名,拖慢速度不说,还容易卡住。
  • -c:抓取指定数量的包后自动退出。比如 -c 100,适合快速验证。
  • -s:抓取每个包的长度,单位字节。默认是 262144,但抓 HTTP 时设成 -s 0 或 -s 1500 就够了,太大浪费内存。
  • -w:把原始包写入文件,后缀通常是 .pcap。配合 -r 读取分析。
  • -r:读取之前保存的 pcap 文件,离线分析。

我的常用组合:

tcpdump -i eth0 -nn -c 1000 -s 0 -w capture.pcap

这条命令的意思是:抓 eth0 网卡,不做 DNS 和端口名解析,抓 1000 个包,每个包抓完整长度,保存到 capture.pcap。

3.3 表达式过滤:精准定位目标流量

不加过滤直接抓包,你会被海量数据淹没。表达式过滤就是你的手术刀。我把它分成三类:

3.3.1 基于协议

tcpdump -i eth0 icmp    # 只抓 ping 包
tcpdump -i eth0 arp     # 只抓 ARP 包
tcpdump -i eth0 tcp     # 只抓 TCP 包

3.3.2 基于 IP 和端口

tcpdump -i eth0 host 192.168.1.1              # 抓与 192.168.1.1 的通信
tcpdump -i eth0 src 10.0.0.1                  # 只抓源 IP 为 10.0.0.1
tcpdump -i eth0 dst 172.16.0.1                # 只抓目标 IP 为 172.16.0.1
tcpdump -i eth0 port 80                       # 只抓 80 端口
tcpdump -i eth0 src port 443                  # 只抓源端口 443

3.3.3 组合过滤(逻辑运算)

tcpdump -i eth0 host 192.168.1.1 and port 80
tcpdump -i eth0 not arp and not icmp
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'   # 只抓 SYN 包
避坑指南:我曾经在排查一个间歇性丢包问题时,直接抓全量包,结果文件太大把磁盘撑爆了。后来学乖了,先用 -c 100 小批量验证过滤条件对不对,再正式抓取。另外,表达式里用 and/or/not 时,最好用引号包起来,避免 shell 解析歧义。

3.4 实战:抓取 HTTP 流量

HTTP 是明文协议,非常适合用来练手。下面我带你走一遍完整流程。

3.4.1 抓取 HTTP 请求和响应

tcpdump -i eth0 -nn -s 0 -A port 80

-A 参数会把包内容以 ASCII 形式打印出来,直接看到 HTTP 的 GET/POST 请求头和响应体。嗯,这里要注意,如果流量很大,屏幕会刷得飞快,建议加上 -c 限制数量。

3.4.2 只抓 HTTP GET 请求

tcpdump -i eth0 -nn -s 0 -A 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420)'

这串数字看着吓人,其实 0x47455420 就是 ASCII 码的 "GET "。说白了,就是在 TCP 载荷里匹配前四个字节是不是 "GET "。我一般把这个命令存成别名,省得每次手敲。

3.4.3 保存到文件并用 Wireshark 分析

tcpdump -i eth0 -nn -s 0 -w http.pcap port 80
# 然后传到本地,用 Wireshark 打开 http.pcap

为什么推荐用 Wireshark 看?因为 tcpdump 的文本输出对 HTTP 请求体和响应体的展示不够友好,尤其是遇到 chunked 编码或 gzip 压缩时,Wireshark 能自动重组和解压,省心很多。

我的习惯:在服务器上用 tcpdump 抓原始包,用 -w 保存,然后 scp 到本地用 Wireshark 分析。这样既不影响服务器性能,又能享受图形界面的便利。

3.5 知识体系总览

下面这张图把 tcpdump 的核心用法串起来了,你可以对照着梳理自己的思路。

tcpdump 核心用法知识体系 tcpdump 安装 常用参数 表达式过滤 实战 HTTP yum / apt apk -i -n -c 协议 / IP / 端口 逻辑组合 -A 查看内容 -w 保存 pcap 核心工作流 安装 → 选择网卡(-i) → 设置过滤条件 → 抓取(-c/-w) → 分析(-r / Wireshark) 排错时先小批量验证过滤条件,再全量抓取保存

3.6 本章小结

tcpdump 的核心用法其实就三件事:选对参数、写好过滤、保存分析。我个人建议你从最简单的 tcpdump -i eth0 -nn port 80 开始练手,慢慢加上 -A 看内容,再尝试组合过滤。等你熟练了,会发现它比任何图形工具都灵活——毕竟,服务器上只有命令行的时候,它就是你唯一的眼睛。