Eliminate gRPC insecure build#25586
Conversation
|
@jiangtaoli2016 F.Y.I. |
|
@yihuazhang what is the motivation for getting rid of the insecure targets? I added myself as a reviewer as I'd like to check that the BUILD / cmake / other build systems changes make sense - please let me know once this is ready for review (and please wait for LGTM from me). |
|
@yihuazhang can you please also provide a list of the "public" insecure targets that you're planning to remove? |
|
@jtattermusch This is something we've been wanting to do for a while. For context, see the internal design doc at go/higher-security-for-grpc. |
|
Thanks @jtattermusch for chiming in and sorry for lacking the context. The doc Mark pointed contains more details about the motivation of this PR. PLMK if you have any questions. Regarding the insecure builds, I think |
Oh I see, I thought you're going to be removing the |
|
It seems the failed tests are not related to this PR. F.Y.I. @markdroth, the PR is ready for a review. No rush though (I expect you might be busy due to perf). @jtattermusch SG. I will let you know once Mark approved this PR. |
markdroth
left a comment
There was a problem hiding this comment.
Thanks for doing this, Yihua! I've been wanting to see this change for a long time.
Jan, your review will be most welcome. I'm sure you can help us spot anything we might inadvertantly break here.
Please let me know if you have any questions. Thanks!
Reviewed 12 of 27 files at r1, 3 of 17 files at r2, 8 of 8 files at r3, 5 of 8 files at r4.
Reviewable status: all files reviewed, 8 unresolved discussions (waiting on @jtattermusch and @yihuazhang)
BUILD, line 130 at r3 (raw file):
] GRPC_SECURE_PUBLIC_HDRS = [
This list can probably go away now, and grpc_security.h can be added to GRPC_PUBLIC_HDRS instead.
BUILD, line 134 at r3 (raw file):
] # TODO(ctiller): layer grpc atop grpc_unsecure, layer grpc++ atop grpc++_unsecure
This TODO can go away now.
BUILD, line 300 at r3 (raw file):
grpc_cc_library( name = "grpc_unsecure",
We need to clean up the conditional compilation structure that we currently have for secure vs. insecure builds.
We have the grpc_unsecure target for insecure builds and the grpc_secure target for secure builds. The two targets actually build a slightly different set of files. Some specifics:
- The insecure build includes init_unsecure.cc and grpc_unsecure_plugin_registry.cc, whereas the secure build includes init_secure.cc and grpc_plugin_registry.cc.
- Both secure and insecure builds depend on
grpc_transport_chttp2_client_insecureandgrpc_transport_chttp2_server_insecure(which definegrpc_insecure_channel_create()andgrpc_server_add_insecure_http2_port()), but the secure build additionally depends ongrpc_transport_chttp2_client_secureandgrpc_transport_chttp2_server_secure(which definegrpc_server_add_secure_http2_port()andgrpc_secure_channel_create()).
I think what we want here is to eliminate the conditional compilation and make the secure target a simple layer on top of the insecure target that adds the dependencies for the credential types (which bring in the SSL library dependency).
Here are some specific changes we should make:
- Move the code from init_secure.cc directly into init.cc, and remove init_secure.cc and init_unsecure.cc. Also remove the relevant declarations in init.h, since those functions can now be static inside of init.cc.
- Move the code from grpc_plugin_registry.cc into init.cc and remove both grpc_plugin_registry.cc and grpc_unsecure_plugin_registry.cc.
- Eliminate
grpc_insecure_channel_create()andgrpc_server_add_insecure_http2_port()from the API and renamegrpc_server_add_secure_http2_port()andgrpc_secure_channel_create()to justgrpc_server_add_http2_port()andgrpc_channel_create(). This will require a gRFC. As part of this, we should probably move their declarations from grpc_security.h to grpc.h. And instead of the code being in src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc and src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc, it should be moved to the existing src/core/ext/transport/chttp2/client/chttp2_connector.cc and src/core/ext/transport/chttp2/server/chttp2_server.cc files.
BUILD, line 1313 at r3 (raw file):
grpc_cc_library( name = "grpc_lb_policy_grpclb",
Here's another case where we have some conditional compilation for insecure builds that needs to be cleaned up.
We currently have two targets for grpclb, one for insecure builds (this one) and another for secure builds (the next one, grpc_lb_policy_grpclb_secure). The only difference between the two is that the insecure one uses the file grpclb_channel.cc, whereas the secure one uses the file grpclb_channel_secure.cc. Both files provide the interface defined in grpclb_channel.h, but with different implementations for the two different builds. And we have the build dependencies set up such that insecure builds and secure builds depend on the right version of this target.
This difference is no longer needed now that insecure builds are going away. Instead, let's do the following:
- Move the code from grpclb_channel_secure.cc directly into grpclb.cc.
- Remove the files grpclb_channel.h, grpclb_channel.cc, and grpclb_channel_secure.cc.
- Remove the
grpc_lb_policy_grpclb_securetarget. - Remove the
grpc_lb_policy_grpclb_securedependency from thegrpctarget, and addgrpc_lb_policy_grpclbas a dependency ofgrpc_common. - Change the
grpc_lb_policy_grpclbtarget to depend ongrpc_transport_chttp2_client_secureinstead ofgrpc_transport_chttp2_client_insecure.
BUILD, line 1847 at r3 (raw file):
grpc_cc_library( name = "grpc_secure_base",
Suggest calling this grpc_security_base.
BUILD, line 1860 at r3 (raw file):
"src/core/lib/security/transport/server_auth_filter.cc", "src/core/lib/security/transport/tsi_error.cc", "src/core/tsi/transport_security.cc",
These TSI files are already present in the tsi target, and they should not be in more than one build target. I think we still need the tsi target, because there are internal callers like GFE that depend on TSI without necessarily depending on gRPC, so we can't just remove that target. So we'll need to make this target depend on the tsi target.
Of course, we can't just depend on the tsi target as it currently exists, because that would pull in the SSL library dependency that we're trying to eliminate here. To avoid this, I suggest the following:
- Move the "base" TSI files (like src/core/tsi/transport_security.cc) into a new target called
tsi_base, which can be a dependency of both this target and thetsitarget. - For each credential type, move the TSI files into a new target called
tsi_${type}_credentials, which can be a dependency of both thetsitarget and the correspondinggrpc_${type}_credentialstarget. (For example, a file like src/core/tsi/fake_transport_security.cc would be in a target calledtsi_fake_credentials, which would be a dependency of both thetsitarget and thegrpc_fake_credentialstarget, so thegrpc_fake_credentialstarget would not need to directly include that .cc file.)
BUILD, line 1944 at r3 (raw file):
name = "grpc_alts_credentials", srcs = [ "src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c",
These upb files should not be repeated here. Instead, add a dependency on the existing alts_upb target.
src/core/lib/security/security_connector/security_connector.h, line 45 at r3 (raw file):
#define GRPC_ARG_SECURITY_CONNECTOR "grpc.security_connector" #define GRPC_SSL_URL_SCHEME "https"
This seems like the wrong place for this definition, since there is nothing SSL-specific in this file. I think this should be kept where it was originally, in ssl_utils.h. Was there some reason you needed to move it?
|
Thanks @markdroth for the detailed feedback, and sorry for the delayed action! Regarding the comments - |
|
The C-core API is not a public API, and we don't offer a backward-compatibility guarantee for it. We are required to publish a gRFC for C-core API changes, but we are not required to make non-breaking changes. In general, the only callers of the C-core API should be C++ and the wrapped languages, so we are in control of all the call sites. We should be able to update them as part of this PR. If there's some reason that it's hard to update the callers at the same time, I'm not opposed to keeping the old APIs for a short time to ease the transition (e.g., to allow us to spread the changes out across multiple PRs). But I don't want to be left supporting duplicate APIs for a long period of time. Also, note that there are subtle behavioral differences between |
|
Ah you are right. Now I remember that we do not need to maintain backward compatibility for C-core surface API changes. After we change all wrapped languages to use the new way of creating an insecure channel, I am not sure if it is going to break any of their internal tests that rely on the subtle difference between old and new behaviors you mentioned (e.g., when communicating call credentials on the channel created via the old API, the call credentials will get ignored but RPC still succeeds while RPC will fail when communicating the call credentials over the channel created via the new API). |
We usually have to update these callers as well. But we can deal with that when we're ready to try importing this change.
Yes. We'll need to update any affected tests as part of this PR. |
|
I apologize for taking so long to address the comments. I finally got time working on it, and it is my top priority now. While working on it, I found the following two issues:
|
The existing
I don't think we can remove this, since there are still use-cases where people want to create a channel from an fd. But since we always assume that the fd is insecure in this case, we can just change the implementation of this function to do the same thing as |
216e7ad to
709090e
Compare
yihuazhang
left a comment
There was a problem hiding this comment.
Reviewable status: 12 of 40 files reviewed, 8 unresolved discussions (waiting on @jtattermusch and @markdroth)
BUILD, line 130 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
This list can probably go away now, and grpc_security.h can be added to
GRPC_PUBLIC_HDRSinstead.
Done.
BUILD, line 134 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
This TODO can go away now.
Done.
BUILD, line 300 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
We need to clean up the conditional compilation structure that we currently have for secure vs. insecure builds.
We have the
grpc_unsecuretarget for insecure builds and thegrpc_securetarget for secure builds. The two targets actually build a slightly different set of files. Some specifics:
- The insecure build includes init_unsecure.cc and grpc_unsecure_plugin_registry.cc, whereas the secure build includes init_secure.cc and grpc_plugin_registry.cc.
- Both secure and insecure builds depend on
grpc_transport_chttp2_client_insecureandgrpc_transport_chttp2_server_insecure(which definegrpc_insecure_channel_create()andgrpc_server_add_insecure_http2_port()), but the secure build additionally depends ongrpc_transport_chttp2_client_secureandgrpc_transport_chttp2_server_secure(which definegrpc_server_add_secure_http2_port()andgrpc_secure_channel_create()).I think what we want here is to eliminate the conditional compilation and make the secure target a simple layer on top of the insecure target that adds the dependencies for the credential types (which bring in the SSL library dependency).
Here are some specific changes we should make:
- Move the code from init_secure.cc directly into init.cc, and remove init_secure.cc and init_unsecure.cc. Also remove the relevant declarations in init.h, since those functions can now be static inside of init.cc.
- Move the code from grpc_plugin_registry.cc into init.cc and remove both grpc_plugin_registry.cc and grpc_unsecure_plugin_registry.cc.
- Eliminate
grpc_insecure_channel_create()andgrpc_server_add_insecure_http2_port()from the API and renamegrpc_server_add_secure_http2_port()andgrpc_secure_channel_create()to justgrpc_server_add_http2_port()andgrpc_channel_create(). This will require a gRFC. As part of this, we should probably move their declarations from grpc_security.h to grpc.h. And instead of the code being in src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc and src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc, it should be moved to the existing src/core/ext/transport/chttp2/client/chttp2_connector.cc and src/core/ext/transport/chttp2/server/chttp2_server.cc files.
Done. I will work on gRFC in parallel.
BUILD, line 1313 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
Here's another case where we have some conditional compilation for insecure builds that needs to be cleaned up.
We currently have two targets for grpclb, one for insecure builds (this one) and another for secure builds (the next one,
grpc_lb_policy_grpclb_secure). The only difference between the two is that the insecure one uses the file grpclb_channel.cc, whereas the secure one uses the file grpclb_channel_secure.cc. Both files provide the interface defined in grpclb_channel.h, but with different implementations for the two different builds. And we have the build dependencies set up such that insecure builds and secure builds depend on the right version of this target.This difference is no longer needed now that insecure builds are going away. Instead, let's do the following:
- Move the code from grpclb_channel_secure.cc directly into grpclb.cc.
- Remove the files grpclb_channel.h, grpclb_channel.cc, and grpclb_channel_secure.cc.
- Remove the
grpc_lb_policy_grpclb_securetarget.- Remove the
grpc_lb_policy_grpclb_securedependency from thegrpctarget, and addgrpc_lb_policy_grpclbas a dependency ofgrpc_common.- Change the
grpc_lb_policy_grpclbtarget to depend ongrpc_transport_chttp2_client_secureinstead ofgrpc_transport_chttp2_client_insecure.
Done.
BUILD, line 1847 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
Suggest calling this
grpc_security_base.
Done.
BUILD, line 1860 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
These TSI files are already present in the
tsitarget, and they should not be in more than one build target. I think we still need thetsitarget, because there are internal callers like GFE that depend on TSI without necessarily depending on gRPC, so we can't just remove that target. So we'll need to make this target depend on thetsitarget.Of course, we can't just depend on the
tsitarget as it currently exists, because that would pull in the SSL library dependency that we're trying to eliminate here. To avoid this, I suggest the following:
- Move the "base" TSI files (like src/core/tsi/transport_security.cc) into a new target called
tsi_base, which can be a dependency of both this target and thetsitarget.- For each credential type, move the TSI files into a new target called
tsi_${type}_credentials, which can be a dependency of both thetsitarget and the correspondinggrpc_${type}_credentialstarget. (For example, a file like src/core/tsi/fake_transport_security.cc would be in a target calledtsi_fake_credentials, which would be a dependency of both thetsitarget and thegrpc_fake_credentialstarget, so thegrpc_fake_credentialstarget would not need to directly include that .cc file.)
Done.
BUILD, line 1944 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
These upb files should not be repeated here. Instead, add a dependency on the existing
alts_upbtarget.
Done.
src/core/lib/security/security_connector/security_connector.h, line 45 at r3 (raw file):
Previously, markdroth (Mark D. Roth) wrote…
This seems like the wrong place for this definition, since there is nothing SSL-specific in this file. I think this should be kept where it was originally, in ssl_utils.h. Was there some reason you needed to move it?
GRPC_SSL_URL_SCHEME is currently defined in ssl_utils.h and used in client_auth_filter.cc. ssl_utils.h belongs to tsi_ssl_credentials target that brings in openssl dependency, while client_auth_filter.cc belongs to grpc_security_base that cannot depend on openssl.
There are only two constants related to the URL scheme - 1) GRPC_SSL_URL_SCHEME and 2) GRPC_FAKE_SECURITY_URL_SCHEME, and I moved both of them to security_connector.h so that it does not just include SSL-specific in the file. Also since grpc_security_connector takes the url scheme as a parameter, I think it makes sense to define those two constants in this header file.
|
Regarding the comment on |
|
F.Y.I. @markdroth, I think I addressed all of your comments, but there are still some build issues related to the wrapped languages. Let me first fix them, and I will let you know when it's ready for the next round of review. |
Yes, I was thinking that Alternatively, it would also be okay to rename |
|
+1 for the |
|
If we do actually have users that want to be able to use creds with |
|
Let's do it... I'll track down who it was later.
…On Fri, Jul 9, 2021 at 2:36 PM Mark D. Roth ***@***.***> wrote:
If we do actually have users that want to be able to use creds with
create_channel_from_fd(), then let's go ahead and do that. It will save
us the step of writing a separate gRFC for that change later.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#25586 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACNG45LXJHWFEGOUMUHADFLTW5TUNANCNFSM4YM4AVBA>
.
|
|
Hi @markdroth, I might need your help in debugging the following two C++ test failures (you can find more detailed error log in https://source.cloud.google.com/results/invocations/9f96e1d1-5afd-474b-bdfa-00422ee15243/targets):
The only change that could be relevant is to convert the |
|
@yashykt Fyi. |
| GRPC_STATUS_DEADLINE_EXCEEDED); | ||
| // Since the subchannel is shared, the second channel should also have | ||
| // keepalive settings in sync with the server. | ||
| // Since the subchannel is not shared any more, the second channel should not |
There was a problem hiding this comment.
Please revert this change. After #28777 the subchannels should be shared.
There was a problem hiding this comment.
Thanks for pointing it out!
| grpc_channel* channel = | ||
| grpc_channel_create(server_address.c_str(), creds, &client_channel_args); | ||
| grpc_channel_credentials_release(creds); | ||
| grpc_channel_credentials* another_creds = grpc_insecure_credentials_create(); |
There was a problem hiding this comment.
No need for another_creds. It's fine to use the same creds object for both channels.
|
@yihuazhang Given that this is a large change, when will we have confidence that it has landed and will not get reverted? Can you please comment here when the change has successfully been imported and after you've checked that all the go/grpc-fusion-master tests are still passing? |
|
The change has been successfully imported yesterday. I will probably give it a week to gain enough confidence that the change will not get reverted. |
This PR is a part of the effort for removing gRPC insecure build so that all gRPC targets can depend on secure builds. Another purpose of this PR is to refactor the BUILD file so that for the targets that do not rely on SSL, they will not link
libssltargets.After this PR, there will be the following continuous efforts.
This change is