如何用 tcpdump 抓包排查网络问题?
简化版
tcpdump 是 Linux 上最常用的命令行抓包工具,用来在没有图形界面的服务器上抓取和查看网络数据包。核心用法是 tcpdump -i 网卡 过滤表达式,比如 tcpdump -i eth0 host 1.2.3.4 and port 80。它的精髓是用过滤表达式精准抓你要的包(按主机 host、端口 port、协议 tcp/udp 过滤),避免海量无关流量。常配合 -w 文件.pcap 把包存下来,再拖到 Wireshark 里做可视化分析。它能回答「包到底有没有发出去/收到、内容是什么、TCP 握手成没成」这类抓心的问题。
详细版
基本结构:tcpdump [选项] [过滤表达式]
常用选项:
| 选项 | 作用 |
|---|---|
-i eth0 | 指定网卡(-i any 抓所有网卡) |
-n | 不反解析 IP 为域名(更快);-nn 连端口也不解析 |
-w file.pcap | 把原始包写入文件(供 Wireshark 分析) |
-r file.pcap | 读取之前抓的文件 |
-c 100 | 抓够 100 个包就停 |
-v / -vv | 更详细的输出 |
-A | 以 ASCII 显示包内容(看 HTTP 明文) |
-X | 以十六进制 + ASCII 显示 |
-s 0 | 抓完整包(旧版默认截断,现代版默认已是全长) |
过滤表达式(BPF 语法):
tcpdump -i eth0 host 1.2.3.4 # 抓和某 IP 相关的包
tcpdump -i eth0 src 1.2.3.4 # 只抓源 IP
tcpdump -i eth0 dst 1.2.3.4 # 只抓目的 IP
tcpdump -i eth0 port 80 # 抓 80 端口
tcpdump -i eth0 tcp # 只抓 TCP
tcpdump -i eth0 host 1.2.3.4 and port 80 # 组合:and / or / not
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' # 只抓 SYN 包
典型排查命令:
# 抓某客户端访问本机 80 端口的包,存文件供 Wireshark 分析
tcpdump -i eth0 -nn host 1.2.3.4 and port 80 -w web.pcap
完整版教学
一、为什么要抓包:眼见为实
前面的工具(ping、telnet、curl)都是「间接推断」网络状态,而抓包是「直接看真相」——网络上到底发了什么包、收了什么包、内容是什么,一览无余。当遇到「玄学问题」时(明明配置对了却不通、偶发丢包、协议交互异常),抓包往往是唯一能一锤定音的手段。它能回答这些别的工具答不了的问题:
- 请求包到底发出去了没有?对方回了没有?
- TCP 三次握手成功了吗?卡在哪一步?
- 是谁先发的 RST(谁把连接重置了)?
- 传输的数据内容到底是什么(HTTP 明文、异常字段)?
tcpdump 就是 Linux 服务器上做这件事的标准工具——纯命令行、几乎所有发行版都有,特别适合没有图形界面的生产服务器。
二、抓包的灵魂:过滤表达式
服务器上流量巨大,不加过滤会瞬间刷屏、根本没法看。所以 tcpdump 用得好不好,全看**过滤表达式(BPF,Berkeley Packet Filter)**用得精不精。核心几类:
- 按主机:
host 1.2.3.4(相关的都抓)、src 1.2.3.4(只抓源)、dst 1.2.3.4(只抓目的)。 - 按端口:
port 80、src port 80、dst port 80。 - 按协议:
tcp、udp、icmp、arp。 - 逻辑组合:
and(与)、or(或)、not(非),如host 1.2.3.4 and port 443 and tcp。
排障时先想清楚「我要看谁和谁、哪个端口、什么协议」的包,再拼表达式,一下就把海量流量缩到几条关键包。这是使用 tcpdump 的第一功力。
三、读懂输出:一行就是一个包
tcpdump 默认每行打印一个包,学会读它:
15:04:23.123456 IP 1.2.3.4.54321 > 5.6.7.8.80: Flags [S], seq 1000, win 64240, length 0
└时间戳 └源IP.源端口 └>目的IP.端口 └TCP标志 └序列号 └窗口 └数据长度
- 时间戳:精确到微秒,用来算包之间的时间间隔(判断延迟/超时)。
源 > 目的:>表示方向,源 IP.端口 → 目的 IP.端口。Flags [...]:TCP 标志位,这是判断握手/挥手/异常的关键:[S]= SYN(发起连接)[S.]= SYN+ACK(.代表 ACK)[.]= ACK[P.]= PSH+ACK(带数据)[F.]= FIN(关闭)[R]= RST(重置连接——出问题的信号)
- seq / ack / win / length:序列号、确认号、窗口大小、数据长度。
四、实战:判断三次握手成没成
抓包最经典的用途之一是看 TCP 三次握手是否成功。正常握手在 tcpdump 里长这样:
IP A.54321 > B.80: Flags [S] ← ① A 发 SYN
IP B.80 > A.54321: Flags [S.] ← ② B 回 SYN+ACK
IP A.54321 > B.80: Flags [.] ← ③ A 回 ACK,握手完成
对照实际抓到的包就能定位卡在哪:
- 只看到 A 发
[S],没有 B 的[S.]→ 对方没回应:服务没起、端口没监听、或防火墙把 SYN 丢了(呼应 telnet 的 timeout)。 - A 发
[S],B 立刻回[R](RST) → 对方主机在,但端口没服务,直接拒绝(呼应 telnet 的 refused)。 - 握手成功后突然出现
[R]→ 连接被某一方主动重置,要查是谁、为什么(超时、程序异常、被中间设备切断)。
**「是谁先发的 RST」**是排查连接莫名中断的关键,抓包能明确看到方向,这是其他工具给不了的。
五、抓下来交给 Wireshark:分工协作
tcpdump 在命令行看单个包还行,但要分析一整段交互、追踪一条 TCP 流、看统计,命令行就吃力了。标准做法是分工:
# 在服务器上用 tcpdump 抓包并存成 pcap 文件
tcpdump -i eth0 -nn host 1.2.3.4 and port 443 -w /tmp/capture.pcap
然后把 capture.pcap 下载到本地,用 Wireshark 打开做可视化分析(着色、追踪流、过滤、统计、看重传)。tcpdump 负责「在服务器上抓」,Wireshark 负责「在本地深度分析」,两者是黄金搭档。
注意:
.pcap是通用抓包格式,tcpdump、Wireshark、tshark 都能读写,所以能无缝传递。
六、抓包的注意事项
- 需要 root 权限:抓包要访问网卡底层,一般得
sudo。 - 性能影响:高流量下抓包有开销,务必用过滤表达式收窄范围、用
-c限制数量或及时停止,别在繁忙生产机上无过滤裸抓。 - 加密流量看不到内容:HTTPS 抓到的是加密后的密文(能看到 TCP/TLS 握手过程,看不到 HTTP 明文),要看明文得在应用层或有密钥的情况下解密。
- 隐私与合规:抓包可能抓到敏感数据(明文密码、用户信息),只在授权范围内抓,妥善处理抓包文件。
七、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| 抓包对象 | 网卡、主机、端口、协议 |
| 过滤语法 | host、port、tcp、udp、and/or/not |
| 分析重点 | 三次握手、重传、RST、TLS 握手、HTTP 头 |
tcpdump -i eth0 host 10.0.0.5 and port 443 -nn
tcpdump -i any tcp port 8080 -w out.pcap
tcpdump -r out.pcap -nn 'tcp[tcpflags] & tcp-syn != 0'
tcpdump 先用精确过滤缩小范围,再保存 pcap 给 Wireshark 深看,效率最高。
- 误区:抓 any 网卡就总是最好。
any方便但链路层信息可能不完整,分析 MAC/VLAN 时应抓具体网卡。 - 误区:没抓到包就说明客户端没发。 可能抓错网卡、命名空间、容器网络、过滤条件或方向。
- 误区:抓包可以直接看到 HTTPS 明文。 TLS 加密后只能看到握手、证书、SNI 等部分信息和加密后的应用数据。
- 追问:为什么常加
-nn? 避免反向 DNS 和服务名解析干扰输出,也减少额外查询。 - 追问:如何判断 TCP 重传? 看相同序列号数据重复发送、ACK 未推进,Wireshark 也会标记重传。
- 追问:抓包文件为什么要注意脱敏? pcap 可能包含 Cookie、Token、内网 IP、证书信息和业务数据。
八、加强记忆
tcpdump 是 Linux 命令行抓包工具,用来「直接看网络上真实收发了什么」。用法 tcpdump -i 网卡 -nn 过滤表达式,灵魂是过滤表达式(host/port/tcp + and/or/not)收窄流量。读输出看方向(源 > 目的)和 Flags:[S]SYN [S.]SYN+ACK [.]ACK [F.]FIN [R]RST(异常信号)——据此判断三次握手成没成、是谁发的 RST。深度分析用 -w file.pcap 存下来丢 Wireshark。注意:需 root、HTTPS 只能看到加密握手、务必过滤别裸抓。