Skip to content

envoy grpc: overridable host#12338

Merged
lizan merged 12 commits intoenvoyproxy:masterfrom
lambdai:hostforasyncclient
Aug 4, 2020
Merged

envoy grpc: overridable host#12338
lizan merged 12 commits intoenvoyproxy:masterfrom
lambdai:hostforasyncclient

Conversation

@lambdai
Copy link
Copy Markdown
Contributor

@lambdai lambdai commented Jul 28, 2020

Commit Message:
Add authority field in envoy grpc message to override the default host name as cluster name.

Signed-off-by: Yuchen Dai silentdai@gmail.com

Additional Description:
I am not sure if this is the good way to go, comparing to a dedicated host header field beside metadata.

If you do agree I can add the test case, or we can switch to alternative approaches.

Risk Level:
Testing:
Docs Changes:
Release Notes:
[Optional Runtime guard:]
Fix #12116

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
@lambdai lambdai requested a review from htuch July 28, 2020 18:51
headers_message_->headers().addCopy(Http::LowerCaseString(header_value.key()),
header_value.value());
if (Http::LowerCaseString(header_value.key()).get() == Http::Headers::get().Host.get()) {
headers_message_->headers().setHost(header_value.value());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch here - definitely for host we want to set rather than append, but I'm surprised we allow host override - we generally disallow setting the special : h2 headers in most operations.

If we decide we want to allow this for host I think we need to at the very least special case :authority :scheme :path etc, and probably do what we discussed on the retry PR and change the API to allow for "append or replace" semantics.

cc @markdroth

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would advise not allowing HTTP/2 special headers to be set for gRPC. I don't know about the EnvoyGprc implementation (which I assume is what this file is for), but in Google gRPC, we don't expect these to be set by the application (at least not directly -- there are some options that can be used to affect how we set them, but they're not generally necessary).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The host is required mainly because the async client is very limited. This grpc client is used by a filter which may need a grpc client(e.g. external authz), or xds client.
The header manipulation is not supposed to be simple: no evaluation, no untrusted value.
The grpc headers are actually as simple as a header set
see

repeated HeaderValue initial_metadata = 5;

Personally I don't want to promote the grpc header factory as complicated as the one in route entry, which represents the scenario which requires
a base header map plus a header add/delete engine, unless this if branch is proved to be hard to handle.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this should not be complicated. And I think that representation of headers is just fine. But I don't understand why users would need to put the host header in initial_metadata.

Google gRPC will populate the ":authority" header internally; it does not need to be passed in by the user in initial_metadata. I think EnvoyGrpc should do the same thing.

To say this another way, I think that users should be able to switch back and forth between EnvoyGrpc and GoogleGrpc without changing their initial_metadata field. Since GoogleGrpc can't handle the host header being set in initial_metadata, EnvoyGrpc shouldn't do it either.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markdroth I highly agree with you that we should make envoygrpc and googlegrpc interchangeable as far as possible.

This cluster_name provide both :authority(as string) and L4 addresses(as the reference to an envoy cluster).

string cluster_name = 1 [(validate.rules).string = {min_bytes: 1}];

I may end up with a new optional field to type EnvoyGrpc

How is :authority filled in googlegrpc?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Google gRPC, the ":authority" header is set based on name used to create the gRPC channel. That's essentially the name specified here:

string target_uri = 1 [(validate.rules).string = {min_bytes: 1}];

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markdroth Google Grpc seems support override authority by ClientContext::set_authority().

Does it mean we can add the authority field for both google grpc and envoy grpc now?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set it that way, but it's almost never necessary. That mechanism was added for some fairly rare virtual hosting scenarios.

My suggestion would be that instead of adding an authority field to the top-level GrpcService message, you instead add this in the EnvoyGrpc message. Having one field that works for both EnvoyGrpc and GoogleGrpc seems confusing, since the semantics are different -- this is probably going to be necessary a lot more for EnvoyGrpc than for GoogleGrpc, since the latter already gets this from the target_uri field. If we ever run into the rare case where this needs to be overridden for GoogleGrpc, we can add a separate field in that message.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @markdroth!
The :authority has the exact semantic on both google grpc and envoy grpc.
I admit my pain point now is to override host at envoy grpc b/c as you mentioned I could fill the targeturi with my desired :authority.
It's likely we will want L4 address be independent virtual host in the future at istio, but we are not there yet.

I am following your comment to make it EnvoyGrpc only

lambdai added 2 commits July 29, 2020 09:42
Signed-off-by: Yuchen Dai <silentdai@gmail.com>
Signed-off-by: Yuchen Dai <silentdai@gmail.com>
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/envoy/.
CC @envoyproxy/api-watchers: FYI only for changes made to api/envoy/.

🐱

Caused by: #12338 was synchronize by lambdai.

see: more, trace.

And used in envoy grpc client

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
@lambdai lambdai changed the title grpc: overridable host envoy grpc: overridable host Jul 29, 2020
@lambdai
Copy link
Copy Markdown
Contributor Author

lambdai commented Jul 29, 2020

/wait

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
@markdroth
Copy link
Copy Markdown
Contributor

/lgtm api

@lizan
Copy link
Copy Markdown
Member

lizan commented Jul 30, 2020

I think you want to set the authority as SNI as well?

@lambdai
Copy link
Copy Markdown
Contributor Author

lambdai commented Jul 30, 2020

I think you want to set the authority as SNI as well?

Thanks! That make sense to me. Is SNI a transports socket option? I am not sure if grpc async client does set SNI before this PR. Let me take a look.

@lambdai
Copy link
Copy Markdown
Contributor Author

lambdai commented Jul 30, 2020

@lizan I looked in the existing config. SNI is by default set in the transport socket of that cluster, in which envoy grpc client will originate tls client.
We could config the SNI there.
Override for particular grpc client may need in the future but not now.

Could we add later until we need it?

@lizan
Copy link
Copy Markdown
Member

lizan commented Jul 30, 2020

@lambdai OK I looked this again, in GoogleGrpc client it can be override in channel args with grpc.ssl_target_name_override if it doesn't what is in target_uri. in EnvoyGrpc the sni value in cluster will be used.

For most use cases with TLS overriding :authority usually need them as well, can you add a comment for that?

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
lambdai added 2 commits July 31, 2020 18:25
Signed-off-by: Yuchen Dai <silentdai@gmail.com>
Signed-off-by: Yuchen Dai <silentdai@gmail.com>
@lambdai
Copy link
Copy Markdown
Contributor Author

lambdai commented Jul 31, 2020

I am blocked by ci on my machine...

lizan
lizan previously approved these changes Jul 31, 2020
lambdai added 3 commits August 1, 2020 01:37
Signed-off-by: Yuchen Dai <silentdai@gmail.com>
Signed-off-by: Yuchen Dai <silentdai@gmail.com>
…o hostforasyncclient

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
Signed-off-by: Yuchen Dai <silentdai@gmail.com>
@lambdai
Copy link
Copy Markdown
Contributor Author

lambdai commented Aug 4, 2020

ping @envoyproxy/api-shepherds for update api: allow host header be empty.
The empty host is required for back compatibility because we don't use "optional".

@markdroth
Copy link
Copy Markdown
Contributor

/lgtm api

@repokitteh-read-only repokitteh-read-only bot removed the api label Aug 4, 2020
@lambdai
Copy link
Copy Markdown
Contributor Author

lambdai commented Aug 4, 2020

Thank you @markdroth

@lizan lizan merged commit 29b4927 into envoyproxy:master Aug 4, 2020
@lambdai
Copy link
Copy Markdown
Contributor Author

lambdai commented Aug 5, 2020

Thanks!

@lambdai lambdai deleted the hostforasyncclient branch August 5, 2020 21:12
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
Add authority field in envoy grpc message to override the default host name as cluster name.

Risk Level: Low
Testing:
Docs Changes:
Release Notes:
Fix envoyproxy#12116 

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
chaoqin-li1123 pushed a commit to chaoqin-li1123/envoy that referenced this pull request Aug 7, 2020
Add authority field in envoy grpc message to override the default host name as cluster name.

Risk Level: Low
Testing:
Docs Changes:
Release Notes:
Fix envoyproxy#12116

Signed-off-by: Yuchen Dai <silentdai@gmail.com>
Signed-off-by: chaoqinli <chaoqinli@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants