mitmproxy: Python製インタラクティブHTTPSプロキシの詳細解説 🕵️‍♂️

プログラミング

ウェブ開発やAPIデバッグ、セキュリティテスト、モバイルアプリの通信解析など、ネットワーク通信を深く理解し、操作する必要がある場面は多岐にわたります。そんな時、強力な味方となるのが「mitmproxy」です。mitmproxyは、Pythonで書かれた高機能なインタラクティブHTTPSプロキシツールキットであり、HTTP/1, HTTP/2, WebSocketsなどの通信を傍受、検査、改変、リプレイすることが可能です。この記事では、mitmproxyの基本から応用まで、その魅力と使い方を詳しく解説していきます。✨

mitmproxyとは? 🤔

mitmproxyは、「Man-In-The-Middle proxy」(中間者プロキシ)の略で、その名の通りクライアントとサーバーの間に位置し、通信を中継するプロキシサーバーとして機能します。最大の特徴は、SSL/TLSで暗号化されたHTTPS通信を復号し、内容をリアルタイムで確認・編集できる点です。これにより、通常は暗号化されて見ることのできないHTTPSリクエストやレスポンスの詳細を把握したり、テスト目的で意図的に内容を書き換えたりすることが可能になります。

mitmproxyプロジェクトは、主に以下の3つのツールで構成されています。これらは共通のコア機能を持ち、異なるインターフェースを提供します。

  • mitmproxy: コンソールベースのインタラクティブなインターフェース。キーボード操作で通信フローをリアルタイムに確認・編集できます。
  • mitmweb: ウェブブラウザベースのグラフィカルインターフェース。Chrome DevToolsに似た感覚で、より視覚的に通信を操作できます。
  • mitmdump: コマンドラインツール。tcpdumpのように動作し、主にスクリプトと組み合わせて通信の自動処理や保存に使用されます。

これらはすべて同一のコア機能を利用しており、ユーザーの好みや用途に応じて使い分けることができます。

主な機能 🚀

mitmproxyは非常に多機能ですが、特に重要な機能をいくつか紹介します。
  • HTTP/HTTPS通信の傍受と改変: リクエストとレスポンスをリアルタイムで捕捉し、内容を自由に変更できます。ヘッダーの追加・削除、ボディの書き換え、ステータスコードの変更などが可能です。
  • 通信の保存と再生 (Replay): キャプチャした通信セッション全体をファイルに保存し、後で詳細に分析したり、クライアント側またはサーバー側の通信を再現したりできます。これはデバッグやテストの自動化に役立ちます。
  • Pythonによるスクリプティング: mitmproxyの最も強力な機能の一つです。Pythonスクリプト(アドオン)を使って、通信フローに対するカスタムロジックを実装できます。特定の条件に基づいて通信を自動的に変更したり、特定のデータを抽出したり、カスタムコマンドを追加したりと、可能性は無限大です。
  • 透過プロキシモード: クライアント側の設定変更なしに通信を傍受できるモードです(macOS/Linux)。ネットワーク設定レベルでトラフィックをmitmproxyにルーティングします。
  • リバースプロキシモード: 特定のサーバーへのトラフィックをmitmproxy経由で転送します。開発中のローカルサーバーへのアクセスを実際のドメイン名で行いたい場合などに便利です。
  • WebSocket通信のサポート: HTTPだけでなく、WebSocketのメッセージも傍受・改変できます。
  • 多様なデータ形式の表示: HTML, JSON, Protobufなど、様々な形式のメッセージを整形して表示(Pretty-print)したり、デコードしたりできます。
  • Anticache: ブラウザのキャッシュを無効化し、常にサーバーから最新のデータを取得するように強制します。
  • Map Local / Map Remote: 特定のURLへのリクエストをローカルファイルや別のURLにリダイレクトします。
  • ブロックリスト: 特定のURLパターンに一致するリクエストをブロックし、定義済みのレスポンスを返します。

インストール 💻

mitmproxyのインストールは比較的簡単です。お使いのOSに応じていくつかの方法があります。Python 3.12以降が必要です。

macOS

Homebrewを使用するのが最も簡単です。

brew install mitmproxy

Windows

公式サイトからインストーラーをダウンロードするか、Microsoft Store経由でインストールできます。

