运维知识
悠悠
2026年7月20日

tcpdump抓包分析实战:从入门到精通,运维必备的"网络显微镜"

凌晨2点,线上服务突然告警,业务反馈接口超时。监控显示服务正常,防火墙没动,配置也没改。你登服务器查了半天,越查越懵——网络明明是通的,业务就是跑不起来。

这种场景我太熟悉了,ping、telnet、netstat 这些老伙计轮番上场,问题依旧悬而未决。最后往往是抓个包一看,才发现是某个TCP重传、或者某个SYN被默默丢弃了。

今天这篇,把tcpdump的实战用法彻底讲清楚。文章比较长,建议先收藏,需要的时候翻出来对照着练。

认识tcpdump:为什么它这么重要

tcpdump是Linux下最经典的网络抓包工具,它工作在网络层,能捕获所有流经网卡的数据包。

和wireshark相比,tcpdump是命令行工具,更适合在服务器上直接使用,尤其是在没有图形界面的生产环境中,几乎是唯一选择。

我一直把它比作"网络显微镜"——ping只能告诉你通不通,telnet只能告诉你端口开没开,而tcpdump能让你看到每一个数据包的真实面貌。这在排查疑难网络问题时,往往是决定胜负的关键。

基础环境准备

开始之前,先准备两台虚拟机,配置如下:

主机IP系统
rocky-web(服务端)192.168.159.167Rocky Linux 9
rocky-client(客户端)192.168.159.168Rocky Linux 9

安装tcpdump很简单:

# CentOS/RHEL/Rocky
yum install -y tcpdump

# Ubuntu/Debian
apt-get install -y tcpdump

必会的10个核心命令

1. 抓取指定网卡的包

最基础的用法,指定网卡开始抓包:

tcpdump -i ens160

执行后会一直抓取该网卡上的所有流量,按Ctrl+C停止。刚接触tcpdump的同学会一脸懵——屏幕上刷刷刷地滚,根本看不清啥是啥。

别急,下面这些过滤参数会帮你精准定位。

2. 抓取指定数量的包

抓几个包看看就行:

tcpdump -c 5 -i ens160

-c 5 表示只抓5个包就停止,避免一直刷屏看不清。

3. 不解析域名和端口(强烈推荐)

tcpdump -nn -i ens160

nn参数告诉tcpdump不要把IP解析成域名、把端口解析成服务名。这一条在生产环境几乎必加,原因有两个:一是提升性能,避免DNS查询拖慢抓包;二是显示更直观,看到的端口号就是真实的端口号。

4. 显示完整时间戳

tcpdump -tttt -i ens160

默认时间显示是11:34:19.760275这种只有时分秒的格式,加了-tttt后会变成2025-06-03 13:53:09.891524,排查问题时能精确到毫秒。

5. 指定协议类型

# 只抓ARP包
tcpdump -i ens160 arp

# 只抓TCP包
tcpdump -i ens160 tcp

# 只抓UDP包
tcpdump -i ens160 udp

# 只抓ICMP包(ping用的就是这个协议)
tcpdump -i ens160 icmp

排查不同类型的问题,用不同的协议过滤,能极大减少干扰信息。

6. 指定端口

# 抓取80端口的包
tcpdump -i ens160 port 80

# 抓取多个端口
tcpdump -i ens160 'port 80 or port 443'

# 抓取端口范围
tcpdump -i ens160 portrange 8000-9000

注意多条件要用引号包起来,避免shell解析出错。

7. 指定主机(最常用)

# 抓取和特定IP相关的所有包
tcpdump -i ens160 host 192.168.159.168

# 只抓源IP是该IP的包
tcpdump -i ens160 src host 192.168.159.168

# 只抓目标IP是该IP的包
tcpdump -i ens160 dst host 192.168.159.168

8. 组合过滤(实战核心)

单个条件往往不够用,需要组合:

# 抓取从168到167的80端口请求
tcpdump -i ens160 src host 192.168.159.168 and dst host 192.168.159.167 and port 80

