2727 * <li>Passing the CA certificate as a PEM string instead of a file path - useful when the
2828 * certificate comes from an environment variable or a secret manager (typical for
2929 * Kubernetes/cloud deployments) and you do not want to write it to disk.</li>
30+ * <li>Connecting to a server with a self-signed certificate without any trust material -
31+ * the {@code ssl_mode=trust} connection property accepts any server certificate and skips
32+ * hostname verification ({@code ssl_mode=none} is accepted as an alias). Use it only for
33+ * testing or in fully trusted environments.</li>
3034 * </ul>
3135 *
3236 * <p>More SSL examples (mTLS, trust stores, SNI) will be added to this class later.</p>
4549 * <li>{@code chUrl} - ClickHouse JDBC URL, e.g. {@code jdbc:clickhouse://my-host:8443/default}.
4650 * When set, standalone mode is used</li>
4751 * <li>{@code chUser} and {@code chPassword} - credentials (standalone mode)</li>
48- * <li>{@code chRootCert} - path to the root CA certificate in PEM format (required in standalone mode)</li>
52+ * <li>{@code chRootCert} - path to the root CA certificate in PEM format. When omitted in
53+ * standalone mode, only the self-signed (trust) example runs</li>
4954 * <li>{@code chImage} - Docker image for local mode, default {@code clickhouse/clickhouse-server:latest}</li>
5055 * </ul>
5156 */
@@ -60,18 +65,19 @@ public static void main(String[] args) {
6065 final String user = System .getProperty ("chUser" , "default" );
6166 final String password = System .getProperty ("chPassword" , "" );
6267 final String rootCert = trimToNull (System .getProperty ("chRootCert" ));
63- if (rootCert == null ) {
64- log .error ("chRootCert is required when chUrl is set. "
65- + "Pass the path to the CA certificate (PEM) that signed the server certificate." );
66- return ;
67- }
6868
6969 log .info ("Running in standalone mode against {}" , url );
7070 try {
71- connectWithCustomRootCertificate (url , user , password , rootCert );
72- connectWithRootCertificateAsString (url , user , password , rootCert );
71+ connectToSelfSignedServer (url , user , password );
72+ if (rootCert != null ) {
73+ connectWithCustomRootCertificate (url , user , password , rootCert );
74+ connectWithRootCertificateAsString (url , user , password , rootCert );
75+ } else {
76+ log .info ("chRootCert is not set - skipping the custom CA certificate examples. "
77+ + "Pass the path to the CA certificate (PEM) that signed the server certificate to run them." );
78+ }
7379 } catch (SQLException | IOException e ) {
74- log .error ("Secure connection with a custom root CA certificate failed" , e );
80+ log .error ("Secure connection failed" , e );
7581 }
7682 return ;
7783 }
@@ -81,6 +87,8 @@ public static void main(String[] args) {
8187 final String image = System .getProperty ("chImage" , "clickhouse/clickhouse-server:latest" );
8288 log .info ("Running in local mode (set -DchUrl to verify your own server)" );
8389 try (SecureServerSupport server = SecureServerSupport .start (image )) {
90+ connectToSelfSignedServer (server .getJdbcUrl (),
91+ SecureServerSupport .USER , SecureServerSupport .PASSWORD );
8492 connectWithCustomRootCertificate (server .getJdbcUrl (),
8593 SecureServerSupport .USER , SecureServerSupport .PASSWORD , server .getCaCertPath ());
8694 connectWithRootCertificateAsString (server .getJdbcUrl (),
@@ -93,6 +101,37 @@ public static void main(String[] args) {
93101 Runtime .getRuntime ().exit (0 );
94102 }
95103
104+ /**
105+ * Connects to a ClickHouse server with a self-signed certificate without providing
106+ * any trust material. The {@code ssl_mode=trust} connection property makes the driver
107+ * accept any server certificate and skip hostname verification. The traditional JDBC
108+ * value {@code ssl_mode=none} is accepted as an alias.
109+ *
110+ * <p><b>Warning:</b> the connection is encrypted, but the server identity is NOT verified,
111+ * which makes it susceptible to man-in-the-middle attacks. Use this mode only for testing
112+ * or in fully trusted environments. Prefer {@code sslrootcert} with the signing CA
113+ * certificate whenever possible.</p>
114+ */
115+ static void connectToSelfSignedServer (String url , String user , String password ) throws SQLException {
116+ log .info ("Connecting to {} accepting any server certificate (ssl_mode=trust)" , url );
117+
118+ Properties properties = new Properties ();
119+ properties .setProperty (ClientConfigProperties .USER .getKey (), user ); // user
120+ properties .setProperty (ClientConfigProperties .PASSWORD .getKey (), password ); // password
121+ properties .setProperty ("ssl" , "true" ); // enable TLS even if the URL has no https scheme
122+ // Accept the self-signed certificate and skip hostname verification.
123+ properties .setProperty (ClientConfigProperties .SSL_MODE .getKey (), "trust" ); // ssl_mode
124+
125+ try (Connection connection = DriverManager .getConnection (url , properties );
126+ Statement stmt = connection .createStatement ();
127+ ResultSet rs = stmt .executeQuery ("SELECT currentUser() AS user, version() AS version" )) {
128+ if (rs .next ()) {
129+ log .info ("Connected (server certificate not verified) as '{}' to ClickHouse {}" ,
130+ rs .getString ("user" ), rs .getString ("version" ));
131+ }
132+ }
133+ }
134+
96135 /**
97136 * Connects to a ClickHouse server using a custom root CA certificate.
98137 * Use this when the server certificate is signed by a private CA (corporate CA,
0 commit comments