0xA

CONNECT メソッド (HTTP)

[5] HTTPCONNECT メソッドは、 プロキシをすり抜けるトンネルを確立することを求めるものです。

[47] このメソッドHTTPS 通信がプロキシを通過するために使われています。

仕様書

意味

[50] CONNECT メソッドは、 要求対象によって識別される起源鯖を出口とするトンネルを確立し、 成功した場合には、トンネルが閉じられるまでの間、 パケットを盲目的に転送するだけの動作をすることを受信者に対して要求するものです >>49

C
クライアント
P
S
C -> P
への CONNECT 要求
P ## S
接続の確立
P -> C
200 応答
C ## S
以後は無変更でクライアント間を中継
C ## S
は一方の接続が閉じられたら、他方の接続も閉じる

[65] CONNECT は、動作としては Upgrade: によるプロトコルの切り替えと然程違いません。どちらも一旦切り替えられると元の HTTP とは異なるプロトコルの規定に支配される接続となり、 基本的に元の HTTP に戻ってくることはできません。それでも Upgrade: は理論上は元の要求の処理をが新しいプロトコルで継続することが期待されるのに対し、 CONNECT は新しいプロトコルではじめから通信が始まることが期待されています。 また Upgrade:受信者であるが直接処理することを期待されているのに対し、 CONNECT受信者自身ではなく中継された先にあるはずのが処理することが期待されているという大きな違いがあります。

[14] CONNECT メソッドは、主として HTTP プロキシを通して https 資源にアクセスするために起源サーバーとの間に TLSセッションを確立するために使います >>12

[15] RFC 7540CONNECT のことを 「疑似メソッド (pseudo-method) 」と呼んでおり >>12、 それがどういう意味かは不明ですが、通常の要求メソッドとは性質が違うことをほのめかしています。

[16] HTTP/2 では CONNECT メソッドは、 (接続全体ではなく) ストリームにおいてトンネルを確立するために使います >>12


[48] このような動作をするものは一般的にはプロキシと呼ばれていますが、 RFC 7230 の用語では中間器の一種であるトンネルに分類されています。

文脈

[75] CONNECT メソッドは、 HTTPS の通信にプロキシを通過させたい時に使われます。

[76] 素のHTTPプロキシは、プロキシ素のHTTPで接続し、 プロキシがこれを一旦解釈してから接続先のサーバーへと中継します。 しかし、これと同じ方法では HTTPSTLS の目的である盗聴改竄の防止が実現できません (プロキシの挙動は盗聴改竄そのものだからです)。 そのため、プロキシがデータを無条件に中継し何の解釈も行わないトンネルモードへと CONNECT メソッドで切り替えてから、 TLSサーバーとの間を結ぶ方法を採るのです。

[78] プロトコルの階層関係を図にすると、次のようになります。

     <----------------- HTTP ---------------->
     <----------------- TLS ----------------->
     <- HTTP (CONNECT) -> <------ TCP ------->
     <------ TCP ------->
クライアント         プロキシ             サーバー

構文

[54] HTTP/1.1 以下CONNECT 要求要求対象は、 authority-form でなければなりません >>49

[17] HTTP/2 では、疑似ヘッダーを次のようにします。

[62] CONNECT 要求payload の意味は定義されていません。 >>49

[63] payload body があると実装によっては要求を拒絶するかもしれません。 >>49

[34] Chrome は次のヘッダーを指定するようです。

[35] Firefox は次のヘッダーを指定するようです。

[36] IE は次のヘッダーを指定するようです。

性質

[64] CONNECT 要求に対する応答は、 キャッシュ可能ではありません >>49

処理

[51] CONNECT 要求に対する要求での利用のみを想定しています >>49

[22] HTTP/2>>17疑似ヘッダーの制約に違反する場合は、 奇形です >>12

[55] は、要求対象に直接接続しても構いませんし、 他のを使うよう設定されている場合には次の内向きCONNECT 要求転送しても構いません >>49

[84] MITM proxy として動作するプロキシは、 自身が CONNECT のデータを読み書きする HTTPS サーバーとして動くことになります。 MITM proxy

[23] CONNECT に対応する HTTP/2 プロキシは、 :authority 疑似ヘッダーで識別されるサーバーへの TCP接続を確立します。確立に成功したら、 状態符号 2xxHEADERS フレームクライアントに送信します。 >>12

[52] 自身への CONNECT 要求を受信した起源鯖は、 接続が確立されたことを示す 2xx 応答を返しても構いません >>49

