http: configurable ignore of HTTP/1.1 upgrades#37642
http: configurable ignore of HTTP/1.1 upgrades#37642ggreenway merged 9 commits intoenvoyproxy:mainfrom
Conversation
|
Hi @tedgeat, welcome and thank you for your contribution. We will try to review your Pull Request as quickly as possible. In the meantime, please take a look at the contribution guidelines if you have not done so already. |
|
CC @envoyproxy/api-shepherds: Your approval is needed for changes made to |
|
@tedgeat 👋 , is it going to work for http2 upstreams too? |
There was a problem hiding this comment.
I don't think remove the unsupported upgrade type and treat the upgrade request as a normal http request is good choice. If clients ask envoy to upgrade but envoy cannot support, rejection would be best choice.
This change brings a new option to our core API and only for a special (or incorrect) hack.
cc @alyssawilk @envoyproxy/senior-maintainers for more input.
/wait
|
|
||
| // Ignore HTTP/1.1 upgrade headers rather than default rejection | ||
| bool ignore_http_11_upgrade = 11; |
There was a problem hiding this comment.
From the naming, the options will ignore all upgrade. But actually the implementation didn't works at that way.
There was a problem hiding this comment.
ignore_http_11_tls_upgrade ?
There was a problem hiding this comment.
or repeated string of upgrade to ignore, so it can be extended without adding multiple config fields.
I'd strongly prefer if we're going to ignore we do what we do for h2c and remove the unsupported upgrade. If Envoy is not going to treat an upgrade as an upgrade, but an upstream is, I think you run into problems. If we want to handle the case that a client asks for an upgrade which neither Envoy or the upstream handle, removing the upgrade header is a clear signal that we're handling the upgrade.
If you have a reason to pass the upgrade header through, this PR should not land until you also add handling verifying that the upstream did not attempt to actually upgrade
/wait-any
There was a problem hiding this comment.
Forwarding the Upgrade header is not valid by my reading of the spec:
When Upgrade is sent, the sender MUST also send a Connection header
field (Section 6.1) that contains an "upgrade" connection option, in
order to prevent Upgrade from being accidentally forwarded by
intermediaries that might not implement the listed protocols.
Connection header is hop-by-hop so it cannot be forwarded. Upgrade cannot be sent without a Connection header. Therefore Upgrade cannot be forwarded (or at the very least is extraneous).
There was a problem hiding this comment.
perfect, so a repeated string of upgrade headers to clear makes the most sense to me
There was a problem hiding this comment.
I think it's more that new protos will get added and then it'll silently break again in the future when a library uses that.
The goal of this PR was to do what pretty much every webserver we've tested so far does, and ignore unsupported upgrade headers.
The "UX" experience here is that our devs don't run into this problem at all locally, but once their app is deployed onto our cluster, which is backed by Istio and Envoy, things start failing. It suddenly started after people did springboot upgrades, and became a massive rabbithole to debug. We'd like to avoid this in the future:
- dev works on their app locally, everythings fine
- dev deploys app to the cluster, starts seeing 403s
- dev spends hours trying to understand AUTH FAILURES
- dev comes to platform folks for help, speaks to someone who has either since forgotten about this, or is simply new to the team, they rabbithole for a bit too
- eventually we realise what it is, and we put in an additional header in the DestinationRule (assuming istio adds support for this list via DR)
To add to this, given this is a client problem - the change to the DestinationRule will need to be done on each destination service the client talks to, so you create a massive orchestration problem for them to release their change too (eg all their destinations would first need to update this config before they can roll out).
There was a problem hiding this comment.
@Stono Thanks - I think this is persuasive. If I understand @alyssawilk and @bplotnick correctly, if the desired UX is to just ignore unsupported upgrades, the upgrade header needs to be removed from the upstream request so that the upstream doesn't attempt to upgrade. Is that the main thing missing from this PR?
There was a problem hiding this comment.
I don't think it is, is it? Correct me if I'm wrong but you effectively have:
local app -> local envoy -------> remote envoy -> remote app
local app always sends the upgrade header, local envoy currently rejects it.
local envoy would need to ignore it, and if you've implemented the concept of ignore it there, remote envoy could simply ignore it too?
Saying that in my envoyfilter here i kind of do what you've suggested (first allow it on the inbound envoy, then strip it from the outbound request - i needed both because both local and remote envoy would reject)
There was a problem hiding this comment.
There's no guarantee the next hop is an envoy. Furthermore, you run into the problem @bplotnick describes earlier: #37642 (comment)
There was a problem hiding this comment.
That makes sense actually, given connection is per hop, local envoy should see it, ignore it, and not forward it on 👍
The spec says either to ignore or upgrade and doesn't mention rejection at all. But as that's the current envoy behaviour this makes ignoring opt-in |
|
note: envoy maintainers will be mostly on vacation until 6th jan /wait-any |
|
/wait |
|
NOTE: since the release of spring boot 3.4 in combination with apache camel (http request) this issue also reases if it is used in combination the envoy proxy. |
|
We are facing this issue with Apache Iceberg 1.7+ client which sends the Upgrade header by default, and the server's envoy proxy rejects it and closes the connection with 403. |
|
I've renamed the config to |
Can we please make this generic with a string matcher? We already have use cases reported for other upgrades so hardcoding a single use case doesn't seem to make sense here. |
Unfortunately it seems like that would be a bigger change since according to @ggreenway in #37150 (comment), the codec doesn't have access to the configuration until after it's applied some upgrade specific logic |
|
+1 from an API perspective I don't think we want to add specific header knobs to the API if there's ever a use case for generic options (which in this case there clearly are) |
Does that comment apply to the current implementation? How could we pass a bool but not a string matcher? |
Thanks Greg! |
wbpcode
left a comment
There was a problem hiding this comment.
I still cannot get the actual value of this PR. The client ask envoy to upgrade and the proxy cannot support, the correct way should be to reject the request to throw the error.
If Envoy remove the upgrade the proxy the request to upstream, it's maybe result in unexpected behavior for the clients.
I added some comments to the style. And hope someone could address my above worry.
cc @ggreenway
|
@wbpcode regarding your inquiry into the value of this PR, the HTTP Upgrade page of the Mozilla MDN docs states
This behavior is not possible when the envoy proxy rejects any request with the header set, which cannot be fulfilled. The expected default behavior is to ignore the header, and many services set these headers in their HTTP clients with this assumption. |
|
@wbpcode This is ready for you to take another look at |
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Tom Edge <tom.edge@autotrader.co.uk> Signed-off-by: Greg Greenway <ggreenway@apple.com> Co-authored-by: Greg Greenway <ggreenway@apple.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Tom Edge <tom.edge@autotrader.co.uk> Signed-off-by: Greg Greenway <ggreenway@apple.com> Co-authored-by: Greg Greenway <ggreenway@apple.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Tom Edge <tom.edge@autotrader.co.uk> Signed-off-by: Greg Greenway <ggreenway@apple.com> Co-authored-by: Greg Greenway <ggreenway@apple.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Tom Edge <tom.edge@autotrader.co.uk> Signed-off-by: Greg Greenway <ggreenway@apple.com> Co-authored-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Dario Cillerai <dcillera@redhat.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Tom Edge <tom.edge@autotrader.co.uk> Signed-off-by: Greg Greenway <ggreenway@apple.com> Co-authored-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Dario Cillerai <dcillera@redhat.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Tom Edge <tom.edge@autotrader.co.uk> Signed-off-by: Greg Greenway <ggreenway@apple.com> Co-authored-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Dario Cillerai <dcillera@redhat.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Tom Edge <tom.edge@autotrader.co.uk> Signed-off-by: Greg Greenway <ggreenway@apple.com> Co-authored-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Dario Cillerai <dcillera@redhat.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Greg Greenway <ggreenway@apple.com> (cherry picked from commit ad40097)
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Greg Greenway <ggreenway@apple.com> (cherry picked from commit ad40097)
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Greg Greenway <ggreenway@apple.com> (cherry picked from commit ad40097) fix stringmatcherimpl template version difference Signed-off-by: Greg Greenway <ggreenway@apple.com>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Greg Greenway <ggreenway@apple.com> (cherry picked from commit ad40097) fix stringmatcherimpl template version difference Signed-off-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Ryan Northey <ryan@synca.io>
Fixes envoyproxy#36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Greg Greenway <ggreenway@apple.com> (cherry picked from commit ad40097) fix stringmatcherimpl template version difference Signed-off-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Ryan Northey <ryan@synca.io>
Fixes #36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Greg Greenway <ggreenway@apple.com> (cherry picked from commit ad40097) fix stringmatcherimpl template version difference Signed-off-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Ryan Northey <ryan@synca.io>
Fixes #36305 Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7: Signed-off-by: Greg Greenway <ggreenway@apple.com> (cherry picked from commit ad40097) fix stringmatcherimpl template version difference Signed-off-by: Greg Greenway <ggreenway@apple.com> Signed-off-by: Ryan Northey <ryan@synca.io>
Fixes #36305
Add configuration to ignore HTTP/1.1 Upgrade headers . See https://datatracker.ietf.org/doc/html/rfc7230#section-6.7:
Risk Level: Medium
Testing: new unit tests
Docs Changes: in with APIs
Release Notes: inline