-
Notifications
You must be signed in to change notification settings - Fork 184
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 using null
peer host for TLS and disabling host and port inference and SNI altogether.
#1561
Conversation
servicetalk-transport-api/src/main/java/io/servicetalk/transport/api/ClientSslConfig.java
Outdated
Show resolved
Hide resolved
servicetalk-transport-api/src/main/java/io/servicetalk/transport/api/ClientSslConfig.java
Outdated
Show resolved
Hide resolved
servicetalk-http-netty/src/test/java/io/servicetalk/http/netty/SslAndNonSslConnectionsTest.java
Show resolved
Hide resolved
5727fea
to
0d5e0a3
Compare
0d5e0a3
to
31043de
Compare
null
peer host for TLS and disabling host and port inference and SNI altogether.
* via {@link #sslConfig(ClientSslConfig)}. | ||
* @return {@code this} | ||
*/ | ||
public abstract SingleAddressHttpClientBuilder<U, R> disableSni(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
disableSni
-> disableSniInference
? Can you clarify why this method is different than the other new methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider the following names to allow users set/unset the value on the builder:
peerHostInference(boolean)
peerPortInference(boolean)
sniHostnameInference(boolean)
or
inferPeerHost(boolean)
inferPeerPort(boolean)
inferSniHostname(boolean)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Scottmitch my reasoning was the following: the inference for SNI is less straightforward than for peerHost – internally, the X509TrustManagerImpl
does a fallback to peerHost when checking the certificate identity. The internals also explicitly add the peerHost to the SNI list.
The existing fallback may seem confusing, hence I decided disabling SNI is the functionality that might be useful. Yet still, my attempt at allowing disabling is not really effective because of the fallback in JDK and Netty. I'll change to the inference related method.
@@ -256,7 +256,7 @@ public ClientSslConfig asSslConfig() { | |||
} | |||
|
|||
if (hostnameVerificationAlgorithm == null) { | |||
builder.disableHostnameVerification(); | |||
builder.hostnameVerificationAlgorithm(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add at the end of @deprecated
description of ClientSslConfigBuilder#disableHostnameVerification()
that if users are sure they need to disable it, they can use hostnameVerificationAlgorithm("")
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* via {@link #sslConfig(ClientSslConfig)}. | ||
* @return {@code this} | ||
*/ | ||
public abstract SingleAddressHttpClientBuilder<U, R> disableSni(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider the following names to allow users set/unset the value on the builder:
peerHostInference(boolean)
peerPortInference(boolean)
sniHostnameInference(boolean)
or
inferPeerHost(boolean)
inferPeerPort(boolean)
inferSniHostname(boolean)
Motivation: There are cases when clients require connecting to a secure server which doesn't identify itself in the TLS certificate with the same address as used for connection establishment, or multiple identities can be presented from diffrent underlying backends. In such case the hostname verification would fail and would need to be disabled. However, the peerHost which is inferred from the connection address would unnecessarily cache SSL sessions, which could lead to issues in session resumption. Therefore, we want to allow explicitly disabling peerHost inference and either allow setting it to a desired address or to null. Modifications: - Added ClientSslConfig#isPeerHostSet method, - ClientSslConfigBuilder#setPeerHost now accepts null and disables address inference, - Added test in SslAndNonSslConnectionsTest validating the mentioned scenario, - Added test in SslAndNonSslConnectionsTest for ensuring hostname validation works as expected when hostname is used (existing tests used only IP). Result: It is now possible to explicitly use `null` for `peerHost` and disable its' inference.
…rence and SNI altogether. Motivation: There are cases when clients require connecting to a secure server which doesn't identify itself in the TLS certificate with the same address as used for connection establishment, or multiple identities can be presented from diffrent underlying backends. In such case the hostname verification would fail and would need to be disabled. However, the peerHost which is inferred from the connection address would unnecessarily cache SSL sessions, which could lead to issues in session resumption. Therefore, we want to allow explicitly disabling peerHost inference and either allow setting it to a desired address or leaving `null`. Modifications: - Added SingleAddressHttpClientBuilder#disablePeerHostInference method, - Added SingleAddressHttpClientBuilder#disablePeerPortInference method, - Added SingleAddressHttpClientBuilder#disableSni method, - ClientSslConfigBuilder#setPeerHost now accepts explicit `null`, - Added case in SslAndNonSslConnectionsTest validating the mentioned scenario, - Added case in SslAndNonSslConnectionsTest for ensuring hostname validation works as expected when hostname is used (existing tests used only IP), - Added case in SniTest validating behaviour for disabled SNI and explicitly disabling it in existing `noSni` cases. Result: It is now possible to explicitly use `null` for `peerHost` in `ClientSslConfig` and disable its' inference using `SingleAddressHttpClientBuilder`'s API.
31043de
to
c2c8e1a
Compare
...icetalk-transport-api/src/main/java/io/servicetalk/transport/api/ClientSslConfigBuilder.java
Outdated
Show resolved
Hide resolved
servicetalk-http-netty/src/test/java/io/servicetalk/http/netty/SslAndNonSslConnectionsTest.java
Show resolved
Hide resolved
* via {@link #sslConfig(ClientSslConfig)}. | ||
* @return {@code this} | ||
*/ | ||
public abstract SingleAddressHttpClientBuilder<U, R> disableSni(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Scottmitch my reasoning was the following: the inference for SNI is less straightforward than for peerHost – internally, the X509TrustManagerImpl
does a fallback to peerHost when checking the certificate identity. The internals also explicitly add the peerHost to the SNI list.
The existing fallback may seem confusing, hence I decided disabling SNI is the functionality that might be useful. Yet still, my attempt at allowing disabling is not really effective because of the fallback in JDK and Netty. I'll change to the inference related method.
dc204ed
to
ef843cf
Compare
ef843cf
to
a725289
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one comment then lgtm
|
||
@Nullable | ||
private String evaluatePeerHost() { | ||
return (configPeerHost == null && inferPeerHost) ? fallbackPeerHost : configPeerHost; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider inlining these definitions or making the anonymous type non-anonymous and adding constructor to clarify we don't need to retain references to configPeerHost
and related variables outside the scope of this class.
) | ||
.listenBlockingAndAwait((ctx, request, responseFactory) -> responseFactory.ok()); | ||
BlockingHttpClient client = HttpClients.forSingleAddress( | ||
HostAndPort.of( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: consider removing HostAndPort.of(
and use the method overload that takes String, int
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work!
Doesn't look like this PR breaks any API now. Should we remove breaking-change
label now?
servicetalk-http-netty/src/test/java/io/servicetalk/http/netty/SniTest.java
Outdated
Show resolved
Hide resolved
* @param shouldInfer value indicating whether inference is on ({@code true}) or off ({@code false}). | ||
* @return {@code this} | ||
*/ | ||
public abstract SingleAddressHttpClientBuilder<U, R> inferPeerHost(boolean shouldInfer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We previously discussed in #1561 (comment), but doesn't look like we come to a conclusion. Does it make sense to join peer host and port together on ClientSslConfig
API into a single method HostAndPort peerHostAndPort()
? If yes, we can have a single method here: inferPeerHostAndPort(boolean)
instead of two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Scottmitch wdyt about single ClientSslConfig#peerHostAndPort()
and inferPeerHostAndPort(boolean)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my understanding the peer port is not used when peer host is not inferred (and also is null
). I think it's reasonable to provide an API where both are affected. And yes, the breaking API change would need to go to ClientSslConfig
. Perhaps we could do it in a separate PR and for now add this feature with no breakage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that if we merge host and port into one method, we can provide only one "infer" method and won't need to change client API later.
Let's make the final decision tomorrow morning. Everything else looks good in the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed with @Scottmitch offline. He suggested to keep host and port independent because sometimes users don't know what is the port number (SRV resolutions or use of Unix Domain Sockets).
064d4ce
to
90553c4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
FAILURE: Build failed with an exception.
428 actionable tasks: 353 executed, 75 up-to-date
What went wrong:
Execution failed for task ':servicetalk-http-netty:pmdTest'.
> 4 PMD rule violations were found. See the report at: file:///home/runner/work/servicetalk/servicetalk/servicetalk-http-netty/build/reports/pmd/test.html
The build fails because of #1596. Please, fix PMD warnings and 🚢
Fixed PMD errors, merged with |
…rence and SNI altogether. (apple#1561) Allow using `null` peer host for TLS and disabling host and port inference and SNI altogether. Motivation: There are cases when clients require connecting to a secure server which doesn't identify itself in the TLS certificate with the same address as used for connection establishment, or multiple identities can be presented from diffrent underlying backends. In such case the hostname verification would fail and would need to be disabled. However, the peerHost which is inferred from the connection address would unnecessarily cache SSL sessions, which could lead to issues in session resumption. Therefore, we want to allow explicitly disabling peerHost inference and either allow setting it to a desired address or leaving `null`. Modifications: - Added `SingleAddressHttpClientBuilder#inferPeerHost` method, - Added `SingleAddressHttpClientBuilder#inferPeerPort` method, - Added `SingleAddressHttpClientBuilder#inferSniHostname` method, - `ClientSslConfigBuilder#setPeerHost` now accepts explicit `null`, - Added case in `SslAndNonSslConnectionsTest` validating the mentioned scenario, - Added case in `SslAndNonSslConnectionsTest` for ensuring hostname validation works as expected when hostname is used (existing tests used only IP), - Added case in SniTest validating behaviour for disabled SNI and explicitly disabling it in existing `noSni` cases. Result: It is now possible to explicitly use `null` for `peerHost` in `ClientSslConfig` and disable its' inference using `SingleAddressHttpClientBuilder`'s API.
…1561 Motivation: `ClientSslConfigBuilder#disableHostnameVerification()` option was deprecated in apple#1561 and can be removed now. Users can use `hostnameVerificationAlgorithm("")` as an alternative, but should avoid disabling hostname verification in general. Modifications: - Remove `ClientSslConfigBuilder#disableHostnameVerification()`; Result: No deprecated `ClientSslConfigBuilder#disableHostnameVerification()` API.
…1637) Motivation: `ClientSslConfigBuilder#disableHostnameVerification()` option was deprecated in #1561 and can be removed now. Users can use `hostnameVerificationAlgorithm("")` as an alternative, but should avoid disabling hostname verification in general. Modifications: - Remove `ClientSslConfigBuilder#disableHostnameVerification()`; Result: No deprecated `ClientSslConfigBuilder#disableHostnameVerification()` API.
Motivation: This change follows from [a change to HTTP client builders](apple#1561) and exposes the same capabilities to GRPC client builders. Modifications: - `SingleAddressGrpcClientBuilder` has new methods: `inferPeerHost`, `inferPeerPort`, and `inferSniHostname` which allow configuring the behaviour of the TLS handshake and inference of the corresponding configurations. Result: Users are able to disable peerHost and peerPort inference and can now use an empty peerHost when they so desire. The SNI hostname inference from the provided address can also be disabled in cases when the address used for connection should not be passed in the SNI extension.
…nts (#1678) Motivation: This change follows from [a change to HTTP client builders](#1561) and exposes the same capabilities to GRPC client builders. Modifications: - `SingleAddressGrpcClientBuilder` has new methods: `inferPeerHost`, `inferPeerPort`, and `inferSniHostname` which allow configuring the behaviour of the TLS handshake and inference of the corresponding configurations. Result: Users are able to disable peerHost and peerPort inference and can now use an empty peerHost when they so desire. The SNI hostname inference from the provided address can also be disabled in cases when the address used for connection should not be passed in the SNI extension.
…nts (#1678) Motivation: This change follows from [a change to HTTP client builders](#1561) and exposes the same capabilities to GRPC client builders. Modifications: - `SingleAddressGrpcClientBuilder` has new methods: `inferPeerHost`, `inferPeerPort`, and `inferSniHostname` which allow configuring the behaviour of the TLS handshake and inference of the corresponding configurations. Result: Users are able to disable peerHost and peerPort inference and can now use an empty peerHost when they so desire. The SNI hostname inference from the provided address can also be disabled in cases when the address used for connection should not be passed in the SNI extension.
Motivation:
There are cases when clients require connecting to a secure server which doesn't
identify itself in the TLS certificate with the same address as used for
connection establishment, or multiple identities can be presented from
diffrent underlying backends. In such case the hostname verification would fail
and would need to be disabled. However, the peerHost which is inferred from the
connection address would unnecessarily cache SSL sessions, which could lead
to issues in session resumption. Therefore, we want to allow explicitly disabling
peerHost inference and either allow setting it to a desired address or to null.
Modifications:
works as expected when hostname is used (existing tests used only IP).
Result:
It is now possible to explicitly use
null
forpeerHost
and disable its' inference.