# 抓取特定网段
tcpdump -i ens160 net 192.168.159.0/24

# 排除某IP的流量
tcpdump -i ens160 not host 192.168.159.1

支持的逻辑运算符有三个:andornot,组合起来能应对绝大多数场景。

9. 保存到文件(必备技能)

# 保存到pcap文件
tcpdump -i ens160 -w capture.pcap

# 抓100个包就停止
tcpdump -i ens160 -c 100 -w capture.pcap

# 指定端口保存
tcpdump -i ens160 port 80 -w http.pcap

-w参数把原始数据包保存成pcap格式的文件,这个文件可以下载到本地用wireshark打开分析。pcap是抓包分析领域的通用格式,相当于网络流量的"录像"。

生产环境抓包时,建议先保存到文件,不要直接在终端看。原因很简单:终端刷屏太快根本看不清,而且文件可以反复回看。

10. 读取pcap文件

tcpdump -r capture.pcap
tcpdump -r capture.pcap host 192.168.159.168

-r参数用于读取之前保存的pcap文件,可以加上过滤条件做精确分析。这个功能在排查历史问题、回溯故障时特别有用。

进阶用法:看懂的"钥匙"

光会抓还不够,还要看得懂抓出来的内容。下面我用一个真实场景,把包的结构讲透。

场景:抓取HTTP请求

在167上部署nginx,修改index.html:

<!DOCTYPE html>
<html>
<head>
<title>Test!</title>
</head>
<body>
<p><em>Hello the cruel world.</em></p>
</body>
</html>

在168上发起请求:

while true; do curl 192.168.159.167; sleep 3; done

在167上抓包:

tcpdump -i ens160 -nn -tttt -vvv dst 192.168.159.168 and port 80

参数说明:

  • -nn:不解析域名和端口
  • -tttt:显示完整时间戳
  • -vvv:显示最详细的信息

抓出来的包长这样:

2025-06-03 16:41:03.735170 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.159.167.80 > 192.168.159.168.48312: Flags [S.], cksum 0xc0cf (incorrect -> 0xf152), seq 1443628272, ack 853270288, win 31856, options [mss 1460,sackOK,TS val 1359281735 ecr 197104783,nop,wscale 7], length 0

我来拆解一下这段信息到底在说啥:

  • 时间戳:2025-06-03 16:41:03.735170
  • 协议类型:IP(IPv4)
  • TOS字段:0x0(服务类型)
  • TTL:64(生存时间,每经过一个路由器减1)
  • 包ID:0
  • 标志位[DF] 表示不分片
  • 协议:TCP (6)
  • 包长度:60字节

源地址到目标地址这一段:

192.168.159.167.80 > 192.168.159.168.48312

意思是167的80端口,发往168的48312端口。> 代表数据流向。

Flags [S.] 是最关键的部分——这是TCP标志位:

  • S = SYN(建立连接)
  • . = ACK(确认)
  • P = PSH(推送数据)
  • F = FIN(关闭连接)
  • R = RST(重置连接)

[S.] 表示这是SYN+ACK包,是TCP三次握手的第二阶段。

后面跟着 seq 1443628272(序列号)、ack 853270288(确认号)、win 31856(窗口大小)等,这些是TCP协议的核心字段。

抓取完整HTTP内容

想看到HTTP请求和响应的明文内容,用-X参数:

tcpdump -i ens160 -nn -tttt -XX dst 192.168.159.168 and port 80

-X参数会以十六进制和ASCII两种形式显示包内容,能直接看到HTTP协议头:

HTTP/1.1 200 OK
Server: Tengine/3.1.0
Date: Tue, 03 Jun 2025 08:41:03 GMT
Content-Type: text/html
Content-Length: 121
Last-Modified: Tue, 03 Jun 2025 08:05:59 GMT
Connection: keep-alive

