Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

開発環境でHTTPとかの通信をキャプチャしていい感じでデバッグする方法

More than 3 years have passed since last update.

この記事は『LITALICO Engineers Advent Calendar 2017』の21日目の記事です。

昨年は、ナウでイケてる格安の分析基盤&BIツールをGoogleスプレッドシートとBigQueryを中心に構築する方法として、無料に近い価格で、分析環境を整える方法を紹介しました。今年に入っても2社ほど、この方法でダッシュボードを作ったりしていたのでまだまだ結構使える感じだと思います。無料の分析UIとして、Spreadsheetに加えて、Google Data StudioやRedashなどを使えたりしますが、まだまだSQLをかかなければいけないことが多かったり制約があったりするので、早くTableau的なやつが安く使えるといいなと思ってます。

今回のAdvent CalendarではWiresharkを使った、開発環境でのパケットキャプチャについて紹介します。LITALICO以外でも開発しているのですが、その開発環境としてGO言語で、docker-compose upして、dockerでDatastoreのEmulator, Elasticsearch, Pub/SubのEmulatorなどが動いていています。その他に、FirebaseにHTTPSでPush通知のリクエストを飛ばしたりしています。時々、アプリからElasticsearchやその他のサービスにどんなリクエストがみたくなるときがあって、GOにprint文とかをうめこんでみたりしているのですが、さすがにだるくなってきたので、Wiresharkでパケットをキャプチャしてどのようなリクエストとレスポンスが飛んでいるのか見れることをゴールにします。

Wiresharkとは

image.png

パケットをキャプチャするソフトウエアです。似たようなソフトソフトウエアとしては、Chalersなどがありますが、CharlesはHTTPに特化しているようなイメージで、WiresharkはIPとかTCPレイヤーとかまるっと見えます。今回Charlesではなく、Wiresharkを選んだのは、Charlesを使うと、Dockerで動かしているコンテナがとまってしまうのと(Issue)、gRPCとSSLをつかっていてその時のデバッグでWiresharkが役立ったので、簡単に使えるようになれるように選びました。

Wiresharkのインストールなどは公式HPや、他のQiita記事を参考にしてみてください

Elasticsearchのパケットをいい感じでデバッグする

早速使い方を説明します。まずWiresharkを開くとネットワークインタフェースを選ぶ画面がでてきます。

image.png

Wifi: en0とかついているのがネットワークインタフェースの名前で、どのインタフェースのパケットをキャプチャするか選びます。右側のうねうねとなっているグラフが現在までのパケット量を表しています。いま使っているMacはWifiとLANにつながっていますので、Wi-Fi: en0とAX88179...がそれぞれWifiとLANのネットワーク・インタフェースで、Loopback: lo0となっているのが、localhostなどにアクセスしたときに使われるネットワークインタフェースです。今回は開発環境でのパケットを取得したいので、Loopback: lo0を選択して次に進みます。

今回はcURLで以下のリクエストを飛ばしてそれがどのようにWiresharkで見つけられるかみてみます。

curl -XGET "http://localhost:9200/test/_analyze" -H 'Content-Type: application/json' -d'
{
  "analyzer" : "readingform_index_analyzer",
  "text" : "おいしい牛乳"
}'

Loopbackでキャプチャできるパケットが取得できるのですが、パケットが多すぎてフィルタしたくなります。
フィルタは以下からできます。

image.png

Elasticsearchは9200のポートで、HTTPのみ表示させたいのでtcp.port == 9200 && httpのように指定するといい感じでフィルタできます。

ただ、Kibanaなどを動かしていると以下のようにやたらゴミなクエリがとんできていて、目的のものが見つけにくいです。

image.png

その場合はさらに、tcp.port == 9200 && http && !(tcp.port == 52083 || tcp.port == 52082)みたいにKibanaが使っているsrcポートを指定してフィルタします。
それでもフィルタできない場合は、リクエストまたはレスポンスに入っているであろうJSON文字列もフィルタできるので今回はjson contains analyzerでフィルタします。analyzerが探したい文字列です

image.png

見つかった目的のパケットを選択した状態で、Wiresharkのメニューの以下からパケットを表示します。(パケット選択して、右クリックから、追跡=>HTTPストリーム、でもいけます。)

image.png

すると以下のようにHTTPのリクエストとレスポンスが表示されていいかんじで見れました。これでデバッグが容易になります。
ちなみに、UTF-8形式にしないと日本語は表示されないので気をつけてください。

image.png

それ以外の方法でも、JavaScript Object Notationを右クリックしてから、パケットバイト列を表示にしてから、HTML形式を選択してもJSON自体の中身は見ることができます。

image.png

まとめ

アプリにprint文などをうめこんでいなくてもWiresharkを使えば、サーバと他のサービス間での通信がキャプチャできます。その他にも、以前、GKEで、gRPCを使ってHTTP/2のSSL通信を使おうとしたときにうまくできなくてWiresharkでパケットをみながら解決したことがありましたので、プロトコルレベルでうまくかないときに使うのもおすすめです。

wapa5pow
サーバサイドのエンジニアです。 機械学習とかも興味あります。
https://wapa5pow.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away