[API翻译]用Wireshark分析gRPC消息

2,478 阅读6分钟

原文地址:grpc.io/blog/wiresh…

原文作者:github.com/huangqiangx…

发布时间:021年02月03日 星期三

Wireshark是一款开源的网络协议分析器,可用于协议开发、网络故障诊断和教育。Wireshark可以让你分析通过网络传输的gRPC消息,并了解这些消息的二进制格式。

在这篇文章中,你将学习如何配置和使用Wireshark gRPC剖析器和协议缓冲区(Protobuf)剖析器,它们是协议专用组件,允许你用Wireshark分析gRPC消息。

课程特点

gRPC和Protobuf剖析器的主要功能如下。

  • 支持剖析(解码)以协议缓冲线格式或JSON格式序列化的gRPC消息。
  • 支持剖析无源、服务器流、客户端流、双向流RPC调用的gRPC消息。
  • 增强了对序列化协议缓冲区数据的剖析,允许你做以下工作。
    • 加载相关的.proto文件
    • 为字节或字符串类型的协议缓冲区注册自己的子分词器

捕捉gRPC流量

本篇文章主要分析捕获的gRPC消息。要了解如何在捕获文件中存储网络流量,请参见《Wireshark用户指南》中的捕获实时网络数据

注意事项

目前,Wireshark只能解析纯文本gRPC消息。虽然Wireshark支持TLS剖析,但它需要每个会话的秘钥。在写这篇文章的时候,只有Go gRPC支持导出这种密钥。要了解如何使用Go gRPC导出密钥,以及其他语言的支持,请参见如何导出gRPC的TLS主密钥

例子

让我们通过必要的设置来分析之前捕获的消息,这些消息是由协议缓冲区教程中使用的地址簿应用程序的一个稍微扩展版本生成的。

地址簿.proto文件

该应用的主协议文件是addressbook.proto。

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;
}

这个文件与协议缓冲区教程版完全相同,只是增加了 portrait_image 字段。

请注意文件顶部的导入语句,它是用来导入时间戳的,时间戳是许多协议缓冲区已知类型之一。

我们的应用程序的变体还定义了一个person-search服务,它可以用来根据选定的Person属性搜索地址簿条目。这个服务定义在person_search_service.proto中。

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) {}
}

因为服务使用 addressbook.proto 中定义的 Person 类型,所以在文件开始时导入地址簿 .proto。

设置protobuf搜索路径

当Wireshark知道你正在分析消息的应用程序所使用的.proto文件时,它就会提供最有意义的解码。

你可以通过在偏好设置中设置Protobuf搜索路径来告诉Wireshark在哪里找到.proto文件。

如果我们的示例应用的.proto文件在d:/protos/my_proto_files目录下,而官方的Protobuf库目录是d:/protos/protobuf-3.4.1/include,那么就像这样把这两个路径添加为源目录。

image.png

通过为应用程序的协议目录选择Load all files选项,您可以从addressbook.proto和person_search_service.proto文件中预加载消息定义。

加载捕获文件

从Wireshark SampleCaptures页面,下载以下通过运行应用程序并发出搜索请求创建的gRPC捕获文件示例:grpc_person_search_protobuf_with_image.pcapng

从 "文件 "菜单中选择 "打开",在Wireshark中加载捕获文件。Wireshark会在窗口顶部的Packet-list窗格中按顺序显示捕获文件中的所有网络流量。

从Packet-list窗格中选择一个条目,Wireshark将对其进行解码,并在下层窗格中显示其详细信息,就像这样。

image.png

从详细信息窗格中选择一个条目,以查看与该条目对应的字节序列。

image.png

设置端口流量类型

该应用的服务器端端口是50051。客户端的端口,每次RPC调用的端口都不一样,在样本捕获文件中是51035。

你需要告诉Wireshark这些端口正在传输HTTP2流量。通过 "解码为 "对话框来完成这一工作,你可以从 "分析 "菜单中访问该对话框(或在数据包列表窗格中右键单击一个条目)。你只需要注册服务器端的端口。

image.png

查看包列表窗格,你会发现Wireshark现在正在解码HTTP2和gRPC消息。

image.png

解码搜索请求信息

选择第一个发送到50051端口的gRPC消息,它对应的是样本的服务请求消息。这就是Wireshark剖析gRPC请求的过程。

image.png

通过检查HTTP2消息头路径字段,你会看到应用程序服务的URL(/tutorial.PersonSearchService),后面是调用的RPC(Search)的名称。

内容类型是由gRPC库设置的,它告知Wireshark,HTTP2消息内容是一个gRPC消息。通过检查样本gRPC请求的解码协议缓冲区消息,可以看到搜索请求的名称是 "Jason "和 "Lily"。

解码服务器流的响应

由于搜索RPC响应是服务器流,所以Person对象可以一个接一个地返回给客户端。

选择响应流中返回的第二个Person消息,可以查看其详细信息。

image.png

通过注册子鉴别器,你可以让Wireshark进一步解码字节或字符串类型的字段。例如,要了解如何为 portrait_image 字段注册一个 PNG 解码器,请参阅 Protobuf 字段子分证器

gRPC和协议缓冲区支持的历史沿革

下面是一个简短的Wireshark版本注释列表,因为它们与gRPC和协议缓冲区的支持有关。

  • v2.6.0:首次发布gRPC和Protobuf剖析器,不支持.proto文件或流式RPC。
  • v3.2.0:改进了基于.proto文件的序列化协议缓冲区数据的剖析,并支持流式RPC。
  • v3.3.0:改进和增强了对.proto文件的支持,例如对协议缓冲区字段值的捕获文件搜索。
  • v3.4.0: 协议缓冲区时间戳时间显示为locale日期-时间字符串。

了解更多

有兴趣了解更多?请从Wireshark用户指南开始。关于这篇文章中使用的例子的更多细节,以及其他包含gRPC消息的样本捕获文件,请参见gRPC剖析器协议缓冲区剖析器维基页面。


www.deepl.com 翻译