UbuntuサーバーサイドJava、OkHttpの通信内容をmitmproxyで見る

UbuntuサーバーサイドJavaアプリを作り始めたのだが、OkHttpの通信を見る方法を知らなかったので調べた

mitmproxyとは?

mitmproxy.org

CharlesやFiddlerと同様に通信を見るためのプロキシだが、mitmproxyは無料、Ubuntuでも使えるという特徴がある。Charlesは有料、FiddlerはWindows専用だ

KeyStore Exploerとは?

HTTPSの通信を見るためには、信頼されたルート証明機関の証明書のキーストアに、mitmproxyの証明書を追加する必要がある。 具体的な説明はここを見てほしい

普通のプログラムはOSが持つキーストアを使うのだが、Javaは独自でキーストアを持っている。 これを編集するために使うGUIのツールがKeyStore Explorerだ

keystore-explorer.org

手順

  1. mitmproxy & KeyStore Explorerをインストールする
  2. mitmproxyを起動する
  3. Javaコード上でOkHttpのプロキシの設定をする
  4. mitmproxyでHTTPの通信を見る
  5. KeyStore ExplorerでJavaのルート証明機関の証明書のキーストアにmitmproxyの証明書を追加する
  6. mitmproxyでHTTPSの通信を見る

インストール手順

公式の手順に従ってインストールする

mitmproxy起動

mitmproxyがインストールされた。さて、今回はmitmweb(mitmproxyのWebクライアント)を起動しよう

$ mitmweb
Web server listening at http://127.0.0.1:8081/
Proxy server listening at http://*:8080

8080番でListenしており、8081番でGUIを表示できることがわかる

OkHttpのプロキシの設定

こんな感じでプロキシを設定する

    val builder = OkHttpClient.Builder()
    builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress("127.0.0.1", 8080)))
    val client: OkHttpClient = builder.build()

mitmproxyでHTTPの通信を見る

この時点でHTTPの通信を見ることはできる

f:id:akrfjmt:20200209202653p:plain

HTTPの通信を見ることはできるようになったので、HTTPSの通信も見れるようにしよう

KeyStore Explorerで作業

KeyStore Explorerを 起動する

f:id:akrfjmt:20200209201402p:plain

SDKMANでJavaをインストールしてる場合、 ~/.sdkman/candidates/java/current/lib/security/cacerts がJavaのキーストアだ。 KeyStore Explorerは隠しディレクトリを開けない場合がある。その場合 ln -s ~/.sdkman ~/sdkman で隠しではないエイリアスを作ろう。 cacertsを開いたらパスワードを聞かれる。これのデフォルト値は changeit

f:id:akrfjmt:20200209203456p:plain をクリックしてルート証明機関の証明書を追加しよう mitmproxy初回起動時に、 ~/.mitmproxy/mitmproxy-ca-cert.cer にmitmproxyのルート証明機関の証明書が作成されているので、これを選択する

f:id:akrfjmt:20200209203708p:plain

mitmproxyでhttpsの通信を見る

HTTPSの通信内容をmitmproxyで見ることができるようになったので確認しよう

f:id:akrfjmt:20200209203819p:plain

その他

「OkHttpはhttpsのプロキシもサポートしてほしい!」みたいなissueがGitHubで散見されるが、なんだかなという感じである

Androidアプリの通信も同様にmitmproxyで見れそうだが、Stethoを使う方が圧倒的に楽、むしろサーバサイドStetho欲しい