On Fri, Sep 11, 2020 at 09:02:57AM +0200, Tim Düsterhus wrote:
> According to the article performing a h2c upgrade via TLS is not valid
> according to the spec. HAProxy implements the H2 spec.

"according to the article" :-) There's no such mention in the spec
itself from what I remember, it's just that it's usually pointless,
but there may be a lot of situations where it's considered better to
forward an upgradable connection over TLS to the next intermediary
because the intermediary network is not safe.

> Question 1: Should HAProxy reject requests that set Upgrade: h2c over
> TLS? I think it should. Basically the following rule should be applied
> automatically to my understanding.
> 
> http-request deny deny_status 400 if { req.hdr(upgrade) h2c } { ssl_fc }

No I disagree. Let's say you have an h2c client on datacenter 1 and
an h2c server on datacenter 2. This rule would prevent you from using
the local haproxy to secure the connection, while providing zero benefit.

By the way, it's fun to see that a discussion started a few days ago
regarding the uselessness of h2c and its removal from the next H2 spec
because "nobody implemented it yet" :-)  And actually the guy had to
implement its own server to find a complying one.

> Further the article says that the HTTP2-Settings header is a hop by hop
> header. It should not be forwarded by a proxy. According to the article
> HAProxy *does* forward it.
> 
> Question 2: Should HAProxy automatically strip the HTTP2-Settings header
> when forwarding requests?

Haproxy is not a proxy but a gateway. See it as a transparent cable
capable of staying synchronized with both ends and interacting the least
possible. There's nothing wrong with repeating hop-by-hop header fields
on gateways if you don't break the transport nor semantics, it's exactly
what happens when you use a raw TLS offloader for example, which doesn't
even understand HTTP. Technically speaking we're not "keeping" the
header, we're formulating a new request that places it again since it's
compatible with both sides' capabilities. In fact haproxy produces a
new connection header with all the tokens that it did not use, since
they are by definition for the next hop. "keep-alive" and "close" are
the only two that are of interest to us and that are terminated locally.

For example, the TE header is hop-by-hop. Haproxy doesn't need it but
maintains the transport, messaging and semantics end-to-end so it does
not need to eliminate it and disrupt end-to-end connectivity as long as
it stays synchronized. Really that's not different from a pure TCP proxy
(which is how haproxy started 20 years ago by the way).

Hoping this clarifies the point,
Willy

Reply via email to