This bug reports some usability issues with TLS in tonic.
tonic = "0.1.0-alpha.3"
tonic-build = "0.1.0-alpha.3"
Windows 64-bit
When building a grpc client with tonic and rustls flag, without specifying a certificate in the builder, I expected tonic to find my server's certificate in the root store, but instead I get some pretty cryptic error messages out of webpki crate.
I did some digging, and even opened an issue on webpki. The short of it: Tonic is able to build a full certificate chain. That's about all I know about that topic! I really know nothing about it. What fixed it for me was adding a line like this when creating my client config:
tls.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
I don't know exactly what this line does, but it does fix my problem. It does require a new dependency on the webpki_roots crate.
I could set the trust anchors manually, but it would circumvent a lot of the boilerplate tonic provides around rustls and ClientConfig.
Does it make sense to add this behavior and dependency to tonic? My first reaction is no, but this seems like something others might trip on, and it would be nice if tonic exposed this for free for users like me that need it. Perhaps behind a feature flag? I also don't know if OpenSSL operates the same way and would take advantage of the feature in the same way. I wasn't able to try it because OpenSSL linking is a bit awkward on windows.
I'm happy to PR a change in!
This is a really good question! So most gRPC examples I've seen have their own ca roots so I have not really seen users require this but I think its something we might be able to support. I'm not opposed to adding an additional feature flag around adding default roots. So I believe the webpki_roots::TLS_SERVER_ROOTS is actually just the mozilla one, where as I believe with openssl you can probe the system for its certs. I'm not sure if we should expose this as a builder since they can vary? I'm not the biggest expert on TLS so not sure what the right path is.
@jen20 any thoughts?
I think we should definitely expose a way to make this simpler - I'll take a look into some of the options and have a think about what could be done.
I spent some time this week to learn a bit about TLS and certificate trust chains. I found the docs at Let's Encrypt to be super useful!
https://letsencrypt.org/certificates/
It's now a little more clear now that rustls::RootCertStore::add_server_trust_anchors is simply adding the Mozilla root certificates to the TLS config. This can also be achieved by downloading the certificates from Mozilla and adding them with ClientTlsConfig::ca_certificate. That solution also works for both OpenSSL and Rustls TLS configs.
I am guessing GRPC community feels pretty comfortable with these certs because they keep updated the Mozilla root certificates in their git repo. I asked around in the GRPC gitter and I think they simply bake in the certs to the GRPC libraries. This is useful when running on an OS like windows where there is no standard location for trusted certs.
https://github.com/grpc/grpc/tree/master/etc
I think it may be useful to either:
Either option would address the basic needs for users like me, and any users who care about initialization cost or root certs wouldn't need to pay the cost by default.
Hi @xmclark! Personally I think I'd tend towards option 1 here. I can likely put together a pull request for this fairly quickly, as I have some other work in flight for TLS bits.
Option one sounds like a great idea!
Super happy to see #114 opened. I pointed my current grpc project using tonic to the jen20/tls-trust-roots branch and it works beautifully using ClientTlsConifg::add_trust_anchors!
I don't mind tonic paying the extra cost of importing the mozilla certs for rustls usage. I think most other grpc libraries do this by default anyways.
I just saw announcement for rustls-native-certs. This may be something else to consider. It has cross platform support.
Oh very nice! @jen20 happy with what ever you think we should go with
I'll update #114 to use the native certs crates, that is likely a more appropriate option than simply relying on the Mozilla roots.
@xmclark this should be fixed with #114, feel free to reopen if there are any more issues.
Most helpful comment
I think we should definitely expose a way to make this simpler - I'll take a look into some of the options and have a think about what could be done.