是不是很神奇?连HTTP响应头都能完整看到。HTTPS是加密的看不到,但HTTP的明文内容能看个底朝天——这也是为什么HTTP不适合传输敏感信息。

实战案例:TCP三次握手分析

理解TCP三次握手是看包的基础。我把一个完整的HTTP请求包序列拆解一下:

1. 192.168.159.167.80 > 192.168.159.168.48312: Flags [S.], seq X, ack Y+1    # 第二次握手
2. 192.168.159.167.80 > 192.168.159.168.48312: Flags [.], ack Y+1             # 第三次握手
3. 192.168.159.167.80 > 192.168.159.168.48312: Flags [P.], seq 1:239           # 发送数据
4. 192.168.159.167.80 > 192.168.159.168.48312: Flags [F.], seq 360             # 关闭连接

注意这里没有第一次握手,因为用的是dst 192.168.159.168,过滤的是发给168的包,第一次握手是168发给167的。

完整的TCP连接生命周期:

  • SYN → 客户端请求建立连接
  • SYN+ACK → 服务端同意建立
  • ACK → 客户端确认
  • PSH+ACK → 传输数据
  • FIN+ACK → 关闭连接

故障信号识别

  • 只有SYN没有SYN+ACK → 服务端无响应(端口未开/防火墙拦截)
  • 大量SYN+无ACK → 可能是SYN Flood攻击
  • 大量TCP重传(Retransmission)→ 网络丢包严重
  • RST包异常增多 → 端口被强制关闭

高级过滤:按标志位抓包

按TCP标志位过滤是排查特定问题的高级技巧:

# 只抓SYN包(排查SYN Flood)
tcpdump -i ens160 'tcp[tcpflags] & tcp-syn != 0'

# 只抓SYN+ACK包
tcpdump -i ens160 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'

# 只抓RST包(排查异常重置)
tcpdump -i ens160 'tcp[tcpflags] & tcp-rst != 0'

# 抓SYN但排除SYN+ACK
tcpdump -i ens160 'tcp[tcpflags] & tcp-syn != 0 and not tcp[tcpflags] & tcp-ack'

syn_flood攻击的特征就是短时间内大量SYN包但没有对应的ACK,用这个过滤条件能快速识别。

真实故障案例:防火墙导致服务不通

某天收到反馈,访问Web服务提示"无法连接服务器",但服务端进程正常。常规检查全部正常,就是连不上。

用tcpdump在服务端抓包:

tcpdump -i eth0 port 8080 -w web_capture.pcap

下载到本地用wireshark分析,发现客户端SYN包已经到了服务端,但服务端没有任何响应

同步在客户端抓包,看到客户端一直在重传SYN(1s → 2s → 4s 指数退避),最终超时。

最后查防火墙规则,发现有人加了这条:

iptables -A INPUT -p tcp --dport 8080 -j DROP

防火墙把8080端口的包默默丢弃了,连个RST都不回,所以客户端只能干等。临时删除规则后,TCP三次握手瞬间正常。

这个案例给我的启示是:用tcpdump能"看到"网络层到底发生了什么,比靠猜要靠谱得多。ping和telnet只能告诉你表象,抓包才能看到真相。

配合Wireshark做深度分析

tcpdump在服务器上抓包很方便,但分析起来不如wireshark直观。最佳实践是:用tcpdump抓包保存成pcap文件,下载到本地用wireshark分析

wireshark的几个神仙功能:

1. Follow TCP Stream(追踪TCP流)

右键 → Follow → TCP Stream,能把一次TCP会话的所有数据按顺序完整展示出来,不用自己拼接。

2. 过滤器语法

wireshark的过滤器比tcpdump更强大,比如:

# 只看重传
tcp.analysis.retransmission

# 只看丢包
tcp.analysis.lost_segment

# 只看乱序
tcp.analysis.out_of_order

# 只看RST
tcp.flags.reset == 1

3. Statistics → Conversations

看所有会话的统计信息,包括包数、字节数、重传率,一眼就能定位异常会话。