[57] 持続接続により引き続き HTTP接続の処理が継続されているのか、 CONNECT によってトンネルとして動作しているのか、 クライアント側から判別する方法はありません。
[53] ただしほとんどの起源鯖は、 CONNECT を実装していません >>49

[60] トンネルの確立は大きな危険を生じさせるものですから、は、 既知のポートや安全な要求対象ホワイトリストにより、 CONNECT の利用を制限するべきです >>49

[46] CONNECT 要求に対する 2xx 応答は、メッセージ本体を持ちません >>45, >>49

[24] HTTP/1.1 以下では、メッセージ本体の代わりに、 ヘッダーの次の CRLF の直後から、トンネルモードに切り替わります。 >>45, >>49

[61] は、 Transfer-Encoding:Content-Length:2xx 応答に含めてはなりません >>49クライアントはこれらを無視しなければなりません >>49

[25] HTTP/2 では、 最初の HEADERS フレームの後、 以後のすべての DATA フレームTCP接続上のデータに対応します。 クライアントから送信された DATA フレームプロキシから TCPサーバーへと送信され、 TCPサーバーから受信したデータはプロキシからクライアントへと DATA フレームで送信されます。 >>12

[26] DATA フレームストリーム管理のためのフレーム (RST_STREAM, WINDOW_UPDATE, PRIORITY) を除き、当該ストリームを使って送信してはならず、 受信したらストリームエラーとしなければなりません>>12

[56] 2xx 以外の応答は、トンネルが形成されていないことを表し、 トンネルとしてではなく HTTP による解釈を継続するべきものです >>49

[58] HTTP/1.1 以下トンネルは、そのいずれかの側の接続が閉じられたと検出した時、 閉じられます。その場合、閉じられた側からの残りのデータをすべて送信し、 両方の接続を閉じ、残ったデータがあれば捨てる、という処理を試みなければなりません>>49

[27] HTTP/2 では END_STREAM フラグTCP FIN フラグに相当します。クライアントは、 END_STREAM フラグが設定された DATA フレームを受信したら、 END_STREAM フラグが設定された DATA フレームを送信することが期待されています。 プロキシは、END_STREAM フラグが設定された DATA フレームを受信したら、 FI ビットを設定した TCPセグメントを最後に送ります。プロキシFIN ビットが設定された TCPセグメントを受信したら、 END_STREAM フラグが設定された DATA フレームを送信します。 >>12

[28] 最後の DATA フレームTCPセグメントは、 空になることもあります。 >>12

[29] HTTP/2 プロキシは、 RST ビットが設定された TCPセグメントをはじめとする TCP接続のエラーを検出したら、ストリームエラー CONNECT_ERROR とします。 >>12

[30] HTTP/2 プロキシは、 HTTP/2ストリーム接続でエラーを検出したら、 RST ビットが設定された TCPセグメントを送信しなければなりません >>12

[31] HTTP/1.1 以下でも同じようにエラー処理が必要なのかもしれませんが、 RFC では規定されていません。

[33] CONNECT は、 TCP接続を維持しなければならず、 その分の資源を消費することに注意が必要です。 CONNECT が閉じられた後も TIME_WAIT 状態の間、 TCP接続の情報を残す必要があることにも注意が必要です。 設定 SETTINGS_MAX_CONCURRENT_STREAMS とは別に CONNECT資源消費にも制限が必要かもしれません。 >>32

[6] トンネル内では HTTPS (HTTP over TLS) を用いるのが主たる用途ですが、 TCP で動作する任意のプロトコルを使うことができます。 トンネルとしてはどのようなプロトコルが使われているか感知しません。

[37] HTTPS プロキシとしての利用の際、 Firefox応答を待たずにヘッダーと空行の後直ちに TLS を開始します。 ChromeIE は、応答を待ちます。 応答200 以外の場合、 ChromeIE接続を閉じますが、 Firefox接続が閉じられるのを待ちます。 ただし 101 なら直ちに閉じます。

[83] curl200 以外の 2xx をエラーとして扱います。

[80] 仕様上は 200 以外の 2xx を返すこともできますが、 実際には使えないということです。サーバークライアントで何をトンネルと解釈するかが異なると HTTP としての解釈とトンネルデータの区分が両者で異なり、 セキュリティー問題を引き起こす危険性があります。 クライアントChrome 同様にエラーと扱うべきでしょう。

[77] 仕様上は CONNECT 要求に対して 200 以外の応答を返した場合に、 持続的接続で次の要求を送ることができます。実際には Webブラウザー407HTTP認証情報付きで CONNECT を再送信する以外で失敗した接続を再利用することはありません。 また、 CONNECT 以外で使ったHTTP接続CONNECT を送信することもありません (が認められてはいます)。

