凌晨2点,线上服务突然告警,业务反馈接口超时。监控显示服务正常,防火墙没动,配置也没改。你登服务器查了半天,ping得通、telnet端口通、本地curl访问正常,业务就是跑不起来。访问网站的数据包有没有到达服务器、服务器有没有返回数据给客户端不确定。
这种场景我太熟悉了------ping只能告诉你通不通,telnet只能告诉你端口开没开,而tcpdump能让你看到每一个数据包的真实面貌。
今天这篇文章,就把tcpdump的实战用法彻底讲清楚。建议先收藏,需要的时候翻出来对照着练。
一、tcpdump是什么?
tcpdump是Linux/Unix系统下最经典的命令行网络抓包工具,它工作在网络层,能捕获所有流经网卡的数据包。和Wireshark相比,tcpdump是命令行工具,更适合在服务器上直接使用,尤其是在没有图形界面的生产环境中,几乎是唯一选择。
二、安装与基础准备
tcpdump通常预装在大多数Linux发行版中,若未安装可通过包管理器安装:
bash
# CentOS/RHEL/Rocky
yum install -y tcpdump
# Ubuntu/Debian
apt-get install -y tcpdump
安装完成后,可以用 tcpdump --h 查看版本信息。
⚠️ 注意:执行tcpdump通常需要root权限或sudo,因为涉及底层网络访问。
三、核心参数速查表
| 参数 | 含义 | 示例 |
|---|---|---|
-i |
指定网卡接口 | -i eth0、-i any(所有接口) |
-c |
抓取指定数量的包后停止 | -c 10 |
-n |
不解析域名,直接显示IP | 避免DNS查询延迟 |
-nn |
不解析域名和端口号 | 强烈推荐生产环境使用 |
-w |
保存到文件(.pcap格式) | -w capture.pcap |
-r |
从文件中读取抓包数据 | -r capture.pcap |
-v/-vv/-vvv |
输出详细程度递增 | 排查时用-vvv |
-e |
显示数据链路层信息(MAC地址) | |
-X/-XX |
以16进制和ASCII输出包内容 | |
-s |
设置抓包长度,-s 0抓完整包 |
|
-tttt |
显示完整时间戳(精确到毫秒) |
💡 生产环境必加
-nn:一是提升性能,避免DNS查询拖慢抓包;二是显示更直观,看到的IP和端口号就是真实的。
四、过滤表达式:精准捕获目标流量
tcpdump最强大的地方在于过滤表达式,通过它可以从海量流量中精准定位你需要的数据包。
1. 主机过滤
bash
# 捕获与某IP相关的所有流量
tcpdump host 192.168.1.100
# 仅捕获源IP为某地址的包
tcpdump src 192.168.1.100
# 仅捕获目标IP为某地址的包
tcpdump dst 192.168.1.100
2. 端口过滤
bash
# 捕获80端口(HTTP)
tcpdump port 80
# 捕获源端口22(SSH出站)
tcpdump src port 22
# 捕获目标端口443(HTTPS)
tcpdump dst port 443
3. 协议过滤
bash
tcpdump icmp # 捕获ICMP包(Ping)
tcpdump arp # 捕获ARP请求/响应
tcpdump udp # 捕获UDP流量
tcpdump tcp # 捕获TCP流量
4. 逻辑组合(and / or / not)
bash
# 捕获某IP的80端口流量
tcpdump host 192.168.1.100 and port 80
# 捕获80或443端口
tcpdump port 80 or port 443
# 排除ARP包
tcpdump not arp
复杂条件可以用括号分组(需用引号包裹):
bash
tcpdump "(tcp or udp) and (port 80 or 443)"
五、10个最常用的实战命令
1. 查看有哪些网卡可用
bash
tcpdump -D
2. 抓取指定网卡的所有流量
bash
tcpdump -i eth0
执行后会一直抓包,按 Ctrl+C 停止。
3. 抓取指定数量的包(避免刷屏)
bash
tcpdump -c 5 -i eth0
4. 生产环境标准用法(强烈推荐)
bash
tcpdump -i eth0 -nn -c 100
不解析域名和端口,直接显示数字。
5. 显示完整时间戳
bash
tcpdump -i eth0 -tttt -nn
输出格式变为 2025-06-03 13:53:09.891524,排查问题精确到毫秒。
6. 保存抓包结果到文件
bash
tcpdump -i eth0 -w capture.pcap
保存为.pcap格式,可以用Wireshark打开分析。
7. 读取已保存的抓包文件
bash
tcpdump -r capture.pcap
8. 抓取特定主机的SSH流量
bash
tcpdump -i eth0 -nn host 192.168.1.100 and port 22
9. 抓取HTTP GET请求
bash
tcpdump -i eth0 -nn -A port 80 | grep "GET"
10. 抓取DNS查询
bash
tcpdump -i eth0 -nn udp port 53
六、输出结果怎么看?
tcpdump输出的数据包格式一般为:
时间 源IP.端口 > 目标IP.端口 协议详细信息
例如:
11:34:19.760275 IP 192.168.1.100.54321 > 192.168.1.1.80: Flags [S], seq 123456789
Flags [S]表示SYN包(三次握手的开始)Flags [.]表示ACK包Flags [P]表示PUSH数据包Flags [F]表示FIN包(连接关闭)
七、高级技巧
1. 捕获完整数据包
默认tcpdump可能只截取部分内容,用 -s 0 抓取完整包:
bash
tcpdump -i eth0 -s 0 -w full.pcap
2. 显示MAC地址
bash
tcpdump -i eth0 -e -nn
3. 显示绝对序列号(TCP分析用)
bash
tcpdump -i eth0 -S -nn tcp
默认显示相对序列号,加 -S 显示绝对序列号。
4. 抓取特定TCP标志位
bash
# 抓取SYN包
tcpdump 'tcp[tcpflags] & tcp-syn != 0'
# 抓取SYN-ACK包
tcpdump 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0'
5. 结合Wireshark分析
tcpdump在命令行下查看不够直观,最佳实践是:
- 在服务器上用
tcpdump -w file.pcap抓包保存 - 把文件下载到本地
- 用Wireshark打开进行图形化分析
八、实战排障场景
场景一:排查服务"连不上"
在服务器上抓包确认请求是否到达本机:
bash
tcpdump -i eth0 -nn port 8080
如果抓不到任何包,说明请求根本没到服务器,问题在中间链路(防火墙、负载均衡等)。
场景二:定位"防火墙拦截"
在串联设备(如防火墙)两侧同时抓包,若"入接口有包、出接口无包",可判定被策略拦截。
场景三:分析TCP重传问题
bash
tcpdump -r http.pcap 'tcp[tcpflags] & tcp-ack != 0'
重传多表明网络不稳定。
总结
tcpdump是每一个运维、开发和网工都应该掌握的核心工具。记住几个要点:
- 生产环境必加
-nn,避免DNS解析拖慢速度 - 善用过滤表达式,精准定位问题,避免信息过载
- 配合Wireshark使用,命令行抓包 + 图形化分析,事半功倍
- 遇到网络问题先抓包,数据包不会说谎
下次再遇到"服务正常但业务无法访问"的玄学问题,让tcpdump助你看透真相。