Summary
SSL Modes
V1 historically has ssl_mode parameter with two options (NONE and STRICT). When NONE is selected then SSL encryption is used but no identity
verification is done (what is conter-intuitive). When STRICT is used then full verification is done. Last option is just placeholder for default behavior
which is full verification.
Usually JDBC drivers provide more options to verify identity and server certificate.This is important to support in ClickHouse Java and JDBC because
many modern systems not always use strict verification. For example, k8s environment can use self-signed certificates per host. This means that
custom CA certification is needed. In other scenarios there could be only custom certificate for multiple endpoints and identity verification should be skipped.
Client V2 should support next values for ssl_mode:
Disabled - disabled encryption and verification. This option cannot be used with HTTP(s) interface because protocol itself defines usage of SSL.
This option will be used for TCP protocol because usage of SSL defined by client.
Trust - trusts server certificate and do not validates identity against certificate. Traffic is encrypted.
VerifyCa - verifies server certificate (it should be sugned by trusted CA) but skips identity verification (doesn't check hostname matches ceriticate).
This used when one SSL certificate for multiple hosts. Traffic is encrypted.
Strict- default behavior when server certificate is verified fully. This classic connection to ClickHouse cloud.
JDBC V2 should support next values for ssl_mode:
none - for backward compatibility only. This option is alias to trust on client side.
disabled - same as client v2
trust - same as client v2
verify-ca - same as client v2
strict - same as client v2
Certificate Authority Verification
Certificate should be signed by trusted CA. JVM trusts all ceriticates that are signed by CA from default truststore. However adding
certificate to each JVM truststore can be problematic and insecure (because all parts of application running on the JVM become
accepting custom CA what can be used by attackers). Thus client library provide way to specify custom truststore only for its communication.
Truststore is a file and not always suitable so client can accept root certificate as string.
Identity Verification
Server hostname should match certificate it provides on connection. When same certificte is issues for multiple server endpoint then this verification
will fail. Thus there is option verify-ca.
Code Changes
Preparation
- Fix handling custom CA certificate. When it is specified alone it should be added to context truststore. It is done in
com.clickhouse.client.api.internal.HttpAPIClientHelper#createSSLContext.
- Also there should be test and verification that root certificate can be passed as string.
- We need good example to demonstrate each scenario in action. This examples will be used in documentation. Examples should be added for currently supported scenarios: custom root certificate.
Changes in Client V2
- Add
SSLMode enum with constants Disabled, Trust, VerifyCa and Strict.
- Add
SSL_MODE("ssl_mode", SSLMode.class, SSLMode.Strict) to com.clickhouse.client.api.ClientConfigProperties. Documentation should tell about modes,
how it works with different protocols and that it doesn't make client use encryption on HTTP protocol.
- Make
com.clickhouse.client.api.internal.HttpAPIClientHelper#createSSLContext handle modes:
SSLMode.Trust should use all trust store
SSLMode.VerifyCA should use all trust host verifier.
- other modes are irrelevant here.
- Handle
com.clickhouse.client.api.ClientConfigProperties#CA_CERTIFICATE correctly and independently from SSL_KEY and SSL_CERTIFICATE in com.clickhouse.client.api.internal.HttpAPIClientHelper#createSSLContext:
- When truststore is specified than CA certificate should be missing as it is in truststore. When CA certificate present then it is added to dynamically created truststore.
- When
SSL_KEY and SSL_CERTIFICATE are specified it mean MTL or SSL authentication is used and this should be added to ssl context.
- When
SSLMode.Trust then ClickHouseSslMode.NONE should be passed to ClickHouseDefaultSslContextProvider when creating context.
- When
SSLMOde.VerifyCA then all trust host verifier should be used
- In
com.clickhouse.client.api.internal.HttpAPIClientHelper#createHttpClient make handle SSLMode.Trust and SSLMode.VerifyCA by using all trust host verifier. It is similar to when SNI is used.
Tests for all SSL modes should be added and be run against docker instance.
Changes in JDBC V2
- Add special handling of
ssl_mode in passed properties before sending them to client builder. Make alias from none to trust in this case.
Tests for all SSL modes should be also added to JDBC connection tests.
Closes: #2389
Closes: #2309
Closes: #2819
Checklist
Delete items not relevant to your PR:
Summary
SSL Modes
V1 historically has
ssl_modeparameter with two options (NONEandSTRICT). WhenNONEis selected then SSL encryption is used but no identityverification is done (what is conter-intuitive). When
STRICTis used then full verification is done. Last option is just placeholder for default behaviorwhich is full verification.
Usually JDBC drivers provide more options to verify identity and server certificate.This is important to support in ClickHouse Java and JDBC because
many modern systems not always use strict verification. For example, k8s environment can use self-signed certificates per host. This means that
custom CA certification is needed. In other scenarios there could be only custom certificate for multiple endpoints and identity verification should be skipped.
Client V2 should support next values for
ssl_mode:Disabled- disabled encryption and verification. This option cannot be used with HTTP(s) interface because protocol itself defines usage of SSL.This option will be used for TCP protocol because usage of SSL defined by client.
Trust- trusts server certificate and do not validates identity against certificate. Traffic is encrypted.VerifyCa- verifies server certificate (it should be sugned by trusted CA) but skips identity verification (doesn't check hostname matches ceriticate).This used when one SSL certificate for multiple hosts. Traffic is encrypted.
Strict- default behavior when server certificate is verified fully. This classic connection to ClickHouse cloud.JDBC V2 should support next values for
ssl_mode:none- for backward compatibility only. This option is alias totruston client side.disabled- same as client v2trust- same as client v2verify-ca- same as client v2strict- same as client v2Certificate Authority Verification
Certificate should be signed by trusted CA. JVM trusts all ceriticates that are signed by CA from default truststore. However adding
certificate to each JVM truststore can be problematic and insecure (because all parts of application running on the JVM become
accepting custom CA what can be used by attackers). Thus client library provide way to specify custom truststore only for its communication.
Truststore is a file and not always suitable so client can accept root certificate as string.
Identity Verification
Server hostname should match certificate it provides on connection. When same certificte is issues for multiple server endpoint then this verification
will fail. Thus there is option
verify-ca.Code Changes
Preparation
com.clickhouse.client.api.internal.HttpAPIClientHelper#createSSLContext.Changes in Client V2
SSLModeenum with constantsDisabled,Trust,VerifyCaandStrict.SSL_MODE("ssl_mode", SSLMode.class, SSLMode.Strict)tocom.clickhouse.client.api.ClientConfigProperties. Documentation should tell about modes,how it works with different protocols and that it doesn't make client use encryption on HTTP protocol.
com.clickhouse.client.api.internal.HttpAPIClientHelper#createSSLContexthandle modes:SSLMode.Trustshould use all trust storeSSLMode.VerifyCAshould use all trust host verifier.com.clickhouse.client.api.ClientConfigProperties#CA_CERTIFICATEcorrectly and independently fromSSL_KEYandSSL_CERTIFICATEincom.clickhouse.client.api.internal.HttpAPIClientHelper#createSSLContext:SSL_KEYandSSL_CERTIFICATEare specified it mean MTL or SSL authentication is used and this should be added to ssl context.SSLMode.TrustthenClickHouseSslMode.NONEshould be passed toClickHouseDefaultSslContextProviderwhen creating context.SSLMOde.VerifyCAthen all trust host verifier should be usedcom.clickhouse.client.api.internal.HttpAPIClientHelper#createHttpClientmake handleSSLMode.TrustandSSLMode.VerifyCAby using all trust host verifier. It is similar to when SNI is used.Tests for all SSL modes should be added and be run against docker instance.
Changes in JDBC V2
ssl_modein passed properties before sending them to client builder. Make alias fromnonetotrustin this case.Tests for all SSL modes should be also added to JDBC connection tests.
Closes: #2389
Closes: #2309
Closes: #2819
Checklist
Delete items not relevant to your PR: