Re: Can proxies forward extended CONNECT in HTTP-version and protocol-agnostic manner?

2023年10月6日(金) 2:19 David Schinazi <dschinazi.ietf@gmail.com>:

>
>
> On Wed, Oct 4, 2023 at 11:51 PM Kazuho Oku <kazuhooku@gmail.com> wrote:
>
>> Hi Lucas, Ben, David,
>>
>> Thank you for your responses.
>>
>> 2023年10月4日(水) 14:50 David Schinazi <dschinazi.ietf@gmail.com>:
>>
>>> Hi folks,
>>>
>>> The original analysis seems to focus on the request and response. For
>>> those, I agree with your analysis. However, things get more complicated
>>> after the protocol tunnel is established. In h1 and h2, the only available
>>> HTTP-transport-layer elements are a bidirectional byte stream, so proxying
>>> the bytes unmodified should be safe. In h3, it gets more complicated
>>> because of things like datagrams. Now if you just blindly copy the request
>>> stream's bytestream, you're losing semantic value. (Note that this also
>>> applies to h2, as one could in theory write an extension to h2 that defines
>>> new capabilities at the h2 framing layer.) As Ben points out, an
>>> implementation that supports RFC 9297 could look at datagrams and the
>>> Capsule-Protocol header, but that doesn't help with other extensions.
>>> Another example is WebTransport and the way it ties other QUIC streams to
>>> the WebTransport session.
>>>
>>> So, if the goal is to build an intermediary that translates
>>> automatically between HTTP versions without understanding the protocol, it
>>> will fail any time a new extension to HTTP itself is required for a
>>> protocol to operate. But that's not a deal breaker, just something to
>>> consider. Those extensions to HTTP require settings, so the client
>>> shouldn't be using those protocols if the intermediary hasn't sent the
>>> corresponding setting. So I guess it comes down to: if an intermediary
>>> wants to do this, it really needs to properly handle translating all of the
>>> extensions that it supports.
>>>
>>
>> I totally agree with this analysis.
>>
>>
>>> To throw one more wrench into these gears, the Capsule-Protocol header
>>> was unfortunately defined to be optional so an intermediary that receives
>>> HTTP/3 :protocol=connect-udp but without Capsule-Protocol=?1 won't know
>>> what to do with datagrams it receives. I vaguely remember that the intent
>>> of the proponents of making Capsule-Protocol optional was explicitly to
>>> prevent doing this type of conversion.
>>>
>>
>> Oh I missed the fact that the capsule-protocol header is optional.
>>
>> Even if that is the case, theoretically an intermediary can discover that
>> the streams must have been using capsule protocol at the moment it receives
>> a HTTP datagram, then retroactively decode the bytes exchanged on the
>> streams to determine whether the boundaries of each capsule is, and start
>> transcoding HTTP datagrams to capsules or vice versa. Such design is
>> possible because IIRC RFC 9297 requires use of capsule protocol on the
>> streams at the same time.
>>
>
> That's not right. RFC 9297 does not require using the Capsule protocol:
> <<Additionally, HTTP extensions can use HTTP Datagrams with their own data
> stream protocol.>>
> https://www.rfc-editor.org/rfc/rfc9297#section-3.5-10
> It's allowed to create a new :protocol that uses HTTP Datagrams with a
> custom stream encoding.
>

Thank you for the correction!