[79] 応答を待たずに要求直後にトンネルデータの送信を開始する場合、 200 以外の応答が返った場合に次の要求を送れないことになります。 場合によっては、トンネルデータがHTTP要求と解釈されてしまい困るかもしれません。

[68] FirefoxChromeHTTP/0.9 応答ネットワークエラーとします。

[69] FirefoxChrome も、 HTTP/1.0HTTP/1.1 かは動作に影響しません。

[38] FirefoxChromeIE も、 1xx はエラーとみなし、その後の応答を待ちません。

[39] FirefoxChromeIE も、 407Proxy-Authenticate: があれば、 モーダルダイアログを表示します。

[40] FirefoxChrome持続的接続により 407接続を再利用しようとします。 IE は再利用しないようにみえます (が条件次第で再利用するかもしれず断言はできません)。

[41] ChromeIE200 応答Content-Length: は無視するようです。しかし ChromeContent-Length: が不正かどうかのチェックは行っているようです。

[42] ChromeFirefoxIE も、 200 応答Connection: closeProxy-Connection: close は無視するようです。

誤り符号 CONNECT_ERROR

[11] 誤り符号 CONNECT_ERROR (0xa) は、 CONNECT 要求により確立された接続再設定または異常に閉じられたことを表します >>10

セキュリティー

[71] CONNECT は、そのサーバーから接続可能な任意の TCP サーバーに、任意のプロトコルでアクセスできます。従って、 杜撰な実装や設定のサーバーは、攻撃の踏み台として使われてしまいます。

[72] 例えば、イントラネットに接続されたサーバーが外部からアクセス可能になっていて、 CONNECT による接続先の制限が何もなければ、 外部からイントラネットに自由にアクセスできるセキュリティーホールでしかありません。

[73] このため CONNECT メソッドは危険だと言われることがしばしばありますが、 どちらかといえばプロトコルが危険なのではなくサーバーの開発者や管理者の責任でしょう。

歴史

draft-luotonen-web-proxy-tunneling (1998)

RFC 2616

[2] RFC 2616 (HTTP/1.1) 9.9 CONNECT

This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel (e.g. SSL tunneling [44]).

この仕様書は、方式名 CONNECT を、動的にトンネルになるように切り替える (たとえば SSL トンネル化) で使うために予約します。

RFC 2817

[4] RFC 2817CONNECT 要求メソッドを初めて正式に規定する仕様書となりました。

[8] RFC 2817>>1 に言及しつつ、既にで広く実装されている >>3 と述べています。

RFC 723x

[7] RFC 7230RFC 7231 により RFC 2817更新され、 より正確に動作が規定されるようになりました。これにより RFC 2817 の該当部分の規定は失効したものと考えられます。

[13] RFC 7540 >>12HTTP/2 における用法を規定しています。

関連

[59] CONNECT メソッドProxy-Authorization: を含めることで、認証を利用できます。

[201] draft-maes-lemonade-http-binding-04 - IMAP and SMTP HTTP Binding ( ( 版)) http://tools.ietf.org/html/draft-maes-lemonade-http-binding-04#section-2.1.3

[202] draft-maes-lemonade-p-imap-12 - Push Extensions to the IMAP Protocol (P-IMAP) ( ( 版)) http://tools.ietf.org/html/draft-maes-lemonade-p-imap-12#page-47

[9] mod_proxy_connect - Apache HTTP Server Version 2.4 ( 版) http://httpd.apache.org/docs/current/en/mod/mod_proxy_connect.html

[43] 479880 – (CVE-2009-1836) Non-200 responses to proxy CONNECT requests lead to attacks on HTTPS ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=479880

[66] draft-luotonen-web-proxy-tunneling-01 - Tunneling TCP based protocols through Web proxy servers ( 版) https://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01

[67] Issue 7338 - chromium - 30x redirects silently honored in response to CONNECT - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=7338

[70] Issue 433784 - chromium - Malformed CONNECT request to HTTP/2 proxy - An open-source project to help move the web forward. - Google Project Hosting ( 版) https://code.google.com/p/chromium/issues/detail?id=433784

[74] A Proxy-savvy Socket in ActionScript 3 ( ()) http://blogs.adobe.com/cantrell/archives/2006/07/a_proxy-savvy_s.html

[81] draft-ietf-httpbis-h2-websockets-07 - Bootstrapping WebSockets with HTTP/2 () https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-07

[82] Bootstrapping WebSockets with HTTP/2 () https://httpwg.org/http-extensions/draft-ietf-httpbis-h2-websockets.html