Linux抓包分析教程:tcpdump、Wireshark、tshark实战

日志显示请求发出去了,对方却说没收到;接口偶发超时,没有任何报错;明明连上了,数据却对不上。这类「看不见的传输层问题」,用再多的应用日志也定位不了,只能靠抓包------把网线上真正流动的字节一个一个抓下来看。这一篇讲透 Linux 抓包三件套:tcpdump 命令行抓、tshark 命令行分析、Wireshark 图形化细看,从语法到实战过滤器一次讲清。

一、抓包能解决什么

抓包是网络排障的「终极手段」,因为它能回答其他工具答不了的问题:

  • 请求到底发出去了没有?(还是应用根本没发)
  • 对方回了什么?(RST?超时?错误码?)
  • 重传、乱序、丢包发生在哪一段?
  • TLS 握手卡在哪一步?
  • 数据内容和长度是否和服务端预期一致?

一句话:抓包是站在「网线视角」看问题,屏蔽了应用层的所有猜测。

二、tcpdump:命令行抓包主力

tcpdump 几乎每台 Linux 都自带或可秒装,是服务器抓包的绝对主力。

安装

复制代码
sudo apt install tcpdump -y      # Ubuntu
sudo dnf install tcpdump -y      # Rocky/CentOS

语法格式

复制代码
tcpdump [选项] [过滤表达式]

常用参数

参数 说明
-i 网卡 指定网卡(any 表示所有)
-nn 不解析主机名和端口名(保持数字,快且准)
-c N 抓 N 个包后停止
-w 文件 保存为 pcap 文件(供 Wireshark 分析)
-r 文件 读取 pcap 文件
-s 长度 抓取每个包的前 N 字节(-s0 抓全部)
-A 以 ASCII 显示内容(看明文 HTTP/Redis)
-X 同时显示十六进制和 ASCII
-v/-vv/-vvv 越来越详细的输出
-e 显示链路层(MAC)信息
-l 行缓冲,配合管道实时看

基础示例

看某网卡上的所有流量:

复制代码
sudo tcpdump -i eth0 -nn

10:30:01.123 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S], seq 123456, win 64240, length 0
10:30:01.145 IP 93.184.216.34.80 > 192.168.1.10.54321: Flags [S.], seq 654321, ack 123457, win 65535, length 0

抓 100 个包就停,保持数字显示:

复制代码
sudo tcpdump -i eth0 -nn -c 100

让 tcpdump 抓包不影响生产

抓包会占用 CPU 和磁盘,生产环境务必加限制:

复制代码
# 只抓 1000 个包、每包前 96 字节、写入文件
sudo tcpdump -i eth0 -nn -c 1000 -s 96 -w /tmp/cap.pcap

存成 pcap 文件后,可以下载到本地用 Wireshark 慢慢分析,避免在服务器上做重活。

三、过滤器(BPF):只抓你关心的

无过滤抓包等于大海捞针。tcpdump 用 BPF(Berkeley Packet Filter) 语法做过滤,核心是「类型 + 方向 + 协议/端口」。

基础过滤

复制代码
# 按主机
tcpdump host 192.168.1.100
# 按源/目的
tcpdump src 192.168.1.100
tcpdump dst 192.168.1.100
# 按端口
tcpdump port 80
tcpdump src port 443
# 按协议
tcpdump tcp
tcpdump udp
tcpdump icmp

组合过滤(and / or / not)

复制代码
# 与某主机 80 端口的通信
tcpdump -nn host 192.168.1.100 and port 80

# 排除 SSH,避免抓到自己
tcpdump -nn not port 22

# 某网段访问 443
tcpdump -nn net 192.168.1.0/24 and port 443

# 两个条件任一
tcpdump -nn port 80 or port 443

进阶:按 TCP 标志位过滤

复制代码
# 只抓 SYN 包(看连接建立)
tcpdump -nn 'tcp[tcpflags] & tcp-syn != 0'

# 只抓 RST 包(看连接被拒)
tcpdump -nn 'tcp[tcpflags] & tcp-rst != 0'

# 抓 FIN(看连接关闭)
tcpdump -nn 'tcp[tcpflags] & tcp-fin != 0'

按包大小过滤(找大包、异常包)

复制代码
tcpdump -nn 'greater 1000'     # 大于 1000 字节
tcpdump -nn 'less 100'         # 小于 100 字节

四、tcpdump 实战场景

场景 1:抓 HTTP 请求内容

复制代码
sudo tcpdump -i eth0 -nn -A -s0 port 80

-A 显示 ASCII 内容,能看到明文 HTTP 请求头和响应,适合排查「请求发没发、返回什么」。

场景 2:抓 Redis/Memcached 等明文协议

复制代码
sudo tcpdump -i eth0 -nn -A -s0 port 6379

