RSS

Wireshark を使用したgRPCメッセージの解析

Wiresharkは、プロトコル開発、ネットワークトラブルシューティング、教育に使用できるオープンソースのネットワークプロトコルアナライザーです。Wiresharkを使用すると、ネットワーク上で転送されるgRPCメッセージを分析し、これらのメッセージのバイナリ形式について学ぶことができます。

この記事では、WiresharkのgRPC dissectorとProtocol Buffers (Protobuf) dissectorの設定と使用方法について説明します。これらは、WiresharkでgRPCメッセージを分析できるようにするプロトコル固有のコンポーネントです。

機能

gRPCとProtobuf dissectorの主な機能は次のとおりです。

  • Protocol BuffersのワイヤーフォーマットまたはJSONでシリアライズされたgRPCメッセージのデコード(解析)をサポート

  • Unary、サーバーストリーミング、クライアントストリーミング、双方向ストリーミングRPC呼び出しのgRPCメッセージのデコードをサポート

  • シリアライズされたProtocol Buffersデータを拡張してデコードし、以下の操作を可能にします。

    • 関連する.protoファイルの読み込み
    • byteまたはstring型のProtocol Buffersフィールドに独自のサブディセクターを登録

gRPCトラフィックのキャプチャ

この記事は、キャプチャされたgRPCメッセージの分析に焦点を当てています。ネットワークトラフィックをキャプチャファイルに保存する方法については、Wiresharkユーザーズガイドの「ライブネットワークデータのキャプチャ」を参照してください。

Protocol Buffersチュートリアルのアドレス帳アプリのわずかに拡張されたバージョンによって生成された、以前にキャプチャされたメッセージを分析するために必要なセットアップをステップバイステップで見ていきましょう。

アドレス帳の.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フィールドを除いて、Protocol Buffersチュートリアルのバージョンと同一です。

ファイルの先頭にあるimportステートメントに注意してください。これは、多くのProtocol BuffersのWell-Known Typesの1つであるTimestampをインポートするために使用されます。

また、私たちのアプリのバリアントは、選択されたPerson属性に基づいてアドレス帳のエントリを検索できるperson-searchサービスを定義しています。このサービスは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ファイルはファイルの先頭でインポートされます。

Protocol Buffersの検索パスの設定

Wiresharkは、分析しているメッセージのアプリで使用されている.protoファイルを知っている場合に、最も意味のあるデコードを行います。

編集メニューの設定 > プロトコル > Protobufからアクセスできる設定で、Wiresharkに.protoファイルの場所を伝えることができます。

例のアプリの.protoファイルがd:/protos/my_proto_filesディレクトリにあり、公式のProtobufライブラリディレクトリがd:/protos/protobuf-3.4.1/includeにある場合、これらの2つのパスをソースディレクトリとして次のように追加します。

Protobuf-search-paths dialog

アプリのプロトコルディレクトリに対してすべてのファイルを読み込むオプションを選択することで、addressbook.protoおよびperson_search_service.protoファイルからのメッセージ定義の事前読み込みを有効にできます。

キャプチャファイルの読み込み

WiresharkのSampleCapturesページから、アプリを実行して検索リクエストを発行して作成された次のサンプルgRPCキャプチャファイルをダウンロードしてください:grpc_person_search_protobuf_with_image.pcapng

ファイルメニューから開くを選択して、Wiresharkでキャプチャファイルを読み込みます。Wiresharkは、キャプチャファイルからのすべてのネットワークトラフィックを、ウィンドウ上部のパケットリストペインに順番に表示します。

パケットリストペインからエントリを選択すると、Wiresharkがそれをデコードし、下部ペインに詳細を表示します。次のようになります。

Packet-list and packet-detail panes

詳細ペインからエントリを選択すると、そのエントリに対応するバイトシーケンスが表示されます。

Packet bytes

ポートトラフィックタイプの指定

アプリのサーバー側ポートは50051です。クライアント側ポートはRPC呼び出しごとに異なりますが、サンプルキャプチャファイルでは51035です。

これらのポートがHTTP2トラフィックを運んでいることをWiresharkに伝える必要があります。これは、分析メニューから(またはパケットリストペインのエントリを右クリックして)アクセスできるデコード設定ダイアログから行います。サーバー側ポートのみを登録する必要があります。

Decode-as dialog

パケットリストペインを見ると、WiresharkがHTTP2およびgRPCメッセージをデコードしていることがわかります。

Packets are decoded as HTTP2 and gRPC messages

検索リクエストメッセージのデコード

ポート50051に送信された最初のgRPCメッセージを選択します。これは、サンプルのサービスリクエストメッセージに対応します。Wiresharkは次のようにgRPCリクエストをデコードします。

Decoded search request

HTTP2メッセージヘッダーのpathフィールドを調べると、アプリのサービス(/tutorial.PersonSearchService)へのURLと、呼び出されたRPCの名前(Search)が表示されます。

gRPCライブラリによって設定されるcontent-typeは、WiresharkにHTTP2メッセージの内容がgRPCメッセージであることを通知します。サンプルのgRPCリクエストのデコードされたProtocol Buffersメッセージを調べると、検索リクエストが「Jason」と「Lily」の名前であることがわかります。

サーバーからストリーミングされるレスポンスのデコード

Search RPCのレスポンスはサーバーストリーミングであるため、Personオブジェクトはクライアントに次々と返されます。

レスポンスストリームで返された2番目のPersonメッセージを選択して、その詳細を表示します。

Decoded search response

サブディセクターを登録することで、byteまたはstring型のフィールドをWiresharkでさらにデコードさせることができます。たとえば、portrait_imageフィールドにPNGデコーダーを登録する方法については、「Protobufフィールドサブディセクター」を参照してください。

gRPCとProtocol Buffersサポートの歴史

gRPCおよびProtocol Buffersのサポートに関連するWiresharkのバージョンについて、簡単な注釈付きリストを以下に示します。

  • v2.6.0: gRPCおよびProtobuf dissectorの最初のリリース。.protoファイルやストリーミングRPCのサポートはありませんでした。
  • v3.2.0: .protoファイルに基づいたシリアライズされたProtocol Buffersデータのデコードが改善され、ストリーミングRPCがサポートされました。
  • v3.3.0: .protoファイルサポートが改善・強化され、Protocol Buffersフィールド値でのキャプチャファイル検索などが可能になりました。
  • v3.4.0: Protocol BuffersのTimestamp時間が、ロケールの日時文字列として表示されるようになりました。

詳細はこちら

さらに詳しく知りたいですか? Wiresharkユーザーズガイドから始めましょう。この記事で使用した例や、gRPCメッセージを含むその他のサンプルキャプチャファイルの詳細については、gRPC dissectorおよびProtocol Buffers dissectorのWikiページを参照してください。