生产环境抓包的注意事项

最后说几个容易踩的坑,都是我用血泪换来的经验:

1. 抓包会消耗CPU

高流量场景下抓包非常消耗CPU资源,建议在低峰期抓,或者用-c限制包数量。

2. 磁盘空间要预留

一个高流量的pcap文件可能几分钟就几个G,抓包前先df -h看看磁盘。我曾经因为没注意磁盘,pcap文件把根分区撑爆,机器直接挂了。

3. 多网卡机器要指定网卡

服务器一般有多块网卡(业务网卡、管理网卡、存储网卡),用-i指定正确的网卡,不然可能抓到一堆无关流量。

4. 权限问题

tcpdump需要root权限或CAP_NET_RAW能力。普通用户执行会报permission denied

5. 容器内抓包要特殊处理

在K8s容器里抓包比较麻烦,常见做法是用kubectl debug注入一个带tcpdump的临时容器,官方文档有详细的操作步骤。

6. 大文件用-W-C切割

# 每个文件100MB,最多保留10个文件
tcpdump -i eth0 -w capture.pcap -C 100 -W 10

-C 100表示每个文件100MB,-W 10表示最多保留10个文件,避免磁盘被撑爆。

7. 性能优化参数

# 增大缓冲区到2MB
tcpdump -i eth0 -B 2048 port 80

# 抓完整包(不截断)
tcpdump -i eth0 -s 0 port 80

默认-s 0只抓每个包的前68字节,看不到完整内容。-s 0抓完整包,虽然更耗资源,但能看到所有细节。

我的tcpdump常用命令速查

最后整理一份我日常用得最多的命令清单,建议保存:

# 1. 基础抓包
tcpdump -i eth0                           # 抓所有包
tcpdump -i eth0 -nn                       # 不解析域名端口
tcpdump -i eth0 -c 100                    # 只抓100个包
tcpdump -i eth0 -tttt                     # 显示完整时间戳

# 2. 按条件过滤
tcpdump -i eth0 host 192.168.1.1          # 指定主机
tcpdump -i eth0 port 80                   # 指定端口
tcpdump -i eth0 tcp                       # 指定协议
tcpdump -i eth0 'port 80 and host 192.168.1.1'  # 组合条件

# 3. 文件操作
tcpdump -i eth0 -w file.pcap              # 保存到文件
tcpdump -r file.pcap                      # 读取文件
tcpdump -i eth0 -w file.pcap -C 100 -W 5  # 文件切割

# 4. 高级过滤
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'  # SYN包
tcpdump -i eth0 'tcp[tcpflags] & tcp-rst != 0'  # RST包

# 5. 显示详细信息
tcpdump -i eth0 -v                        # 详细
tcpdump -i eth0 -vv                       # 更详细
tcpdump -i eth0 -vvv                      # 最详细
tcpdump -i eth0 -X                        # 显示包内容(十六进制+ASCII)
tcpdump -i eth0 -s 0 -X                   # 显示完整包内容

结语

tcpdump看着简单,但真要用好,需要大量的实战积累。建议大家搭个测试环境,亲手抓一下各种场景的包

  • 正常HTTP请求的包长啥样
  • TCP三次握手的完整过程
  • 四次挥手的包序列
  • 连接被重置时的RST包
  • 网络丢包时的重传包

看多了,下次遇到问题就能一眼看出包里的异常。抓包分析能力,是运维工程师的核心竞争力之一,也是面试的高频考点。

如果觉得本文有用,欢迎点赞、在看、转发三连,让更多运维兄弟看到。

关注公众号【耕云躬行录】,回复"tcpdump"领取我整理的tcpdump速查手册(含常用命令、过滤表达式、故障排查清单)

个人博客:躬行笔记

文章目录

博主介绍

热爱技术的云计算运维工程师,Python全栈工程师,分享开发经验与生活感悟。
欢迎关注我的微信公众号@运维躬行录,领取海量学习资料

微信二维码