能看到 Redis 命令原文,快速确认客户端发了什么。

场景 3:排查连接超时

复制代码
# 抓 SYN 包,看有没有回 SYN-ACK
sudo tcpdump -nn -c 20 'tcp[tcpflags] & tcp-syn != 0 and host 10.0.0.5'
  • 有 SYN 没 SYN-ACK → 对方没回(防火墙 DROP 或服务没监听)
  • 有 SYN 有 RST → 对方端口没开
  • 有 SYN 有 SYN-ACK 没 ACK → 客户端侧问题

场景 4:定位重传

复制代码
sudo tcpdump -nn -i eth0 -w /tmp/retrans.pcap port 443

下载后用 Wireshark 看 tcp.analysis.retransmission 过滤,或直接用 tshark 统计。

场景 5:抓特定 IP 的 DNS 查询

复制代码
sudo tcpdump -nn -i any port 53 and host 192.168.1.10

五、tshark:命令行的 Wireshark

tshark 是 Wireshark 的命令行版,不需要 GUI,能在服务器上直接分析 pcap,还能统计。

安装

复制代码
sudo apt install tshark -y      # Ubuntu
sudo dnf install wireshark-cli -y   # Rocky/CentOS

常用参数

参数 说明
-i 网卡 实时抓包
-r 文件 读 pcap 文件
-Y 过滤 显示过滤(Wireshark 语法)
-T fields -e 字段 输出指定字段
-z 统计 做统计(如 -z io,stat,1)
-V 显示包的全部协议树

示例

读取 pcap 并按条件过滤:

复制代码
tshark -r /tmp/cap.pcap -Y "http.request" -T fields -e http.host -e http.request.uri

api.example.com	/v1/users
api.example.com	/v1/orders

统计重传:

复制代码
tshark -r /tmp/cap.pcap -Y "tcp.analysis.retransmission" | wc -l

看每秒包数:

复制代码
tshark -r /tmp/cap.pcap -z io,stat,1

统计 TCP 连接耗时:

复制代码
tshark -r /tmp/cap.pcap -Y "tcp.flags.syn==1 && tcp.flags.ack==0" -T fields -e ip.src -e ip.dst -e tcp.dstport

tshark 的定位

  • 服务器无 GUI → 用 tshark 命令行抓和初步分析。
  • 需要深度交互 → tcpdump/tshark 抓成 pcap,下载到本地用 Wireshark。

六、Wireshark:图形化精细分析

Wireshark 是抓包分析的黄金标准,图形界面、协议解码、流量统计一应俱全。服务器上一般不装,而是在本地分析别处抓来的 pcap。

基本工作流

  1. tcpdump -w 在服务器抓包。
  2. 下载 pcap 到本地。
  3. Wireshark 打开,用显示过滤器缩小范围。

常用显示过滤器

过滤器 作用
ip.addr == 192.168.1.100 某 IP 相关
tcp.port == 80 某端口
http 所有 HTTP
http.request.method == "POST" POST 请求
tcp.analysis.retransmission 重传包
tcp.analysis.zero_window 零窗口(接收方处理不过来)
tcp.flags.reset == 1 RST 包
dns DNS 查询
tls.handshake.type == 1 TLS ClientHello

三个最有用的功能

  1. Follow TCP Stream(右键 → Follow → TCP Stream):把一条连接的完整对话拼出来,看 HTTP 请求响应最直观。
  2. Statistics → Conversations:按会话看流量排名,找占带宽的元凶。
  3. Expert Information(分析 → 专家信息):自动标出重传、丢包、乱序等异常。

七、抓包分析的通用技巧

  • 先缩小范围:用过滤器抓「关注的 IP + 端口」,别抓全量。
  • pcap 会很大 :加 -c 限包数、-s 限长度,别把磁盘写满。
  • 对时间:抓包时间戳和应用日志时间对齐,才能把「日志报错」和「网络包」对应起来。
  • 看序列号:TCP 序列号能揭示重传、乱序、丢包。
  • 看 RTT :tcp.analysis.ack_rtt 反映真实往返延迟。
  • 关注标志位:SYN/SYN-ACK/ACK/FIN/RST 组合能还原连接的生命周期。

八、⚠️ 常见错误

  1. 抓包不加限制写满磁盘 。生产抓包必须 -c+-s+-w,或限制时间。
  2. 抓包不过滤抓到一堆无关流量。务必用 BPF 过滤到具体 IP/端口。
  3. 在错误的网卡上抓 。多网卡机器要选对 -i,或用 any。
  4. 忘了权限 。抓包需要 root 或 CAP_NET_RAW,普通用户会报 permission denied。
  5. 看到重传就以为网络坏。少量重传正常,大量重传(>1%)才说明链路有问题。
  6. 忽略抓包本身的影响 。高流量下抓包会掉包,tcpdump 报 packets dropped by kernel 时抓到的数据不完整,要调大 buffer(-B)或减少过滤范围。
  7. 加密流量看不懂就放弃 。TLS 流量看不到内容,但握手过程、RST、重传、时延仍可分析,这些往往才是问题所在。
  8. 在容器里抓宿主网卡的包。容器网络要进对应的 network namespace 抓。

