[client-v2] Client does not honor sslMode=none
Description
v1 allowed for ssl connections with sslMode=none, v2 fails
Steps to reproduce
environment
ssl enabled clickhouse with:
mkdir clickhouse-ssl
cd clickhouse-ssl
# Generate private key
openssl genrsa -out server.key 2048
# Generate certificate signing request
openssl req -new -key server.key -out server.csr -subj "/C=US/ST=Test/L=Test/O=Test/CN=localhost"
# Generate self-signed certificate
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
# Generate DH parameters (this may take a while)
openssl dhparam -out dhparam.pem 2048
# Set proper permissions
chmod 600 server.key
chmod 644 server.crt dhparam.pem
ssl-config.xml:
<clickhouse>
<https_port>8443</https_port>
<tcp_port_secure>9440</tcp_port_secure>
<openSSL>
<server>
<certificateFile>/etc/clickhouse-server/ssl/server.crt</certificateFile>
<privateKeyFile>/etc/clickhouse-server/ssl/server.key</privateKeyFile>
<dhParamsFile>/etc/clickhouse-server/ssl/dhparam.pem</dhParamsFile>
<verificationMode>none</verificationMode>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
</server>
<client>
<loadDefaultCAFile>true</loadDefaultCAFile>
<cacheSessions>true</cacheSessions>
<disableProtocols>sslv2,sslv3</disableProtocols>
<preferServerCiphers>true</preferServerCiphers>
<verificationMode>none</verificationMode>
<invalidCertificateHandler>
<name>AcceptCertificateHandler</name>
</invalidCertificateHandler>
</client>
</openSSL>
</clickhouse>
and then run:
docker run -p8123:8123 -p8443:8443 -p9000:9000 -p9440:9440 \
-e"CLICKHOUSE_PASSWORD=password" \
-v $(pwd)/ssl-config.xml:/etc/clickhouse-server/config.d/ssl.xml \
-v $(pwd):/etc/clickhouse-server/ssl \
-it --rm clickhouse/clickhouse-server:latest
Error Log or Exception StackTrace
❯ clj -Sdeps '{:deps {com.clickhouse/clickhouse-jdbc {:mvn/version "0.8.6"}}}'
(let [jdbc-url "jdbc:clickhouse:https://localhost:8443?ssl=true&sslmode=none"
sql "select 1 as happy"]
(with-open [connection (java.sql.DriverManager/getConnection jdbc-url "default" "password")
p-stmt (.prepareStatement connection sql)]
(let [rs (.executeQuery p-stmt)]
(while (.next rs)
(println (.getInt rs "happy"))))))
Execution error (SunCertPathBuilderException) at sun.security.provider.certpath.SunCertPathBuilder/build (SunCertPathBuilder.java:148).
unable to find valid certification path to requested target
user=> (pst 15)
SunCertPathBuilderException unable to find valid certification path to requested target
sun.security.provider.certpath.SunCertPathBuilder.build (SunCertPathBuilder.java:148)
sun.security.provider.certpath.SunCertPathBuilder.engineBuild (SunCertPathBuilder.java:129)
java.security.cert.CertPathBuilder.build (CertPathBuilder.java:297)
sun.security.validator.PKIXValidator.doBuild (PKIXValidator.java:383)
sun.security.validator.PKIXValidator.engineValidate (PKIXValidator.java:271)
sun.security.validator.Validator.validate (Validator.java:256)
sun.security.ssl.X509TrustManagerImpl.checkTrusted (X509TrustManagerImpl.java:230)
sun.security.ssl.X509TrustManagerImpl.checkServerTrusted (X509TrustManagerImpl.java:132)
sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts (CertificateMessage.java:1302)
sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate (CertificateMessage.java:1195)
sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume (CertificateMessage.java:1138)
sun.security.ssl.SSLHandshake.consume (SSLHandshake.java:393)
sun.security.ssl.HandshakeContext.dispatch (HandshakeContext.java:476)
sun.security.ssl.HandshakeContext.dispatch (HandshakeContext.java:447)
sun.security.ssl.TransportContext.dispatch (TransportContext.java:201)
nil
user=>
Compare to the same query with v1 enabled:
❯ clj -J-Dclickhouse.jdbc.v1=true -Sdeps '{:deps {com.clickhouse/clickhouse-jdbc {:mvn/version "0.8.6"}}}'
(let [jdbc-url "jdbc:clickhouse:https://localhost:8443?ssl=true&sslmode=none"
sql "select 1 as happy"]
(with-open [connection (java.sql.DriverManager/getConnection jdbc-url "default" "password")
p-stmt (.prepareStatement connection sql)]
(let [rs (.executeQuery p-stmt)]
(while (.next rs)
(println (.getInt rs "happy"))))))
1
nil
Expected Behaviour
v2 mode should honor sslMode none
Duplicate of https://github.com/ClickHouse/clickhouse-java/issues/2309
The real problem is that there is no good way to use client with self signed certificates.
Having sslmode leads to a security issue - if this parameter is somehow passed to a connection string attacker may connect to any server.
The real problem is that there is no good way to use client with self signed certificates. Having
sslmodeleads to a security issue - if this parameter is somehow passed to a connection string attacker may connect to any server.
@chernser Isn't using sslmode=none similar to using HTTP without SSL, but just that with sslmode=none the data is encrypted? But HTTP is still supported by Clientv2, or is this also disabled for security reasons?
The real problem is that there is no good way to use client with self signed certificates. Having sslmode leads to a security issue - if this parameter is somehow passed to a connection string attacker may connect to any server.
Discussed with @michael-anastasakis. it's aright to provide the escape hatch to users who knows what they do, as long as the secure behaviour is default
duplicate of #2309