数据抓包是我们做业务测试、竞品分析的常用方法,在直播、短视频等常见的音视频业务场景能有好的数据抓包工具帮助,很多时候也能事半功倍。这里我们就介绍两款常见的数据抓包工具:
Charles[1] 是在 macOS 上最常使用的 HTTP/HTTPS 数据抓包工具。下面是它的一些功能:
我们在这里对重点配置做一下介绍:
1)Mac 端代理设置
安装好 Charles 后,在菜单栏勾选 Proxy → macOS Proxy
,系统 HTTP/HTTPS 代理将会被自动设置为本地代理,默认端口 8888
。
2)Mac 端 HTTPS 证书设置
在 Charles 菜单栏选择 Help -> SSL Proxying -> Install Charles Root Certificate
,会自动导入 Charles Proxy CA 证书并打开 Keychain Access。
这里需要我们双击新导入的证书弹出证书信息页面,将 Secure Sockets Layer (SSL)
设置为 Always Trust
,关闭页面后弹出密码提示,输入密码更新系统信任设置。
3)Mac 端 HTTPS 设置
在 Charles 菜单栏选择 Proxy -> SSL Proxy Settings...
,在 SSL Proxying
选项卡中选中 Enable SSL Proxying
,并添加需要抓包的域名端口。
这样才能解析 HTTPS 的数据。
4)iPhone 手机端代理设置
要对 iPhone 手机进行 HTTP/HTTPS 抓包,需要确保 iOS 设备和 Mac 设备处于同一局域网内。
然后,设置 iOS HTTP 代理:打开 iOS 设备对应 WIFI 设置,添加代理,设置 IP 地址为 Mac 的局域网地址,端口号设置为上面讲到的默认代理端口号 8888
。
Mac 局域网地址可以在 Charles 中从菜单栏 Help → Local IP Address
获取。
设置完成后,在 iOS 设备上访问数据链接,Charles 弹出 Access Control 确认对话框,选择 Allow,可以开始抓取 HTTP 包。
5)iPhone 手机端 HTTPS 设置
如果想要对 iPhone 手机进行 HTTPS 抓包,还需要在手机上进行设置。
首先,在菜单栏选择 Help → SSL Proxying → Install Charles Root Certificate on a Mobile Device or a Remote Browser
,弹出提示框。
根据上述提示,在 iOS 设备上使用 Safari 浏览器访问 chls.pro/ssl
,Safari 浏览器会自动下载证书并提示安装,根据提示一步一步安装好,证书会被添加到设置 → 通用 → 描述文件
中。
进入设置 → 通用 → 关于本机 → 证书信任设置
,对上一步安装的 Charles 证书启用完全信任。
接下来,在 iOS 设备上访问 HTTPS 数据链接,可以开始抓取 HTTPS 包。
在使用 Charles 抓包时,我们可能会遇到解析不了 HTTPS 数据的情况,这是为什么呢?
如下图,当我们抓包解析不了 HTTPS 数据时:
提示显示:
SSL Proxying not enabled for this host: enable in Proxy Settings, SSL locations
复制代码
这是因为我们没有添加对应的域名和端口,做如下操作即可:
在菜单栏选择 Proxy -> SSL Proxy Settings...
,在 SSL Proxying 选项卡中可以添加需要抓包的域名端口。
上面讲到的 Charles 处理 HTTP/HTTPS 请求的数据抓包是强项,但是对于 RTMP、DNS、TCP、UDP 协议的数据抓包就无法胜任了。这时候我们可以使用 Wireshark[2],下面是它的一些功能:
我们在这里对基本配置流程和常见抓包示例做一下介绍:
1)Wireshark 下载和安装
从 Wireshark 官网下载页面[3]下载 Mac 版本的安装包安装即可。
需要注意的是下图中处理 app 外的其他两个 pkg 也需要安装一下:
安装成功后,打开 Wireshark 的界面如图:
这个界面列出了当前系统所使用的网卡,点击任何一项就可以开始监听了。
2)手机连接配置
要用 Wireshark 来抓包 iPhone 的数据,首先需要 iPhone 的数据经由 Mac OS 传输才行。可以通过 rvictl
来做到,rvictl
是一个可以连接设备来抓包的工具。
Remote Virtual Interface Tool starts and stops a remote packet capture instance for any set of attached mobile devices. It can also provide feedback on any attached devices that are currently relaying packets back to this host.
复制代码
我们可以使用下面的命令来连接一个设备:
$ rvictl -s
复制代码
对应的,可以使用下面的命令来断开一个设备:
$ rvictl -x
复制代码
不过在使用 rvictl
工具之前,通常需要做一下安装:
$ cd /Applications/Xcode.app/Contents/Resources/Packages/
$ open .
复制代码
双击安装 MobileDevice.pkg
和 MobileDeviceDevelopment.pkg
。
在 Mac OS 10.15.0 以上,还需要注意 rvictl
命令的路径发生了改变,需要做配置:
在 `/etc/paths` 文件中增加一行路径 `/Library/Apple/usr/bin/`。保存后,重启终端。
复制代码
完成上述操作以后,再使用
$ rvictl -s
复制代码
就可以启动一个虚拟的网络接口,名字是 rvi0
(如果是多台 iPhone 则数字累加,如:rvi1,rvi2 等)。
这时候再打开 Wireshark 就可以看到这个网络接口了:
双击就可以看到数据抓包了。
2.2.1、TCP 三次握手抓包
先回顾一下 TCP 三次握手和四次挥手的基础知识:
接下来看一下 Wireshark 的抓包情况:
下图是第一次握手的抓包数据,这个包由客户端(172.16.146.107)发送给服务端(203.55.2.249),发送的 SYN
包的数据中 Sequence number
是 0。
下图是第二次握手的抓包数据,这个包由服务端(203.55.2.249)发送给客户端(172.16.146.107),发送的 SYN + ACK
包的数据中 Sequence number
是 0,Acknowledgement number
是 1。
下图是第三次握手的抓包数据,这个包由客户端(172.16.146.107)发送给服务端(203.55.2.249),发送的 ACK
包的数据中 Acknowledgement number
是 1。
2.2.2、RTMP 握手和协议控制消息抓包
下面是对直播 RTMP 推流的数据进行抓包的情况:
前面的 Handshake C0+C1
、Handshake C2
、Handshake S0+S1+S2
是握手消息;后面的 connect()
、createStream()
、publish()
等是客户端发送的命令消息(Command Message);Set Chunk Size
、Window Acknowledgement Size
、Set Peer Bandwidth
等是客户端发送的协议控制消息(Protocol Control Messages);再到后面的 Audio Data
和 Video Data
就是音视频数据消息(Data Message)了。
1)握手过程
在握手过程中,RTMP 协议本身并没有规定这 6 个消息的具体传输顺序,但 RTMP 协议的实现者需要保证这几点:
从抓包的数据来看,这里的实现并没有遵守该规定。这里的实现是客户端发送了 Handshake C0+C1
、Handshake C2
两条握手消息后,服务端发回 Handshake S0+S1+S2
消息完成握手。
2)Set Chunk Size 协议控制消息
首先我们来回顾一下 RTMP 协议中关于 Set Chunk Size 协议控制消息的规定:
1、Set Chunk Size 消息类型(Message Type)为 1。
2、协议控制消息一般使用的类型为 0 的块消息头。
3、协议控制消息一般使用保留的块流 ID 2。
4、RTMP 协议定义的块(Chunk)的数据格式是:
+--------------+----------------+--------------------+--------------+
| Basic Header | Message Header | Extended Timestamp | Chunk Data |
+--------------+----------------+--------------------+--------------+
| |
|<------------------- Chunk Header ----------------->|
复制代码
4.1、Basic Header
部分,协议控制消息一般使用保留的块流 ID 2,而块流 ID 在 2-63 之间的,会使用 1 字节类型的格式,所以 Set Chunk Size 协议控制消息使用的 Basic Header 的格式会是下面这种类型:
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|fmt| cs id |
+-+-+-+-+-+-+-+-+
Chunk basic header 1
复制代码
其中,对应的 fmt 字段值是 0,表示使用类型为 0 的块消息头;cs id 字段值是 2,即使用协议控制消息保留的块流 ID。
4.2、Message Header
部分,协议控制消息会使用类型为 0 的块消息头格式,所以 Set Chunk Size 协议控制消息的块消息头格式如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp | message length|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| message length (cont) |message type id| msg stream id |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| message stream id (cont) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Message Header - Type 0
复制代码
其中,对应的 timestamp 字段值根据情况设置;message length 字段值是 4,表示 Set Chunk Size 消息的长度是 4 字节;message type id 字段的值是 1,表示是 Set Chunk Size 消息;message stream id 的值则根据情况设置。
4.3、Extended Timestamp
部分这里是没有的。
4.4、Chunk Data
部分,RTMP 协议中 Set Chunk Size
协议控制消息的格式如下:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0| chunk size (31 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
复制代码
其中,chunk size 字段是我们设置的块大小的值。注意这里是小端字节序。
接下来,我们看一下我们抓包到的 Set Chunk Size
消息块:
上面抓包得到这条 16 字节的 Set Chunk Size
消息的数据(十六进制)如下:
02 00 00 00 00 00 04 01 00 00 00 00 00 00 10 00
其中:
0x0001 = 2 ^ 12 = 4096
,表示设置的块大小值为 4096 字节。关于 Wireshark 的抓包示例我们就介绍到这里,更多的强大的功能,大家可以自己动手去试试,相信不会让你失望。
[1]Charles: www.charlesproxy.com/
[2]Wireshark: www.wireshark.org/
[3]Wireshark 官网下载页面: www.wireshark.org/download.ht…
推荐阅读
《FFmpeg 工具:音视频开发都用它,快@你兄弟来看》
《可视化音视频分析工具:好用工具大集锦,快转发给你兄弟看看》