【mitmproxy】モバイルアプリで通信監視したい人へ

## 0. 初めに
モバイルアプリの通信監視をしたい時、[**Charles**](https://www.charlesproxy.com/)を使用するのが便利だと思います。
Charlesは通信監視機能だけでなく、特定の通信だけを見るフィルタリングや、レスポンス内容の書き換えができたりと、使用している方も多いのではないでしょうか？

しかし、便利さと引き換えに**無料版は30日間しか使用できない**という制約があります。。。

先日それで大変困ったところ知り合いに[**mitmproxy**](https://mitmproxy.org/)をお勧めしていただき、これが大変便利だったので、今回まとめました。

以下、皆さんの参考の一助になれば幸いです。

# 前提事項 

* MacBook Pro(M1搭載)でmitmproxyを使用する

* MacPCとは別の、iOSデバイスの通信を確認する


## 目次
1. [mitmproxyとは？](#1-mitmproxyとは？)
2. [インストール手順](#2-インストール手順)
3. [終了方法](#3-終了方法)
4. [基本的な使用方法](#4-基本的な使用方法)
5. [参考](#5-参考)


# 1. mitmproxyとは？

### 概要
* **mitmproxy**は、インタラクティブなコンソールインターフェースを持つオープンソースのネットワークプロキシツールです。主な機能は、ネットワーク通信（特にHTTPとHTTPS通信）を中継し、観察し、変更し、リダイレクトすることです。
* これにより、特定のネットワークリクエストやレスポンスの詳細を確認したり、それらを変更したりすることができます。

### 基本的なしくみ
* 基本的なコンセプトとして、ネットワーク上で情報が送受信されるとき、「リクエスト」（要求）と「レスポンス」（応答）の形式で行われますが。通常、このリクエストとレスポンスは直接、クライアント（あなたのコンピュータ）とサーバー（ウェブサイトをホストしているサーバー）の間でやりとりされます。mitmproxyは、このリクエストとレスポンスの間に入る「中間者」です。つまり、クライアントとサーバーの間に立ち、通信を中継します。
* 使用者のコンピュータ（クライアント）は、リクエストを直接ウェブサーバーに送る代わりに、そのリクエストをmitmproxyに送ります。次にmitmproxyはそのリクエストをウェブサーバーに送り、レスポンスを受け取ります。そして、そのレスポンスをあなたのコンピュータに戻します。
* この流れの中で、mitmproxyは全ての通信を見ることができます。そして、必要に応じてリクエストやレスポンスを変更することもできます。これにより、ある特定のリクエストがどのようなレスポンスを引き起こすのかを確認したり、通信の様々な側面をデバッグ（調査）したりすることができるのです！


まぁ長ったらしいことは後にして、実際にインストール手順を見ていきましょう！

# 2. インストール手順
### Step1. PCへのインストール

* まず、terminalにて、以下のコマンドからインストールしましょう。
（体感15~20分くらいかかったかも）

```diff_powershell:mitmproxyをbrewインストール
brew install mitmproxy
```


:::note warn
注意
mitmproxyはPython製のソフトウェアなので、Pythonとそのパッケージマネージャpipが先にインストールされている必要があります。
その際は、[公式URL](https://www.python.org/%EF%BC%89%E3%81%8B%E3%82%89%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)からインストールしましょう。
:::

### Step2. iOSデバイスのプロキシを手動に設定


* モバイル端末を使用する場合、iOSデバイスのWi-Fi設定を変更し、
その通信(Wi-Fi)がMac上のmitmproxyを経由するように設定する必要があります。


1. iOSデバイス上で「設定」アプリを開き、「Wi-Fi」を選択する
2. 接続中のWi-Fiネットワークを選択し、その詳細設定画面を開く
3. 一番下までスクロール。「プロキシ」を選択し、「手動」を選択する
4. 「サーバ」と「ポート」にそれぞれMacの使用している Wi-FiのIPアドレスとmitmproxyがリッスンしているポート番号（デフォルトでは8080）を入力する

:::note info
下記は、使用しているMacの システム設定 > Wifi > Wifiの詳細 > TCP/IPから確認可能
(**図1**を参照)
サーバー：Macの使用している WifiのIPアドレス
ポート：mitmproxyがリッスンしているポート番号（デフォルトでは8080）
:::
<details><summary>図１</summary>
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/e8a82f30-0646-cfe2-ae7c-36cc5cd66f56.png">
</details>


### Step3. 証明書のインストール 

* mitmproxyの証明書をiOSデバイスに入れ、有効化します。
1. iOSデバイスからsafari(ブラウザはなんでもOK) > “mitm.it“を検索
2. **図2**から"iOS"をダウンロード
3. iOSデバイスの設定 > 一般 > VPNとデバイス管理 からmitmproxyを”インストール”する
4. インストールし、信頼すると**図3**のように表示される
5. iOSデバイスの設定 > 一般 > 情報 >証明書信頼設定 からmitmproxyを**図４**のように有効にする

<details><summary>図2</summary>
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/302c60c3-3067-6e88-e360-a3727f32d61f.png">
</details>

<details><summary>図3</summary>
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/3d0a1e04-b80f-bc0d-17a6-e537f287a613.png">
</details>

<details><summary>図4</summary>
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/d4e4ef0a-9594-07cd-e8cb-13d387fcc4ed.png">
</details>

### Step4. mitmproxyを起動する 

* MacPCのterminalから起動します。 
(8080の部分は、Step2で設定したポート番号です。)

```diff_powershell:mitmproxyを起動
mitmweb -p 8080 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/16987078-a8a8-6659-8f20-43cd752c22c0.png)


* 起動すると以下のように表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/2cf1caa3-50a7-7a92-dd0c-23446bba17a9.png)

* iOSデバイス側で通信を使用すると以下のように表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/85388fff-f0e7-7a60-07ec-4d8e5f2a19d1.png)


# 3. 終了方法
### Step1. mitmproxyを終了する
* terminalで開いたmitmproxy上で”control + c”で終了する

### Step2. iOSモバイルでの終了処理
* 設定 > Wi-Fi > Mac が接続している Wi-Fi と同じネットワークのi アイコン > プロキシ構成 > オフ にする

# 4. 基本的な使用方法
### その１. フィルタリング
* 特定の通信のみを表示することができます。
1. 以下のように、start タブのsearchに表示したいURLを記載する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/c14b7315-7caa-e8a5-8244-6ac90b6f8f41.png)

2.  以下のように対象のURLのみ表示されます
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/e9472288-867f-4a4d-4ca3-5aa0b9927081.png)

### その２. インタセプティング

* インタセプティングというのは特定の通信を傍受することです。またそのままres, reqを書き換えることができます。

1. start タブのinterceptに書き換えをしたいURLを記載する
2. iOSデバイスでその通信を繋ぐ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516597/bc883d47-8033-4cb6-0d25-cd55a5a0dc3e.png)

3. 選択して"aキー"でリクエストを通すことが可能
4. リクエストを通すと、レスポンスを補足し、止まる
5. ペンのアイコン「edit」をクリックすると編集モードに入り、編集可能
6. 編集が終わったらチェックマークをクリックする
7. "aキー"でリクエストを通すことが可能

上記のようにすることで、proxyを通った通信の傍受をし、内容の編集ができます。
※ちなみにzキーで通信を全て削除できます。

# 5. 参考
* https://blog.flatt.tech/entry/mitmproxy