Wireshark Protobuf 和 gRPC 内置解析器使用介绍
Wireshark 从2.6.0版本开始支持解析Protobuf和gRPC协议,但到3.3.x/3.4.0版本相关功能才比较完备。
1. 主要功能
Wireshark内置的Protobuf和gRPC解析器主要功能包括:
-
支持解析Protobuf和JSON两种格式封装的gRPC消息。(所以后续Protobuf相关功能也同样适用于Protobuf封装格式的gRPC消息)
-
支持解析流模式的gRPC接口的消息。
-
支持*.proto文件搜索路径的配置,以便Wireshark可以准确解析字段名称及字段值(例如Protobuf的varint字段可能是有符号或无符号整型,布尔或枚举类型,需要借助.proto文件才能正确解析)。支持proto2或proto3语法定义的.proto文件。
-
支持将Protobuf字段可以解析为Wireshark字段,以便用户可以在过滤器工具栏中输入Protobuf的字段名或消息名查找包含该字段或消息的包。
-
支持编写子解析器,用于进一步解析bytes或string类型的Protobuf字段。
-
支持除gRPC外其它基于Protobuf协议的解析功能:
-
可以通过配置UDP端口与消息的映射关系解析直接在UDP上传输的Protobuf消息。
-
可以自己编写C或Lua插件,用于解析基于Protobuf上构建的自定义协议的抓包。
-
后续章节将通过一些例子具体说明Wireshark Protobuf及gRPC内置解析器的用法。
2. 示例中使用的.proto文件
本章给出了后续示例中使用的.proto文件。
以下是表示人员信息及地址簿的 addressbook.proto
文件内容如下:
// This file comes from the official Protobuf example with a little modification.
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phone = 4;
google.protobuf.Timestamp last_updated = 5;
bytes portrait_image = 6;
}
message AddressBook {
repeated Person people = 1;
}
注意:根据 'import "google/protobuf/timestamp.proto"'
这一行可知,addressbook.proto
依赖于Protobuf官方标准库。如果本机已安装Protobuf,则安装目录下应该可以找到放标准库.proto文件的目录,如果没有可以从这里下载 protobuf-official-lib-protos.zip。
以下名为 person_search_service.proto
文件的内容表示定义了一个根据名称、编号等字段搜索人员信息的接口:
// A gRPC service that searches for persons based on certain attributes.
syntax = "proto3";
package tutorial;
import "addressbook.proto";
message PersonSearchRequest {
repeated string name = 1;
repeated int32 id = 2;
repeated string phoneNumber = 3;
}
service PersonSearchService {
rpc Search (PersonSearchRequest) returns (stream Person) {}
}
注意:person_search_service.proto
文件依赖于 addressbook.proto
文件。
3. 消息定义文件(*.proto)搜索路径配置
在Wireshark Protobuf协议配置界面的 ‘Protobuf Search Paths’ 选项里配置查找以上文件的路径。
假设 addressbook.proto
和 person_search_service.proto
文件同在 d:/protos/my_proto_files
目录下,且 "google/protobuf/timestamp.proto"
文件的绝对路径为 d:/protos/protobuf-3.4.1/include/google/protobuf/timestamp.proto
(即Protobuf标准库在 d:/protos/protobuf-3.4.1/include
目录里)。则你需要将 d:/protos/protobuf-3.4.1/include/
和 d:/protos/my_proto_files
路径都加到 ‘Protobuf Search Paths’ 配置表里,并保证 'd:/protos/my_proto_files'
这条记录的 ‘Load all files’ 选项选中(表示预先加载该目录下的消息),配置界面如下图所示:
注意:配置界面菜单入口为:编辑(Edit)->首选项(Preferences)->Protocols->ProtoBuf->Protobuf search paths,(或者在详情页面Protobuf某字段右键菜单里选择“Protocol Preferences”及其中的 ‘Protobuf Search Paths…’ 选项。
4. Wireshark gRPC解析器使用示例
4.1. 消息体为Protobuf格式的gRPC抓包文件示例
这是一个Protobuf封装的gRPC抓包示例 grpc_person_search_protobuf_with_image.pcapng。打开该文件后,需要使用“Decode As…”右键菜单将50051端口的TCP流解析成HTTP2协议,如下图所示:
然后抓包文件将被解析为:
以上是请求消息的截屏,表示要查询用户名字为Jason或Lily的人员信息。
由于Search
操作定义为服务器流模式接口(server streaming RPC mode), 则人员对象(Person)可以分多个包一个接一个的返回给客户端侧:
4.2. 消息体为JSON格式的gRPC抓包文件示例
这是一个JSON封装的gRPC抓包示例 grpc_person_search_json_with_image.pcapng。与上一个例子类似,打开该文件后,需要使用“Decode As…”右键菜单将50052端口的TCP流解析成HTTP2协议。抓包文件的截屏:
注意:JSON格式的包在未配置 ‘Protobuf Search Paths’ 的情况下也能查看,因为没有用到Protobuf。
5. Wireshark Protobuf解析器使用示例
5.1. 内置的Protobuf UDP解析器
如果你自定义的一个协议是让Protobuf消息直接在某个UDP端口上传输,你可以在Wireshark Protobuf的配置界面的“Protobuf UDP Message Types”配置项里添加UDP端口与消息类型的映射关系。例如,如果UDP端口8127上传输的是前述 addressbook.proto
文件里定义的 “tutorial.AddressBook” 类型的消息,则你可以在Protobuf首选项配置页面的 “Protobuf UDP message Types” 项中添加UDP端口与该消息类型的映射记录,配置界面如下所示: