Skip to content
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

alts: if ALTS is not running on GCP, fails call #4807

Merged
merged 3 commits into from
Aug 29, 2018

Conversation

jiangtaoli2016
Copy link
Contributor

In ALTS, rather than throws RuntimeException if the application is not running on GCP, we fail at interceptCall.

Metadata metadata,
ServerCallHandler<ReqT, RespT> nextHandler) {
if (!status.isOk()) {
serverCall.close(status, new Metadata());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure whether it is sufficient here.

Copy link
Member

Choose a reason for hiding this comment

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

This would be appropriate, although, isn't it impossible to actually get here? Won't the server be unable to accept new connections? And without connections it won't get any RPCs.

Server-side does have start() that can throw an IOException...

@jiangtaoli2016
Copy link
Contributor Author

@ejona86 Could you please take a look?

+ "ALTS handshaker service");
} else {
status =
Status.FAILED_PRECONDITION.withDescription(
Copy link
Member

Choose a reason for hiding this comment

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

The gRPC library can't use FAILED_PRECONDITION: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How about INTERNAL? I feel FAILED_PRECONDITION is the right description though.
"Operation was rejected because the system is not in a state required for the operation's execution."

Copy link
Member

Choose a reason for hiding this comment

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

INTERNAL is okay. We can change it later if need be.

tcpfFactoryForTest = tcpfFactory;

return new AltsChannel(delegate().build());
return delegate().intercept(new AltsClientInterceptor(status)).build();
Copy link
Member

Choose a reason for hiding this comment

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

Only add the interceptor when it will be helpful (like in the else case above).

You should add a note that you can't call build() multiple times.

@jiangtaoli2016
Copy link
Contributor Author

@ejona86 code revised. PTAL

status =
Status.INTERNAL.withDescription("ALTS is only allowed to run on Google Cloud Platform");
}
delegate().intercept(new AltsClientInterceptor(status));
Copy link
Member

Choose a reason for hiding this comment

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

Move this into the else.

@@ -50,7 +44,7 @@ public void buildsNettyChannel() throws Exception {
assertThat(altsClientOptions).isNull();

ManagedChannel channel = builder.build();
assertThat(channel).isInstanceOf(AltsChannel.class);
assertThat(channel).isInstanceOf(ManagedChannel.class);
Copy link
Member

Choose a reason for hiding this comment

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

This check dose nothing, since it's a ManagedChannel that is returned.

Status.FAILED_PRECONDITION
.withDescription("Failed to get Google default credentials")
.withCause(e);
Status.INTERNAL.withDescription("Failed to get Google default credentials").withCause(e);
Copy link
Member

Choose a reason for hiding this comment

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

Probably UNAUTHENTICATED

delegate.enterIdle();
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
if (!status.isOk()) {
Copy link
Member

Choose a reason for hiding this comment

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

No more need for this check.

Metadata metadata,
ServerCallHandler<ReqT, RespT> nextHandler) {
if (!status.isOk()) {
serverCall.close(status, new Metadata());
Copy link
Member

Choose a reason for hiding this comment

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

This would be appropriate, although, isn't it impossible to actually get here? Won't the server be unable to accept new connections? And without connections it won't get any RPCs.

Server-side does have start() that can throw an IOException...

@jiangtaoli2016
Copy link
Contributor Author

@ejona86 Revised. The reason we want to check GCP platform is to prevent network attack on handshaker service. If attacker re-directs metadata server, it may fool grpc client.

In the normal case, if app is not running on GCP, it would fail on connecting to handshaker server.
In the case of being attack (by redirect to a fake handshaker server) and not running on GCP, grpc server or client would fail the call during interceptCall -- although connecting to attacker's handshaker server succeeded.

This GCP residency check is defense in depth.

@jiangtaoli2016 jiangtaoli2016 merged commit 87513d8 into grpc:master Aug 29, 2018
@lock lock bot locked as resolved and limited conversation to collaborators Nov 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants