HTTP CONNECT:HTTPプロキシはHTTPSをどう扱うのか
HTTPSリクエストがHTTPプロキシを通る流れを追い、CONNECT応答とオリジンサーバーの応答を区別して、トンネルの失敗箇所を見つけます。
「200 Connection Established」は、プロキシがトンネルを受け入れたという意味です。Webサイトからページが返ったわけではありません。この後に宛先とのTLSが続き、その次にHTTPSリクエスト自体を送ります。
プロキシ接続からWebサイトの応答まで
- クライアントがプロキシのエンドポイントに接続します。
- プロキシに、宛先ホストとポートへの接続を要求します。
- プロキシがその要求を受け入れるか、拒否します。
- 受け入れられると、クライアントはトンネルを通して宛先とTLSをネゴシエートします。
- クライアントがTLS内でHTTPSリクエストを送り、Webサイトの応答を受け取ります。
プロキシへの接続拒否、トンネルの拒否、証明書エラーは、この流れの別々の箇所で起こります。設定を変える前に、最後に完了した手順を確認してください。
CONNECTのやり取り
HTTP/1.1でのやり取りを簡略化すると、次のようになります。
CONNECT example.com:443 HTTP/1.1
Host: example.com:443
HTTP/1.1 200 Connection Established
リクエストの対象はホストとポートであり、Webサイトのパスやクエリは含みません。CONNECT応答が成功すると、接続はトンネルのバイト列を運びます。HTTPSの宛先なら、クライアントの次のやり取りはTLSハンドシェイクです。
英語の理由句との文字列一致ではなく、数値のステータスを読み取ります。同じステータスでも、プロキシによって文言が異なる場合があります。
curlで観察する
ローカルのポート8080にHTTPプロキシがある場合:
curl --noproxy '' --proxy http://127.0.0.1:8080 --connect-timeout 5 --max-time 15 --verbose https://example.com/待ち受けアドレスを自分のエンドポイントに置き換えます。候補が必要なら、HTTPプロキシ一覧を見て選んだ項目をテストしてください。除外リストが空なので、この呼び出しではプロキシが選ばれます。時系列に、プロキシへの接続、CONNECT応答、宛先証明書の検証、Webサイトの応答を探します。ログの具体的な文言はcurlのビルドによって異なります。
プロキシがトンネルを受け入れた後でも、宛先は404、429、500を返すことがあります。HTTP応答を返す前に、TLS中に失敗する場合もあります。
どこで止まったか
| 観察結果 | 次に調べること |
|---|---|
| プロキシへの接続が拒否される | プロキシのアドレス、待ち受けポート、プロセス、ネットワークアクセス。 |
| プロキシが407を返す | プロキシのアカウントと認証方式。 |
| プロキシが宛先やポートを拒否する | アクセス方針と、CONNECTで許可される宛先。 |
| トンネルは開くが、その後TLS検証が失敗する | 宛先名、トラストストア、時計、管理されたTLS傍受の有無。 |
| TLSは成功し、Webサイトがエラーを返す | Webサイトの応答。 |
比較するときは片側を固定します。同じプロキシで別の宛先を試すか、許可された直接経路で同じ宛先と比較してください。
トンネルにも運営者がいる
プロキシはCONNECTの宛先を把握し、通信のタイミングと量を扱います。通常のエンドツーエンドTLSは、そのTLSセッションを終端しないプロキシから、Webサイトのアプリケーション内容を保護します。クライアントが信頼する管理された傍受プロキシでは、信頼関係の仕組みが異なります。