HTTP・HTTPSプロキシ
HTTPプロキシは、ブラウザーやアプリのウェブリクエストを受け、代わりに接続先へ接続します。通常のHTTP通信に加え、CONNECTメソッドに対応すれば暗号化されたHTTPS通信も運べます。HTTPSプロキシは、アプリとプロキシ自体の間の接続も暗号化します。
アプリがプロキシにどう接続するかと、その先のサイトにどう通信するかは、別々の選択です。両方を理解すると適切な接続設定を選べます。プロトコル全般の比較はSOCKSとHTTPプロキシで説明しています。
HTTPプロキシがウェブリクエストを扱う方法
監視スクリプトがhttp://example.com/catalogを要求するとします。サイトへ直接接続せず、設定したプロキシに接続します。HTTP/1.1では完全な接続先URLを送るため、プロキシはどのサーバーとページにアクセスするか分かります。要求を転送し、サイトの応答をスクリプトへ返します。
この方式では、プロキシがHTTPメッセージを処理します。GETやPOSTなどのメソッド、要求アドレス、ヘッダー、送信データを読めます。対応する設定があれば、アクセス規則、リクエスト記録、対象応答のキャッシュを使えます。キャッシュは応答のキャッシュ規則に従う任意機能で、HTTPプロキシを購入しても全ページが保存されるわけではありません。
サイトはプロキシの出口IPから接続を受け取ります。HTTPという用語はIPの由来や割り当て期間を示しません。同じプロトコルを、データセンター、ISP、住宅用、モバイルのアドレスと、固定IPやローテーションプールの組み合わせで提供できます。
HTTPプロキシでHTTPSサイトを開く方法
HTTPSサイトは、アプリとサイト間のやり取りをTLSで守ります。HTTPプロキシは、それを運ぶためにまずトンネルを作ります。https://example.com/catalogの要求は、次の順序です。
- アプリがプロキシに接続し、
example.com:443へのトンネルをCONNECTメソッドで要求します。指定するのはホストとポートで、ページのパスは含みません。 - プロキシは、必要な認証も含め、アクセスと接続先が許可されているか確認します。接続先への接続を開き、トンネルの準備完了を知らせます。
- アプリはトンネルを通してサイトとTLSハンドシェイクを行い、サイトの証明書を検証します。
- アプリはTLS接続内でウェブリクエストを送ります。プロキシは暗号化されたバイト列を双方向に中継します。
ページを届けるために、プロキシが読む必要はありません。サイトのTLS接続の両端はアプリとサイトのままです。CONNECTがトンネルを、TLSが暗号化と、検出されない改変からの保護を提供します。
このため、プロキシアドレスがhttp://で始まってもHTTPSサイトを開けます。サイトのHTTPS保護はトンネル内で動き、アプリとプロキシ間のTLSには依存しません。
HTTPSプロキシが追加するもの
HTTPSプロキシでは、まずアプリがプロキシとTLSを確立し、その証明書を検証します。その保護された接続内で、HTTP要求やトンネル用のCONNECTを送ります。アプリとプロキシの間の観測者は、それらを読めません。
HTTPS接続先では、アプリは2本の独立したTLS接続を維持します。1本はプロキシと、もう1本はトンネルを介してサイトとつながります。プロキシは自分宛ての外側の保護を外しますが、中のサイトデータは暗号化されたままです。それを復号できるサイトへ転送します。HTTP接続先では内側のTLSがなく、プロキシまでの接続だけが保護されます。
| プロキシへの接続 | 接続先 | 暗号化されるもの |
|---|---|---|
| HTTP | HTTPサイト | どちらの接続もTLSを使わず、経路上で要求と応答を読めます。 |
| HTTP | HTTPSサイト | サイトの通信はトンネル内で暗号化されます。プロキシへの接続では、CONNECTとプロキシ認証にTLS保護はありません。 |
| HTTPS | HTTPサイト | TLSがプロキシまでを守ります。プロキシは要求を読め、TLSなしでHTTPサイトへ転送します。 |
| HTTPS | HTTPSサイト | TLSがプロキシ宛ての要求を守り、別のTLSがトンネル内のサイト通信を守ります。 |
これは証明書検証を有効にし、HTTPS検査や別のVPNを使わない通常の転送の比較です。プロキシへの接続を暗号化しても、HTTPサイトがHTTPSに変わるわけではありません。
プロキシとサイトに見えるもの
HTTPS接続先では、転送プロキシはTLS内のページパス、クエリ、Cookie、フォームデータ、応答内容を読めません。ただし、接続したクライアントIP、CONNECTで要求されたホストとポート、通信時刻と量は分かります。プロキシへのTLSは、区間内の観測者からCONNECTを隠しますが、要求を実行するプロキシ自体からは隠しません。
プロキシ認証情報は、サイトのログインと別に送ります。Basic認証はユーザー名とパスワードをBase64で符号化しますが、秘密鍵なしで復元できます。通常のHTTPプロキシ接続では観測者から守れません。サイトのHTTPSはトンネル内で始まり、先に行ったプロキシログインは対象外です。プロキシへのTLSが、そのログインを転送中に保護します。
反対側では、サイトが出口IPから通信を受け、自分宛ての要求を読みます。アカウント、セッションCookie、アプリが送った情報を識別できます。HTTPSプロキシを選んでも、これらが消えたり、出口IPが自動的に受け入れられやすくなったりはしません。
HTTPS検査は、一部の管理ネットワークやデバッグツールで使う別の構成です。アプリが検査プロキシの管理する認証局を信頼すると、両側に別々のTLS接続を維持して内容を読めます。通常のCONNECT転送でその証明書の導入は不要です。HTTPSプロキシ自体の証明書を信頼することと、サイトのなりすましを許可することは別です。
接続設定の読み方
プロキシ設定には、アドレス、ポート、接続プロトコル、必要な認証が要ります。プロキシURLのプロトコルはプロキシ、接続先URLのプロトコルはサイトに適用されます。
以下のcurlコマンドは、異なる2種類のプロキシ接続から同じHTTPSサイトを要求します。ホスト名とポートは、選んだ方式用に提供された値に置き換えてください。
curl --proxy http://proxy.example:8080 https://example.com/
curl --proxy https://proxy.example:8443 https://example.com/
最初はHTTPでプロキシに接続し、その後CONNECTとサイトへのTLSを作ります。2番目は先にHTTPSプロキシへのTLSを作り、内部に独立したサイトTLSを通します。どちらも、サービスが要求する認証を別途指定します。
http://をhttps://に変えるだけでは、HTTP専用ポートはTLS接続先になりません。HTTPS用ホスト名があるなら、その名前を使います。IPに置き換えると証明書の名前不一致を起こす場合があります。
アプリの表示も注意して読みます。「HTTPSプロキシ」という欄は、HTTPSサイト用のプロキシを選ぶだけで、プロキシには通常のHTTPでつなぐ場合があります。curlのHTTPS_PROXYもHTTPS接続先用を選ぶため、値がhttp://で始まっても正しい設定です。表示名は対象の要求を、URLのスキームは接続方法を示します。
DNSとプロキシ経由の通信
HTTPクライアントが接続先ホスト名を渡すと、通常はプロキシがIPを調べて接続します。プロキシ自体の名前が必要なら、クライアントが別途照会します。ブラウザーが予測などの機能でDNSを使う場合もあります。これらは別の照会で、ウェブプロキシを設定しても全DNS要求が通るわけではありません。
設定の対象は、アプリが実際にプロキシへ送る通信です。別プログラムは直結を続け、例外リストで特定サイトを迂回する場合もあります。たとえばAPIスクリプトをプロキシ経由にしても、無関係なブラウザーの経路は変わりません。実際にタスクを動かすアプリと構成から出口を確認します。
サイトへのHTTP/2とプロキシへのHTTP/2
HTTP/2は別々のストリームで複数のやり取りを1接続にまとめます。プロキシでは、どの接続が対応するかが重要です。アプリはサイトとHTTP/2を交渉でき、それはHTTP/1.1 CONNECTで作ったトンネル内でも可能です。プロキシは暗号化バイト列を中継するため、サイトのHTTP/2を理解する必要はありません。
アプリとプロキシ間のHTTP/2は別機能です。各CONNECTトンネルが独自のHTTP/2ストリームを使い、複数トンネルで1接続を共有できます。たとえば別々の2サイトへのトンネルが、その接続を共有しつつ、接続先接続とサイトTLSセッションを分離できます。クライアントからの追加接続を減らしますが、暗号化要求をプロキシが読めるようにはしません。
選んだ方式に両端が対応する必要があります。HTTPSだけでHTTP/2とは決まらず、HTTPSプロキシもHTTP/1.1を使えます。性能はクライアント、経路、サーバー負荷、接続再利用にも左右されます。HTTP/2は全タスクの高速化保証ではありません。
通常のCONNECTは、両端が許可すれば別のTCP系プロトコルも運べますが、接続先ポートが制限される場合があります。UDPは中継しません。HTTP/3はUDP上のQUICなので、同じTCPトンネルを同様には通れません。HTTPのUDP転送はCONNECT-UDPなどの追加方式と互換実装が必要です。HTTPSやHTTP/2だけの対応では、それらの対応は分かりません。
HTTP・HTTPSアクセスが役立つ用途
閲覧やサイトテストでは、CONNECT対応HTTPプロキシが、HTTP・HTTPS双方の接続方法を提供します。チームはプロキシのネットワークからサイトを見つつ、ページ描画、Cookie、ログインはブラウザーに任せられます。
クローラー、APIクライアント、定期監視では、HTTPクライアントがURLを変えずに指定出口IPから要求できます。要求の準備と応答処理はアプリの役割です。HTTPSトンネル内では、プロキシは各ページやAPI呼び出しを解析せずに運べます。
ログインと接続先要求を含め、プロキシまでの接続も守る必要があるとき、TLSで保護するHTTPSプロキシが有用です。管理できないネットワークを通る場合に重要です。クライアントはプロキシ自体へのTLSに対応する必要があり、HTTPSサイトを開けるだけでは不十分です。
接続エラーの読み方
プロキシへの到達、トンネル作成、サイト通信のどこでも失敗します。エラーコードだけでなく、段階が重要です。
| 現象 | 確認する場所 |
|---|---|
| プロキシが407を返す | プロキシが認証を要求しています。認証情報とアクセス方式を確認します。サイトアカウントは別のログインです。 |
| HTTPは動くがHTTPSは動かない | HTTPSに予定のプロキシを使っているか、CONNECTと接続先ポートが許可されるかを確認します。 |
| TLSまたは証明書のエラーが出る | プロキシ接続とサイト接続のどちらのエラーかを特定します。証明書検証を無効にせず、対象ホスト名、TLS接続先、証明書の信頼を確認します。 |
| 403が返る | CONNECTの拒否はプロキシからです。正常に確立・検証したHTTPS接続内の403は、サイトの応答です。段階が異なり、対処も異なります。 |
トンネルとTLSハンドシェイクの成功は、経路の動作を示します。しかし、特定アカウント、出口IP、要求の受け入れは保証しません。プロキシが動いていても、ログイン確認、CAPTCHA、頻度制限は、サイトやアプリ側で対応が必要な場合があります。
