网络抓包工具应用 Cookbook

Table of Contents

最后更新:2019-05-27

1 Wireshark

如何捕获到 FCS ?

并不是所有网卡都可以捕获到,尝试:

sudo ethtool -K eth0 rx-fcs on  # 捕获 FCS
sudo ethtool -K eth0 rx-all on  # 接受 FCS 校验失败的帧

linux cooked 是什么?

有些包的以太网字段会出现“linux cooked”,是因为有一些包底层没有用到以太网帧,一般监听到回环的网卡会出现这个现象,由 Wireshark 虚拟的包。

1.1 过滤器应用

Wireshark 使用了两种过滤器,捕获过滤器和显示过滤器:

  • 捕获过滤器使用的 BPF 语法,底层调用了 libcap/Winpcap;
  • 显示过滤器支持更高级的语法,用来分析已捕获到的流量。如,按 IP 过滤:
ip.dst_host matches "192.168.156.\d{0,1}"
ip.src_host matches "192.168.156.\d{0,1}"

1.2 IP 协议

关于 Fragment Offset 显示问题

一个分片后的数据包,在 Wireshark 2.4.2 中显示为 1480,如图:

ip1.png

在新版本(2.6.2)中却显示的 185,如图:

ip2.png

因为 1480 = 185 × 8,根据 RFC 791 定义:

The fragment offset is measured in units of 8 octets (64 bits).  The first fragment has offset zero.

所以这里显示的 185。

1.3 TCP 协议

为什么出现“ACKed segment that wasn't captured”?

如果看到少量的“ACKed segment that wasn't captured”字样,多数情况是因为在 TCP 三次会话握手过程中才开启的抓包,导致捕获的会话数据不完整,可以进一步用过滤器分析会话数据来确认情况。

如何过滤出重传(Retransmission)的 TCP 包,便于分析和哪些 IP 通信有问题

tcp.analysis.retransmission

2 tcpdump

常用参数:

参数 含义
-i 指定网络接口,如:-i any 或者 -i eth0
-w 把捕获的内容写入到文件中
-r 读取 pcap 文件
-n 禁用 DNS 反向查询 IP
-nn 禁用 DNS 反向查询 IP、端口号以数字显示(而不是服务名)
-X 打印包的详细内容,十六进制 + ASCII 显示

按包大小捕获:

tcpdump greater 128 # 捕获大于128字节的包

tcpdump less 128 # 捕获小于128字节的包

捕获与 www.shellcodes.org 之间的通信包(TCP、UDP 和 ICMP):

tcpdump host www.shellcodes.org

src 和 dst 关键字:

src 表示源地址,dst 表示目标地址:

tcpdump dst www.shellcodes.org

表示捕获所有发往给 www.shellcodes.org 的数据包。

net 关键字:

支持 CIDR:

tcpdump net 10.8.14.0/24

port 和 portrange 关键字:

tcpdump port 3389

tcpdump portrange 1024-1028 # portrange 指定端口范围

捕获 HTTP 数据:

tcpdump -A port 80 and host www.shellcodes.org

3 其他工具

Q:作为 Emacs 重度粉丝,可以用 Emacs 分析 pcap 文件吗?

A:安装 pcap-mode 即可。不过我倾向于命令行用 tshark、tcpdump,图形化用 Wireshark,专业工具干专业事,pcap-mode 只用来临时方便看看数据包而以。

4 综合分析

4.1 分析响应速度慢

某个 API 接口响应速度时快时慢,这个 API 也同时调用了多个其他服务器的接口,我怀疑就是其中某个接口响应太慢所致,为了快速定位原因,我在 API 的生产环境上用 tcpdump 抓包:

sudo tcpdump -i eth0 -w catch.pcap

然后拷贝到本地用 Wireshark 分析,找到出问题的会话:

11   0.005519   172.19.0.2 → 10.10.4.1 TCP 74 38670 → 443 [SYN] Seq=0 Win=29200 Len=0 MSS=1460 SACK_PERM=1 TSval=2772715814 TSecr=0 WS=128
12   0.005557 10.10.4.1 → 172.19.0.2   TCP 74 443 → 38670 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1460 SACK_PERM=1 TSval=1814471534 TSecr=2772715814 WS=128
13   0.005577   172.19.0.2 → 10.10.4.1 TCP 66 38670 → 443 [ACK] Seq=1 Ack=1 Win=29312 Len=0 TSval=2772715814 TSecr=1814471534
14   0.025868   172.19.0.2 → 10.10.4.1 TLSv1 583 Client Hello
15   0.025897 10.10.4.1 → 172.19.0.2   TCP 66 443 → 38670 [ACK] Seq=1 Ack=518 Win=30080 Len=0 TSval=1814471554 TSecr=2772715834
16   0.028025 10.10.4.1 → 172.19.0.2   TLSv1.2 3133 Server Hello, Certificate, Server Key Exchange, Server Hello Done
17   0.028039   172.19.0.2 → 10.10.4.1 TCP 66 38670 → 443 [ACK] Seq=518 Ack=3068 Win=35456 Len=0 TSval=2772715837 TSecr=1814471557
18   0.029371   172.19.0.2 → 10.10.4.1 TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
19   0.029811 10.10.4.1 → 172.19.0.2   TLSv1.2 324 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
20   0.030425   172.19.0.2 → 10.10.4.1 TLSv1.2 311 Application Data
21   0.071192 10.10.4.1 → 172.19.0.2   TCP 66 443 → 38670 [ACK] Seq=3326 Ack=889 Win=31104 Len=0 TSval=1814471600 TSecr=2772715839
32  30.100738 10.10.4.1 → 172.19.0.2   TLSv1.2 576 Application Data
33  30.102365   172.19.0.2 → 10.10.4.1 TCP 66 38670 → 443 [FIN, ACK] Seq=889 Ack=3836 Win=41216 Len=0 TSval=2772745911 TSecr=1814501629
34  30.102480 10.10.4.1 → 172.19.0.2   TCP 66 443 → 38670 [FIN, ACK] Seq=3836 Ack=890 Win=31104 Len=0 TSval=1814501631 TSecr=2772745911
35  30.102500   172.19.0.2 → 10.10.4.1 TCP 66 38670 → 443 [ACK] Seq=890 Ack=3837 Win=41216 Len=0 TSval=2772745911 TSecr=1814501631

可以看到21号包和32号包之间通信时间间隔了30秒左右,也就是问题出在 10.10.4.1:在收到请求后,30秒左右才给返回结果。经过排查,是 10.10.4.1 的数据库挂了。