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

Allow us to point all the grpc servers at files to pick up credentials #120

Closed
Jonpez2 opened this issue May 26, 2021 · 13 comments
Closed

Comments

@Jonpez2
Copy link
Contributor

Jonpez2 commented May 26, 2021

I'm currently trying to plug together SPIFFE (https://github.com/spiffe) and buildbarn in a deployment on GKE, to give me well-managed mTLS. My current approach is to use the spiffe-helper (https://github.com/spiffe/spiffe-helper) to keep pem files up to date on the in one container, with spiffe-helper just invoking 'sleep infinity', and then having the buildbarn container share a filesystem so that it can read the resultant certs. Note that SPIFFE rotates the leaf certificates very frequently - on the order of once per hour. This is pretty painful however, as buildbarn uses jsonnet to pipe creds through to the process, which means that a hot reload of the rotated certs is impossible without a full restart.

I'm thinking that the best option here would be for buildbarn to allow specification of a set of files for certs, and then just use grpc's hot reloading code as demonstrated here - https://github.com/grpc/grpc-go/blob/master/security/advancedtls/examples/credential_reloading_from_files/server/main.go

Does that seem right? Or am I missing something obvious?

Thank you!

@Jonpez2
Copy link
Contributor Author

Jonpez2 commented Jun 4, 2021

Any thoughts on this please? Would you prefer me to propose a code change?

@EdSchouten
Copy link
Member

Hey! Sorry for letting you wait.

I'm fine with supporting use cases like these. I think the cleanest way to support this is to factor out the keypair string fields we have in our config files to a separate Protobuf message. We can then use a oneof in there to choose between providing the key material inline, vs. using other frameworks.

Instead of using stuff like spiffe-helper, I'm also fine with integrating https://github.com/spiffe/go-spiffe/tree/main/v2. That way you don't need to run all sorts of sidecars just to get TLS working.

@Jonpez2
Copy link
Contributor Author

Jonpez2 commented Jul 16, 2021

My turn to apologize to you!

So actually an even better approach (for me anyway!) would be to upgrade to grpc 1.38.0 and then allow use of xds, like this: https://cloud.google.com/traffic-director/docs/security-proxyless-setup. That still requires a bit of changes inside buildbarn - specifically, all the servers will have to do this (https://github.com/grpc/grpc-go/blob/master/examples/features/xds/server/main.go#L82) - but it means that all the certificate specification and discovery and so forth becomes someone else's problem. Wdyt?

@EdSchouten
Copy link
Member

Oh, that would be pretty sweet. Feel free to submit a PR to add a gRPC configuration for enabling xDS!

@Jonpez2
Copy link
Contributor Author

Jonpez2 commented Jul 16, 2021 via email

@Jonpez2
Copy link
Contributor Author

Jonpez2 commented Jul 19, 2021

Nothing is ever simple...
grpc/grpc-go#4601

EdSchouten added a commit that referenced this issue Jul 19, 2021
Modern versions of protoc-gen-go shipped with gRPC will emit
grpc.ServiceRegistrar as part of all generated code, as opposed to using
*grpc.Server:

grpc/grpc-go@9519eff#diff-c765195c37749c9c3591e05f8f0c77858ea5aa093e9b6f3f7a339309f9e507b2

The advantage of this is that gRPC services can be registered against
custom server types. Those include the xDS server type that @Jonpez2 is
trying to use in #120.

This change effectively backports the commit linked above to the older
version of protoc-gen-go that is part of the old Protobuf v1 repository.
Ideally we wouldn't use that compiler at all, but it looks like there
are still several blockers on the rules_go side to switch to the updated
compiler.
@EdSchouten
Copy link
Member

EdSchouten commented Jul 19, 2021

Hey @Jonpez2!

Would a change like this be of any use to you?

https://github.com/buildbarn/bb-storage/compare/eschouten/20210719-service-registrar

This would allow you to write something like this in pkg/grpc/server.go:

var s interface {
    grpc.ServiceRegistrar
    GetServiceInfo() map[string]grpc.ServiceInfo
    Serve(net.Listener) error
}
if useXDS {
    s = xds.NewGRPCServer(...)
} else {
    s = grpc.NewServer(...)
}

// The rest of the code that registers services and calls .Serve() can go here.

Just let me know and I'll merge this.

@Jonpez2
Copy link
Contributor Author

Jonpez2 commented Jul 19, 2021 via email

@EdSchouten
Copy link
Member

EdSchouten commented Jul 19, 2021

Great! Merged!

It looks like the construct is sufficient for you to achieve what you want, as long as you take the following into account:

@Jonpez2
Copy link
Contributor Author

Jonpez2 commented Jul 21, 2021 via email

@EdSchouten
Copy link
Member

It looks like v2 hasn't been released yet, so it wouldn't make a lot of sense to invest in that right now. I'd say, just put that PR that I linked above into the already existing patches/com_github_grpc_ecosystem_go_grpc_prometheus/ directory.

@Jonpez2
Copy link
Contributor Author

Jonpez2 commented Jul 22, 2021

ok!

@EdSchouten
Copy link
Member

Considering that this issue hasn't received any updates for >1y, I'm going to close it. It should be easier nowadays to get xDS support added, especially with the preparations discussed above. Happy to receive contributions going forward!

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

No branches or pull requests

2 participants