-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Is there a way to configure NettyServerBuilder with SniHandler? #7397
Comments
As far as I can tell, this is not possible at the moment. Here are my notes on what I think would need to be implemented to support SNI:
|
That's right, you would need the Want to contribute? |
Possibly, I have a hacky patch sufficient for my needs working locally. I think I would like to see the Similarly, @dapengzhang0 let me know what you think about some appropriate builder API changes and I'll contribute the changes at some point. If someone else finds they need this, just leave a comment here and I would be happy to contribute it sooner. |
cc @ejona86 |
I'm not all that impressed with SniHandler. I understand the need, but I don't think we'd want to use it. It is really most useful if you need to asynchronously determine the server certificate, like if you were going to generate them on-the-fly. But that's not all that common and based on the API you suggested, isn't something you are looking for. In the normal case, this is really the job of an X509ExtendedKeyManager, as the I agree there are ways to make that easier. It could deserve a convenience implementation. But "this is just how Java does it" and it's really a separate issue than the API we provide. |
@ejona86 thanks for taking the time to look into this. My understanding is that your suggestion would work as follows. The server side The client side A major limitation of this approach is that the server must choose an alias from a single My use case involves starting with the equivalent of a I can't see an obvious way to achieve the last point, where I need to construct a single Do you have any words of advice for this last point? |
Given that both Since |
I think the current conclusion is that |
That's already handled. Lots of modern Internet infrastructure would break without the client providing SNI.
I'd accept "it is a huge pain to configure multiple aliases," but it is possible. The alias lookup is part of the KeyManager, so you can totally return them. Java's After poking around a bit, it looks like this actually works out-of-the-box (in the Java sense, not gRPC), where you don't need to write any SNI lookup code, as long as you have multiple entries in your keystore. Java's "New" X509KeyManager searches through all the aliases looking for a certificate that matches the SNI name. You just have to make sure to use the newer X509 key manager and not the older SunX509 key manager. To make the keystore, I used openssl to create p12 files of the cert+key. Then I used keytool to combine them into a single file. (I used "changeit" as all my passwords)
And then to create the Netty SslContext: KeyStore store = KeyStore.getInstance("PKCS12");
store.load(TestUtils.class.getResourceAsStream("/certs/server.p12"),
"changeit".toCharArray());
KeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509");
factory.init(store, "changeit".toCharArray());
sslContext =
GrpcSslContexts.configure(SslContextBuilder.forServer(factory))
.build(); It is possible to build the KeyStore at runtime, but converting a file-based private key to the Java PrivateKey class is needlessly annoying. Normally Netty's utilities do that for you, but that's not available here to my knowledge. |
Thanks, I missed the The The The This looks good for the server side behaviour. My understanding is that the client side still needs an This is the last piece, if there is a way to change the client |
I think I can do this with a Thanks again for your help digging into this. |
SNI is already handled. I think via passing "host" to So there should be no need to change anything on client-side. |
Thanks, I will close this once I have verified for myself. During my previous testing I did not see the client side work out of the box and had to make the change mentioned above, so not sure what was going on there. |
Did your testing include the case that the client host is for an authority different than the actual host? I think that might have been where the issue was on the client side. |
That's actually the only case I tested, since I was contacting localhost I used channelBuilder.overrideAuthority() to provide the name to be used for TLS/virtual hosting. |
With the setup I was using previously involving This seems to indicate that the SSL client hello packet does not contain the SNI information for some reason. I'm not sure how this differs with your approach, but it definitely looks like the hello packet in my test using a standard |
I made the Wireshare trace: tls trace - with sni.pcapng.gz. It shows SNI working just fine. Below is a screenshot. I used the interop client and server with SNI is handled by the actual TLS implementation. It is possible there's some issue there. I know different implementations behave differently when the hostname ends in a dot (e.g., |
I tracked it down to Ok I think I am good here now, thanks again for your help. |
Is it possible to configure
io.grpc.netty.NettyServerBuilder
withio.netty.handler.ssl.SniHandler
for Server Name Indication capabilities of a gRPC server?I would like to use SNI to switch the server certificates used based on the host name.
The text was updated successfully, but these errors were encountered: