Introduction
忘備録。
そもそもの動機は透過プロキシを利用してプロキシを無視する flutter の通信を、透過プロキシによって無理やりプロキシ経由の通信にするのが始まりだった。
Wi-Fi 共有でアクセスしてくる iPhone 端末の flutter アプリにプロキシ通信をさせたかった。
実行環境は MacOS Sequoia 15.3。
How to do?
1. Wi-Fi 共有
Wi-Fi 共有を有効にする。
2. Wi-Fi インターフェースの確認
Wi-Fi 共有を使うと出現するインターフェースを調べる。
1 | $ ifconfig | grep bridge |
ここでは bridge100
であることがわかる。
余談だが networksetup -listallhardwareports
ではこの追加されるインターフェースは見えないので注意。
ここで bridge0
が目的のインターフェースと勘違いすると、後の mitmproxy の起動で通信を傍受できないので詰む。
3. mitmproxy のインストール
1 | $ brew install mitmproxy |
4. IP フォワーディングを有効にする
1 | $ sudo sysctl -w net.inet.ip.forwarding=1 |
UNIX 系のオペレーティングシステムで IP フォワーディングを有効にするコマンド。
IP フォワーディングとは、システムがルーターのように機能し、異なるネットワーク間でIPパケットを転送できるようにする機能。
無効にする場合は
1 | $ sudo sysctl -w net.inet.ip.forwarding=0 |
5. パケットフィルター (PF) の設定
1 | # バックアップ |
デフォルトの設定に対して追記する。
1 | scrub-anchor "com.apple/*" |
custom
という単語に特に意味はない。rdr-anchor
コマンドは、リダイレクトルール(NAT やポートフォワーディングルールなど)のためのアンカーポイントを定義するために使用。
アンカーは、 pf.conf
の中でルールをグループ化し、管理を容易にすることで特定のアンカーに対して個別にルールセットを動的に読み込んだり、変更したりすることが可能になる。
つまり、自分が作った定義に名前を付けるだけである。
5. ファイヤーウォールを有効にする
6. Wi-Fi 共有を経由するパケットを mitmproxy に向ける
先に書いた load anchor
の記述に対応して設定を定義。
1 | $ sudo vi /etc/pf_custom.conf |
ここでは mitmproxy
によるローカルプロキシが 127.0.0.1:8080 で動作する前提。
1 | + rdr on bridge100 inet proto tcp to any -> 127.0.0.1 port 8080 |
7. パケットフィルタの適用
追記した内容を適用する。
1 | $ sudo pfctl -ef /etc/pf.conf |
8. /etc/sudoers の修正
sudo pfctl -s state
を全てのユーザーが実行できるように設定を追記。
1 | $ sudo visudo |
1 | + ALL ALL=NOPASSWD: /sbin/pfctl -s state |
9. mitmproxy の起動
1 | $ mitmproxy --mode transparent --showhost |
古いバージョンだと mitmproxy -T --host
になるが、現時点 (mitmproxy 11.1.3) だと非推奨になっている。
10. CA 証明書のインストール
mitmproxy
の役割は透過プロキシであり、名前が示す通り MITM = Man-In-The-Middle : 中間者である。
そのため、クライアントに対して https 通信に必要なオレオレ CA 証明書を Wi-Fi 共有に接続する端末にインストールする。
Mac の Wi-Fi 共有にアクセスし、 http://mitm.it
にアクセスする。
今回は iOS なので iOS の ca-cert.pem を選択してダウンロード。
許可を求められるので許可する。
ダウンロードされる。
iOS の 設定 -> 一般 -> VPN とデバイス管理 に移動。
先にダウンロードしたプロファイルが表示されている。
プロファイルを選択。
インストールを実行。
インストール完了。
iOS の 設定 -> 一般 -> 情報 -> 証明書信頼設定 に移動。
mitmproxy を選択。
続ける を選択し、証明書を有効にする。
10. クライアントの通信を傍受
試しにクライアントで https://github.com にアクセス。
通信内容が mitmproxy に表示される。