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 精细解读。掌握了抓包,你就拥有了看穿网络问题的「透视眼」,任何「明明发出去了对方说没收到」的扯皮都能一锤定音。

相关推荐
QMCY_jason1 小时前
ubuntu x86_64架构的编译 aarch64架构的程序
linux·运维·ubuntu
分布式存储与RustFS1 小时前
RustFS 该跟 stable 还是 nightly?两条版本线的分工、风险与回退,一张表说清
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
拂拉氏1 小时前
【知识讲解】 Linux进程间通信之管道与共享内存
linux·进程间通信
其实防守也摸鱼1 小时前
Linux文本处理命令理论学习
linux·服务器·前端·数据库·sql·学习·安全
无足鸟ICT1 小时前
【RHCA+】rpm命令(安装、升级、卸载和查询)
linux·运维·服务器
吹什么轩1 小时前
linux系统复习:从冯·诺依曼到操作系统:一切的开场
linux·运维·服务器
程序员-Benothing1 小时前
SSH从入门到精通:密钥登录、config配置、跳板机
linux·运维·服务器·ssh
一条泥憨鱼1 小时前
【计算机网络】| 从 MAC 到 NAT 的跨网段通信全链路
服务器·网络·学习·计算机网络·macos
Elastic 中国社区官方博客2 小时前
Jina AI:Elasticsearch 集成
大数据·运维·人工智能·elasticsearch·搜索引擎·全文检索·jina