>
> But yeah I agree that it's tricky and that it is questionable if such an
>> approach would make sense in the long run.
>>
>> I think I am becoming convinced that probably having an allow list is the
>> correct answer here.
>>
>
> That would be safe. Implement the automatic conversion but only enable it
> for an allowlist of :protocols. New ones are rare so keeping that list
> up-to-date shouldn't be too hard.
>
> For the virtue of laziness as a programmer, maybe I can let the users
>> configure the allow list and make it their problem instead of mine :-)
>>
>>
>>> Anyway, apologies for the long ramble. Based on all this, it's probably
>>> not safe to convert unknown HTTP upgrade tokens between HTTP versions.
>>>
>>> David
>>>
>>> On Wed, Oct 4, 2023 at 1:56 PM Ben Schwartz <bemasc@meta.com> wrote:
>>>
>>>> I think conversions between HTTP/2 and HTTP/1.1 would require a new
>>>> standards-track RFC to codify the usage of "GET" (and possibly revise our
>>>> interpretation of the "HTTP" and "TLS" upgrade tokens), but otherwise it
>>>> should be fine.  That document would have to incorporate some
>>>> requirements related to
>>>> https://datatracker.ietf.org/doc/draft-schwartz-httpbis-optimistic-upgrade/,
>>>> which hasn't gotten enough comments yet.  Please review!
>>>>
>>>> Conversions involving HTTP/3 are more interesting due to datagrams.  If
>>>> the Capsule-Protocol header is present, then conversions between H2 and H3
>>>> are well-defined.  Otherwise, I don't think it's safe: the H3 hop could
>>>> send a datagram, and the H2 hop wouldn't know what to do with it.  Silently
>>>> blackholing all datagrams, on a request that claims to be successful, is
>>>> not a good solution.
>>>>
>>>> --Ben Schwartz
>>>>
>>>> ------------------------------
>>>> *From:* Lucas Pardue <lucaspardue.24.7@gmail.com>
>>>> *Sent:* Wednesday, October 4, 2023 4:01 PM
>>>> *To:* Kazuho Oku <kazuhooku@gmail.com>
>>>> *Cc:* HTTP Working Group <ietf-http-wg@w3.org>
>>>> *Subject:* Re: Can proxies forward extended CONNECT in HTTP-version
>>>> and protocol-agnostic manner?
>>>>
>>>> Hi Kazuho, On Wed, Oct 4, 2023 at 8: 56 PM Kazuho Oku <kazuhooku@
>>>> gmail. com> wrote: Hi folks, As a proxy developer, I would like to
>>>> implement a tunnel for extended CONNECT requests in a HTTP-version agnostic
>>>> way, without knowing how each
>>>> ZjQcmQRYFpfptBannerStart
>>>> This Message Is From an External Sender
>>>>
>>>> ZjQcmQRYFpfptBannerEnd
>>>> Hi Kazuho,
>>>>
>>>>
>>>>
>>>> On Wed, Oct 4, 2023 at 8:56 PM Kazuho Oku <kazuhooku@gmail.com> wrote:
>>>>
>>>> Hi folks,
>>>>
>>>> As a proxy developer, I would like to implement a tunnel for extended
>>>> CONNECT requests in a HTTP-version agnostic way, without knowing how each
>>>> protocol as indicated by the :protocol: pseudo header is to be transcoded.
>>>>
>>>> The request can come in any HTTP version, then forwarded in any HTTP
>>>> version.
>>>>
>>>> If we look at the existing RFCs and drafts, it seems to me that that's
>>>> possible.
>>>>
>>>> Websocket, connect-udp, connect-ip, connect-ethernet, connect-tcp, they
>>>> all use GET + upgrade in HTTP/1.1, use extended CONNECT in H2 and H3.
>>>> Therefore, we can have one shared logic to convert between the HTTP
>>>> versions that is ignorant of the upgrade token being specified.
>>>>
>>>> But because each upgrade protocol defines its own mapping to H1, H2 and
>>>> H3, the question is: can we assume that we'd be reusing this design pattern
>>>> so that we can have proxying logic that is agnostic to the upgrade token?
>>>>
>>>> Specifically, I think we can break down the question to:
>>>>
>>>> 1. Can we transcode H2 extended CONNECT requests to H3, or vice versa?
>>>> I think the answer is yes.
>>>>
>>>> 2. Can we transcode H2 / H3 extended CONNECT requests to H1 GET +
>>>> upgrade? Maybe the answer is yes.
>>>>
>>>> 3. Can we transcode H1 GET + upgrade into H2 / H3 extended CONNECT? I'm
>>>> not sure if this is possible with h2c. Is it just enough to have a deny
>>>> list that contains h2c?
>>>>
>>>>
>>>> I tend to agree with your answers. FWIW we obsoleted `h2c` in RFC9113
>>>> [1] so I think making an exception for it (deny list) is fine.
>>>>
>>>> Cheers,
>>>> Lucas
>>>>
>>>>
>>>> [1] = https://www.rfc-editor.org/rfc/rfc9113.html#section-3.1
>>>>
>>>>
>>>> --
>>>> Kazuho Oku
>>>>
>>>>
>>
>> --
>> Kazuho Oku
>>
>

-- 
Kazuho Oku

Received on Friday, 6 October 2023 01:21:58 UTC