九、原理探究:一次三次握手的抓包实录

抓包最有价值的能力是「读懂连接的生命周期」。用一次 TCP 三次握手 + 数据传输 + 四次挥手为例:

三次握手

复制代码
1  10.0.0.5.54321 > 10.0.0.9.80: Flags [S], seq 1000, win 64240
2  10.0.0.9.80 > 10.0.0.5.54321: Flags [S.], seq 5000, ack 1001, win 65535
3  10.0.0.5.54321 > 10.0.0.9.80: Flags [.], ack 5001, win 64240
  • 包 1:客户端发 SYN,seq=1000
  • 包 2:服务端回 SYN+ACK(S.),ack=1001(1000+1),seq=5000
  • 包 3:客户端回 ACK(.),ack=5001(5000+1)

记住规律:ack = 对方 seq + 1(SYN 和 FIN 各占一个序号)。

数据传输

复制代码
4  10.0.0.5.54321 > 10.0.0.9.80: Flags [P.], seq 1001:1501, ack 5001, length 500
5  10.0.0.9.80 > 10.0.0.5.54321: Flags [.], ack 1501, win 65535
  • 包 4:客户端发 500 字节数据(P. 表示 PSH+ACK),seq 1001~1501
  • 包 5:服务端 ACK,确认收到 1501

四次挥手

复制代码
6  10.0.0.5.54321 > 10.0.0.9.80: Flags [F.], seq 1501, ack 5001
7  10.0.0.9.80 > 10.0.0.5.54321: Flags [.], ack 1502
8  10.0.0.9.80 > 10.0.0.5.54321: Flags [F.], seq 5001, ack 1502
9  10.0.0.5.54321 > 10.0.0.9.80: Flags [.], ack 5002
  • 包 6/7:客户端发 FIN,服务端 ACK
  • 包 8/9:服务端发 FIN,客户端 ACK

从抓包能看出什么异常

现象 抓包特征 含义
连接被拒 SYN → RST 端口没开
连接超时 SYN →(无回应) 防火墙 DROP 或不可达
服务端处理慢 收到请求后长时间无 ACK/响应 应用处理慢
网络丢包 重复的 seq、retransmission 链路丢包
接收方满 zero_window 接收方来不及处理
半开连接 大量 SYN 无后续 SYN Flood 或扫描

抓包的底层原理

tcpdump 使用 libpcap 库,通过内核的 AF_PACKET 套接字 直接从数据链路层复制数据包。这就是为什么它能抓到「网线上真实的字节」------它绕过了 TCP/IP 协议栈的处理,直接看原始帧。也正因为抓的是链路层,它能看到 TCP/IP 层不会暴露的问题(如 MAC 冲突、ARP 异常)。

理解抓包的层次,就知道它的边界:在容器/虚拟化环境里,数据包会经过多张虚拟网卡,要在正确的 namespace 和网卡上抓,才能看到你要的那段流量。

十、抓包速查表

复制代码
# 快速抓 HTTP 内容
sudo tcpdump -i eth0 -nn -A -s0 port 80

# 抓包存文件
sudo tcpdump -i eth0 -nn -c 1000 -s0 -w /tmp/cap.pcap

# 抓 SYN/RST 诊断连接
sudo tcpdump -nn 'tcp[tcpflags] & (tcp-syn|tcp-rst) != 0'

# 读文件 + 过滤(tshark)
tshark -r cap.pcap -Y "http.request" -T fields -e http.host -e http.request.uri

# 统计重传
tshark -r cap.pcap -Y "tcp.analysis.retransmission" | wc -l

# 抓指定主机+端口
sudo tcpdump -nn host 10.0.0.5 and port 443 -w /tmp/tls.pcap

抓包是「用真相终结猜测」的手段。记住主线:tcpdump 抓、BPF 过滤、tshark 命令行分析、Wireshark 精细解读。掌握了抓包,你就拥有了看穿网络问题的「透视眼」,任何「明明发出去了对方说没收到」的扯皮都能一锤定音。

相关推荐
且从容.1 小时前
ubuntu安装flink
linux·ubuntu·flink
数字新视界3 小时前
动环监控信创适配在智能机房管理中的应用价值与未来展望
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
爱和冰阔落3 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨3 小时前
WSL2的安装与使用
linux·wsl
微小的鱼3 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng3 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮4 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹4 小时前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器
孙克旭_4 小时前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_5 小时前
云原生基础之Containerd容器运行时
运维·云原生