WSL (Windows Subsystem for Linux) を使用している場合は、Linuxと同様の方法でインストールできます。

Linux

公式サイトからバイナリをダウンロードするか、pipを使ってインストールします(Python環境が必要です)。

pip install mitmproxy

Dockerイメージも提供されています。

docker pull mitmproxy/mitmproxy

インストール後、ターミナルで mitmproxy --version, mitmweb --version, mitmdump --version を実行して、正しくインストールされているか確認しましょう。

基本的な使い方 🛠️

mitmproxyを起動し、クライアント(ブラウザやモバイルデバイスなど)のプロキシ設定を行うことで通信の傍受を開始します。

1. mitmproxy/mitmweb/mitmdumpの起動

ターミナルで以下のいずれかのコマンドを実行します。デフォルトではポート8080でプロキシサーバーが起動します。

  • コンソールUI: mitmproxy
  • Web UI: mitmweb (Web UIはデフォルトで http://127.0.0.1:8081 でアクセス可能)
  • コマンドライン (スクリプト実行用): mitmdump

ポート番号を変更したい場合は -p オプション (または --port) を使います。

mitmproxy -p 8888

mitmweb のWeb UIポートを変更する場合は --web-port を使います。

mitmweb --web-port 8082

2. クライアントのプロキシ設定

通信を傍受したいデバイスやアプリケーションのネットワーク設定で、HTTPおよびHTTPSプロキシサーバーとしてmitmproxyを実行しているマシンのIPアドレスとポート番号(デフォルトは8080)を指定します。

  • PCブラウザ: OSのシステムプロキシ設定を変更するか、ブラウザ拡張機能(例: Proxy SwitchyOmega)を使います。
  • モバイルデバイス (iOS/Android): Wi-Fi設定の詳細から手動でプロキシを設定します。サーバーにはmitmproxyを実行しているPCのIPアドレス、ポートには8080などを入力します。PCと同じWi-Fiネットワークに接続している必要があります。
  • ターミナル/プログラム: 環境変数 HTTP_PROXYHTTPS_PROXY を設定します。
    export HTTP_PROXY=http://<mitmproxy_ip>:8080
    export HTTPS_PROXY=http://<mitmproxy_ip>:8080

⚠️ 注意: WSLからmitmproxyを起動する場合、WSL2のネットワークはホストOSとは別になるため、ホストOSのIPアドレスを指定し、必要に応じてポートフォワーディングやファイアウォールの設定を行う必要があります。

3. HTTPS通信のための証明書のインストール (重要) 🔒

HTTPS通信を傍受・復号するには、mitmproxyが動的に生成するサーバー証明書をクライアントに信頼させる必要があります。これを行わないと、クライアントは証明書エラーで接続できません。

  1. プロキシ設定が完了したクライアントのブラウザで、特別なURL http://mitm.it にアクセスします。
  2. 表示されるページから、お使いのOSに対応するmitmproxyのCA証明書をダウンロードします。
  3. ダウンロードした証明書をシステムまたはブラウザにインストールし、「信頼されたルート証明機関」として設定します。(OSによって手順が異なります。iOSの場合は設定アプリの「一般」→「情報」→「証明書信頼設定」で有効化が必要です。)

証明書が正しくインストールされれば、HTTPSサイトへのアクセスもmitmproxy経由で行われ、通信内容が復号されて表示されるようになります。🎉

mitmproxy (コンソールUI) の基本操作

mitmproxy を起動すると、コンソール画面に通信フローがリスト表示されます。キーボードで操作します。

  • j / k または ↑ / ↓: フローを選択
  • Enter: 選択したフローの詳細を表示
  • q: 前の画面に戻る / 終了
  • i: インターセプト(傍受)フィルタを設定
  • a: インターセプトしたリクエストを送信 / レスポンスをクライアントに返す
  • A: すべてのインターセプトしたフローを再開
  • e: フローを編集 (Request/Responseなど選択)
  • d: フローを削除
  • r: フローをリプレイ
  • f: フローをフィルタリング
  • /: フローを検索
  • Shift + F: 新しいフローを自動で追従
  • ?: ヘルプ(キーバインド一覧)を表示

mitmweb はブラウザ上で直感的に操作できます。

Pythonスクリプティングによる自動化 🐍

mitmproxyの真価はPythonスクリプト(アドオン)による拡張性の高さにあります。mitmdump または mitmproxy/mitmweb-s オプションでスクリプトファイルを指定することで、通信フローに対する様々な処理を自動化できます。

スクリプトでは、特定のイベント(リクエスト受信時、レスポンス受信時など)に対応する関数(イベントフック)を定義します。

イベントフックの例

以下は代表的なイベントフックです。

  • request(flow: http.HTTPFlow): クライアントからのHTTPリクエストを受信したとき。リクエスト内容の変更が可能。
  • response(flow: http.HTTPFlow): サーバーからのHTTPレスポンスを受信したとき。レスポンス内容の変更が可能。
  • websocket_message(flow: http.HTTPFlow): WebSocketメッセージを受信したとき。
  • tcp_message(flow: tcp.TCPFlow): TCPメッセージを受信したとき。
  • load(loader): スクリプトがロードされたとき。初期化処理に使う。
  • configure(updated): オプションが変更されたとき。

flow オブジェクトを通じて、リクエスト (flow.request)、レスポンス (flow.response)、クライアント接続情報 (flow.client_conn)、サーバー接続情報 (flow.server_conn) などにアクセスできます。

スクリプト例 1: 特定ヘッダーの追加

すべてのレスポンスにカスタムヘッダーを追加する例です。

from mitmproxy import http

def response(flow: http.HTTPFlow) -> None:
    # すべてのレスポンスに 'X-Mitmproxy-Processed: true' ヘッダーを追加
    flow.response.headers["X-Mitmproxy-Processed"] = "true"
    print(f"Added header to {flow.request.pretty_url}")

このスクリプトを add_header.py として保存し、以下のコマンドで実行します。

mitmdump -s add_header.py

スクリプト例 2: 特定URLのリクエストをブロック

特定のドメインへのアクセスをブロックし、カスタムレスポンスを返す例です。

from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    # example.com へのアクセスをブロック
    if "example.com" in flow.request.pretty_host:
        print(f"Blocking request to {flow.request.pretty_url}")
        # 403 Forbidden レスポンスを生成して返す
        flow.response = http.Response.make(
            403,  # status_code
            b"Blocked by mitmproxy script",  # content
            {"Content-Type": "text/plain"}  # headers
        )

このスクリプトを block_example.py として保存し、実行します。

mitmdump -s block_example.py

スクリプト例 3: レスポンスボディの書き換え

特定のAPIレスポンス(JSON)の内容を書き換える例です。

import json
from mitmproxy import http
from mitmproxy import ctx # ctx.log を使うため

def response(flow: http.HTTPFlow) -> None:
    # 特定のAPIエンドポイントへのレスポンスか確認
    if flow.request.pretty_url.startswith("https://api.example.com/users/me"):
        # レスポンスがJSON形式か確認
        content_type = flow.response.headers.get("Content-Type", "")
        if "application/json" in content_type:
            try:
                # レスポンスボディをJSONとしてパース
                data = json.loads(flow.response.content)

                # ユーザー名を書き換える
                original_name = data.get("username")
                data["username"] = "MITMPROXY_USER"
                ctx.log.info(f"Modified username from '{original_name}' to 'MITMPROXY_USER'")

                # 書き換えたJSONをレスポンスボディに設定
                flow.response.text = json.dumps(data, indent=2)

            except json.JSONDecodeError:
                ctx.log.warn("Failed to decode JSON response.")
            except Exception as e:
                ctx.log.error(f"Error modifying response: {e}")

このスクリプトを modify_user.py として保存し、実行します。

mitmdump -s modify_user.py

このように、Pythonスクリプトを使えば、非常に柔軟かつ強力な通信操作が可能になります。アイデア次第で様々なテストやデバッグ、データ収集が自動化できます。🚀

ユースケース・応用例 🎯

mitmproxyはその強力な機能から、様々な分野で活用されています。
  • Web/API開発のデバッグ:
    • 送受信されるリクエスト/レスポンスの詳細(ヘッダー、ボディ、タイミング)を確認。
    • APIリクエストを改変して異常系のテストを実施(例: 不正なパラメータ送信、特定ヘッダーの削除)。
    • APIレスポンスを改変してフロントエンドの挙動を確認(例: エラーレスポンスのシミュレーション、データ形式の変更)。
    • レスポンスを遅延させてネットワーク遅延の影響をテスト。
  • モバイルアプリの通信解析:
    • アプリがバックエンドAPIとどのように通信しているかを詳細に把握。
    • アプリが送信するデータ(トラッキング情報、個人情報など)を確認。
    • APIレスポンスを改変してアプリの脆弱性や不具合をテスト(2014年頃からこの用途での利用例が見られます)。
    • 証明書ピニング(Certificate Pinning)が実装されているアプリの通信を解析(追加の対策が必要な場合あり)。
  • セキュリティテスト (ペネトレーションテスト):
    • WebアプリケーションやAPIの脆弱性診断(例: 不適切な入力検証、情報漏洩)。
    • リクエストを改ざんしてセキュリティ機構(認証、認可など)をテスト。
    • HTTPS通信が適切に暗号化されているか、中間者攻撃に対して耐性があるかを確認。
  • プライバシー分析:
    • ウェブサイトやアプリがどのような情報を収集・送信しているかを調査。
    • トラッカーや広告ネットワークの通信を特定・ブロック。
  • Webスクレイピング:
    • ブラウザ操作と組み合わせて、動的なWebサイトやJavaScriptで保護されたAPIからデータを抽出(2016年頃からの利用例)。人間がブラウジングした結果をmitmproxyでフックし、Pythonスクリプトでデータを保存・加工します。
  • プロトコルの学習・リバースエンジニアリング:
    • 未知のプロトコルや非公開APIの通信内容を解析。

他のツールとの比較 ↔️

ネットワークプロキシツールにはCharles ProxyやFiddlerなど、他にも有名なものがあります。mitmproxyはそれらと比較して以下のような特徴があります。

特徴 mitmproxy Charles Proxy Fiddler
ライセンス 無料 & オープンソース (MIT License) 商用 (有料ライセンス) 無料 (Fiddler Classic) / 商用 (Fiddler Everywhere)
プラットフォーム macOS, Linux, Windows macOS, Windows, Linux Windows (Classic) / macOS, Linux, Windows (Everywhere)
インターフェース CUI (mitmproxy), Web UI (mitmweb), CLI (mitmdump) GUI GUI
スクリプティング Python (非常に強力) 限定的 (Map Local/Remote, Rewrite 등) JScript.NET, C# (Fiddler Classic) / より限定的 (Everywhere)
自動化・CI/CD連携 得意 (mitmdump + Python) 不得意 限定的
学習コスト やや高め (特にCUIとスクリプティング) 比較的低い (GUI中心) 比較的低い (GUI中心)

mitmproxyの強み:

  • 無料でオープンソースであること。
  • 強力なPythonスクリプティング機能により、高度な自動化やカスタマイズが可能。
  • CUI/CLIツールが充実しており、サーバー環境や自動化パイプラインでの利用に適している。

mitmproxyの弱み(他のツール比):

  • GUI (mitmweb) は比較的新しく、CharlesやFiddlerほど洗練されていない部分もあるかもしれない。
  • CUIやスクリプティングに慣れていないユーザーにとっては、初期の学習コストがやや高い可能性がある。

どのツールを選ぶかは、目的、予算、好み、必要な機能によって異なります。自動化や高度なカスタマイズを重視するなら、mitmproxyは非常に有力な選択肢となるでしょう。 👍

まとめ ✨

mitmproxyは、HTTP/HTTPS通信の傍受、検査、改変、リプレイを可能にする強力なオープンソースのプロキシツールキットです。コンソール、Web UI、コマンドラインの3つのインターフェースを持ち、特にPythonによる高度なスクリプティング機能が特徴です。

Web開発のデバッグ、APIテスト、モバイルアプリ解析、セキュリティ診断など、幅広い用途でその力を発揮します。HTTPS通信を扱うための証明書設定や、各種機能、スクリプティングを理解することで、ネットワーク通信に関する問題解決や分析作業を大幅に効率化できるでしょう。

無料で利用でき、コミュニティも活発なので、ぜひ一度試してみてはいかがでしょうか。きっとあなたの開発やテストの強力な武器になるはずです! 💪

コメント

タイトルとURLをコピーしました