-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consul Connect SDK HTTPClient #4466
Comments
The root cause here is that our built-in proxy is advertising To be clear it's a Layer 4 proxy so it makes no sense to advertise support for a L7 protocol, not a limitation of the proxy implementation. If the services either end of two proxies use http2 then our proxy should remain oblivious and just forward the packets over it's own TLS - this is what happens right now if you use http2 client and server which are both talking to a Connect proxy it works fine. TLS-in-TLS is perhaps not ideal but it's workable and not something we can solve when only proxying layer 4. The actual bug here is that when the client end is a native integration, and the server end is our built-in proxy, then the following happens:
The real fix here is that our proxy should not advertise h2 next proto. The reason it does is that it just uses our SDK which we explicitly built to support h2 servers. We need to make it configurable for server that it doesn't support that and then configure our proxy not to add "h2". Once this is done the above example would look like:
This gets us back to a non-broken state, but it does mean that different combinations of proxy/native client and server will have varying http2 support. Later we can consider adding support for http2 proxying end to end by having the proxy establish connections to the service first and discover whether it supports http2. The downside is that for now the go http.Client only supports http2 over TLS which means that to actually work this would need the app to be configured for TLS separately from connect already. At that point it's likely better to just natively integrate. We could also consider making it possible to re-enable the current behaviour in the proxy config such that, if you know your application will support h2c, the proxy can still terminate the TLS and pass raw http2 on to the server. This is the case for gRPC services by default (when not provided explicit TLS creds) for example. As an aside, an issue I opened years ago to add tl;drThe right solution for now is to make |
This is no longer an issue because the builtin proxy is no longer part of consul. |
Well, the managed proxies were removed, but not the builtin proxy. Sorry! |
Any chance that this could get fixed? I am running into this currently. Envoy handles it properly but for testing the simpler builtin proxy is often enough. |
If you could tell me how you'd want the interface to look like, I can add that I guess. Add |
@apollo13 honestly given that we don't recommend using the built in proxy any more I'm not sure if we'll get to prioritizing this super soon. The ideal fix I think would be something like:
If that's something you'd be willing to contribute that would be welcome! |
When attempting to make a connection to an upstream, the provided HTTPClient attempts to connect using HTTP2 when the downstream is only HTTP/1.1 with no TLS connection.
I believe this is because the HTTP2 is negotiated in the handshake phase of the connection, the proxy is responding that it has ALPN capabilities and therefore the client will use this when attempting to send a request upstream.
However the problem is that upstream service in this instance is not using HTTP2 and is only HTTP/1.1 with no TLS, the protocol has been negotiated with the proxy not the upstream. When a request is sent to the upstream it is sent as a HTTP2 request the upstream server will reject this as it is not supported.
Reproduction Steps
Steps to reproduce this issue, eg:
Since Go does not support HTTP2 without TLS and it is not possible to use HTTPS upstream from the SDK as there is no way to manually configure self signed TLS roots. A quick fix would be to disable HTTP2 support in the SDK.
A long term fix would be to correctly report ALPN status based on the upstreams ability to speak HTTP2 or to have this as a manual configuration option when configuring a proxy. In either case configuration would need to be enabled for TLS roots in the HTTP client or allow insecure based on the assumption that the connection between the proxy and service over localhost is OK.
Operating system and Environment details
Tested on Darwin however behavior covers all environments
Log Fragments
Below is the output from ngrep using the command
sudo ngrep -W byline -d all port 8087 or 8443
The proxy is running on port 8443 and the upstream service 8087
The text was updated successfully, but these errors were encountered: