他者の発行したオレオレROOT証明書を信頼しないと安全に通信できない 外部 HTTPS Server
がある場合に、
許可外のサーバーの通信内容を盗聴・改ざんされないようにする
- 他者の発行したROOT証明書の影響範囲を制限する
- ※ OS組み込みのROOT証明書以外
- 自分で発行したROOT証明書だけを信頼すれば良くなる
- HTTPプロキシサーバー(DMZ)でTLSが復号されている場合にも対応
- HTTPSリクエストに割込み
- プロキシで割込み
Clientアプリ(ブラウザなど)
はLocal Proxy Server
に TCP中継 (CONNECT
) 要求Local Proxy Server
はMITM HTTPS Server
に中継する- ※ 接続先指定を無視し、全てを
MITM HTTPS Server
に中継
- ※ 接続先指定を無視し、全てを
Clientアプリ
はLocal Proxy Server
経由でMITM HTTPS Server
にHTTPSリクエスト
- 名前解決で割込み
Clientアプリ(ブラウザなど)
は対象のドメイン名の名前解決要求を出す- ※ 事前にプロキシの例外に追加しプロキシサーバーが使われないようにしておく
- hosts がローカルの
MITM HTTPS Server
の IPに名前解決する- ローカルのIP
- 設定キー:
FORWARDING_SERVER_BIND_IP
- 例:
127.9.9.9
- 設定キー:
- ※ 事前にhosts ファイルで書き換え対象のドメイン名をローカルのIPに名前解決されるようにしておく
- ローカルのIP
Clientアプリ
は名前解決で得られたローカルのIP (MITM HTTPS Server
) にHTTPSリクエスト- ポート番号はデフォルト
443
( 環境変数TARGET_PORT
で設定可能)
- ポート番号はデフォルト
- プロキシで割込み
Clientアプリ
-MITM HTTPS Server
間でTLS接続が成功- ※ 事前に
MITM HTTPS Server
のROOT証明書を信頼するようにしておく
- ※ 事前に
MITM HTTPS Server
はプロキシが処理可能なリクエストに変換してからプロキシサーバーへリクエスト- Host ヘッダーから実際の接続先FQDN & ポート番号を取得しプロキシサーバーへCONNECTリクエスト
- ポート番号: デフォルト(明示されていない場合)は
443
- ポート番号: デフォルト(明示されていない場合)は
- Host ヘッダーがない場合は
- 接続先FQDN: TLS Handshake の 拡張 (Server Name Indication)
- ポート番号: 環境変数
TARGET_PORT
( デフォルト443
)
- Host ヘッダーから実際の接続先FQDN & ポート番号を取得しプロキシサーバーへCONNECTリクエスト
- プロキシサーバーが代理で
外部 HTTPS Server
とTCP接続 MITM HTTPS Server
-外部 HTTPS Server
間でTLS接続が成功- ※ 事前に
MITM HTTPS Server
内でのみ外部 HTTPS Server
のROOT証明書を信頼するようにしておく.env
のroot_cert_file_name
設定
- ※ 事前に
Clientアプリ
-外部 HTTPS Server
間でHTTP通信
- docker, docker-compose をインストール
- ROOT証明書を作成
sh generate-root-key.sh
- 引数1:
ROOT_CERT_COMMON_NAME
- ROOT証明書の「発行先」・「発行者」
- 任意 (デフォルトは
"Private CA"
)
- 引数2:
ROOT_CERT_LIFETIME_DAYS
- ROOT証明書の「有効期限」 (単位: 日)
- 任意 (デフォルトは
30
)
- 引数1:
- 生成した ROOT証明書
./.generated/root.crt
を信頼- 証明書を開いて
信頼されたルート証明機関
にインストールする
- 証明書を開いて
- 信頼する必要のある「他者の発行したROOT証明書」を
./.provided-root-ca
に配置する- ファイル名は
.env
で指定するため自由
- ファイル名は
- 設定
- 設定ファイルを作成:
.env.example
を.env
にコピー(既に存在するならばスキップ)cp --no-clobber .env.example .env
- 設定ファイル
.env
を必要に応じて編集- ※ Docker Machine を使っている場合は、
FORWARDING_SERVER_BIND_IP
,HTTP_PROXY_SERVER_BIND_IP_PORT
には127.0.0.0/8
のIPではなく、docker-machine ip
で得られるIPを設定する必要がある$ docker-machine ip 192.168.99.100
- ※ Docker Machine を使っている場合は、
- 設定ファイルを作成:
- 通信経路を変更(以下のどちらかを選択)
- プロキシで割込み
- プロキシサーバー設定を変更
- 対象ドメイン (
.env
のTARGET_DOMAINS
に書いたドメイン) 宛の通信をHTTP_PROXY_SERVER_BIND_IP_PORT
で指定したIP:PORTのプロキシを使うようにする - 対象IP (
.env
のTARGET_IPS
に書いたIP) 宛の通信をHTTP_PROXY_SERVER_BIND_IP_PORT
で指定したIP:PORTのプロキシを使うようにする - ※ 他ドメイン・IP宛は元のプロキシ/DIRECTから変更しない
- プロキシ自動設定ファイル など個別設定できるもの推奨
- 対象ドメイン (
- プロキシサーバー設定を変更
- 名前解決で割込み (※ IPアドレス宛は対応不可)
- hosts ファイルを変更
- 対象ドメイン (
.env
のTARGET_DOMAINS
に書いたドメイン) がFORWARDING_SERVER_BIND_IP
で指定したIPに名前解決されるようにする127.9.9.9 example.com example.net
- Windowsの場合
C:\Windows\System32\drivers\etc
- ※ Windowsの場合、1行のエイリアスの最大数は
8
である点に注意
- ※ Windowsの場合、1行のエイリアスの最大数は
- 対象ドメイン (
- 対象ドメインをプロキシの例外に追加(プロキシサーバーを使わないようにする)
- ローカルの hosts を使用して名前解決されるようにしてDockerコンテナ内の
MITM HTTPS Server
にリクエストが飛ぶようにする必要があるため
- ローカルの hosts を使用して名前解決されるようにしてDockerコンテナ内の
- hosts ファイルを変更
- プロキシで割込み
MITM HTTPS Server
&Local Proxy Server
を起動docker-compose up --build -d
- HTTPプロキシサーバー経由で
外部 HTTPS Server
にアクセスしていること - リクエスト中に元のリクエスト先FQDNが含まれていること
- クライアントが Server Name Indication に対応していること or Host ヘッダーが存在すること
- Host ヘッダーが存在しない場合、転送先ポートは
TARGET_PORT
に指定した番号のみ対応- ※ Host ヘッダーが存在 & プロキシで割込みの場合は任意のポート番号に対応