Scylla Documentation Logo Documentation
  • Server
    • Scylla Open Source
    • Scylla Enterprise
    • Scylla Alternator
  • Cloud
    • Scylla Cloud
    • Scylla Cloud Docs
  • Tools
    • Scylla Manager
    • Scylla Monitoring Stack
    • Scylla Operator
  • Drivers
    • CQL Drivers
    • DynamoDB Drivers
Download
Menu

Caution

You're viewing documentation for a previous version of Scylla Java Driver. Switch to the latest stable version.

Scylla Java Driver Manual SSL

SSL¶

You can secure traffic between the driver and Cassandra with SSL. There are two aspects to that:

  • client-to-node encryption, where the traffic is encrypted, and the client verifies the identity of the Cassandra nodes it connects to;

  • optionally, client certificate authentication, where Cassandra nodes also verify the identity of the client.

This section describes the driver-side configuration; it assumes that you’ve already configured SSL in Cassandra:

  • the Cassandra documentation covers a basic approach with self-signed certificates, which is fine for development and tests.

  • this blog post details a more advanced solution based on a Certificate Authority (CA).

Preparing the certificates¶

Client truststore¶

This is required for client-to-node encryption.

If you’re using self-signed certificates, you need to export the public part of each node’s certificate from that node’s keystore:

keytool -export -alias cassandra -file cassandranode0.cer -keystore .keystore

Then add all public certificates to the client truststore:

keytool -import -v -trustcacerts -alias <cassandra_node0> -file cassandranode0.cer -keystore client.truststore
keytool -import -v -trustcacerts -alias <cassandra_node1> -file cassandranode1.cer -keystore client.truststore
...

If you’re using a Certificate Authority, the client truststore only needs to contain the CA’s certificate:

keytool -import -v -trustcacerts -alias CARoot -file ca.cer -keystore client.truststore

Client keystore¶

If you also intend to use client certificate authentication, generate the public and private key pair for the client:

keytool -genkey -keyalg RSA -alias client -keystore client.keystore

If you’re using self-signed certificates, extract the public part of the client certificate, and import it in the truststore of each Cassandra node:

keytool -export -alias client -file client.cer -keystore client.keystore
keytool -import -v -trustcacerts -alias client -file client.cer -keystore server.truststore

If you’re using a CA, sign the client certificate with it (see the blog post linked at the top of this page). Then the nodes’ truststores only need to contain the CA’s certificate (which should already be the case if you’ve followed the steps for inter-node encryption).

Driver configuration¶

The base class to configure SSL is RemoteEndpointAwareSSLOptions. It’s very generic, but you don’t necessarily need to deal with it directly: the default instance, or the provided subclasses, might be enough for your needs.

JSSE, Property-based¶

withSSL() gives you a basic JSSE configuration:

Cluster cluster = Cluster.builder()
  .addContactPoint("127.0.0.1")
  .withSSL()
  .build();

You can then use JSSE system properties for specific details, like keystore locations and passwords:

-Djavax.net.ssl.trustStore=/path/to/client.truststore
-Djavax.net.ssl.trustStorePassword=password123
# If you're using client authentication:
-Djavax.net.ssl.keyStore=/path/to/client.keystore
-Djavax.net.ssl.keyStorePassword=password123

JSSE, programmatic¶

If you need more control than what system properties allow, you can configure SSL programmatically with RemoteEndpointAwareJdkSSLOptions:

SSLContext sslContext = ... // create and configure SSL context

RemoteEndpointAwareJdkSSLOptions sslOptions = RemoteEndpointAwareJdkSSLOptions.builder()
  .withSSLContext(context)
  .build();

Cluster cluster = Cluster.builder()
  .addContactPoint("127.0.0.1")
  .withSSL(sslOptions)
  .build();

Note that you can also extend the class and override newSSLEngine(SocketChannel,InetSocketAddress) if you need specific configuration on the SSLEngine. For example, to enable hostname verification:

SSLContext sslContext = ... // create and configure SSL context

RemoteEndpointAwareJdkSSLOptions sslOptions = new RemoteEndpointAwareJdkSSLOptions(sslContext, null) {
    protected SSLEngine newSSLEngine(SocketChannel channel, InetSocketAddress remoteEndpoint) {
        SSLEngine engine = super.newSSLEngine(channel, remoteEndpoint);
        SSLParameters parameters = engine.getSSLParameters();
        // HTTPS endpoint identification includes hostname verification against certificate's common name.
        // This API is only available for JDK7+.
        parameters.setEndpointIdentificationAlgorithm("HTTPS");
        engine.setSSLParameters(parameters);
        return engine;
    }
};

Cluster cluster = Cluster.builder()
  .addContactPoint("127.0.0.1")
  .withSSL(sslOptions)
  .build();

Netty¶

RemoteEndpointAwareNettySSLOptions allows you to use Netty’s SslContext instead of the JDK directly. The advantage is that Netty can use OpenSSL directly, which provides better performance and generates less garbage. A disadvantage of using the OpenSSL provider is that it requires platform-specific dependencies, unlike the JDK provider.

Converting your client certificates for OpenSSL¶

OpenSSL doesn’t use keystores, so if you use client authentication and generated your certificates with keytool, you need to convert them.

  • use this command to extract the public certificate chain:

    keytool -export -keystore client.keystore -alias client -rfc -file client.crt
    
  • follow this tutorial to extract your client’s private key from client.keystore to a text file client.key in PEM format.

Updating your dependencies¶

Netty-tcnative provides the native integration with OpenSSL. Follow these instructions to add it to your dependencies.

There are known runtime incompatibilities between newer versions of netty-tcnative and the version of netty that the driver uses. For best results, use version 2.0.7.Final.

Using netty-tcnative requires JDK 1.7 or above and requires the presence of OpenSSL on the system. It will not fall back to the JDK implementation.

Configuring the context¶

Use the following Java code to configure OpenSSL with your certificates:

KeyStore ks = KeyStore.getInstance("JKS");
// make sure you close this stream properly (not shown here for brevity)
InputStream trustStore = new FileInputStream("client.truststore");
ks.load(trustStore, "password123".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);

SslContextBuilder builder = SslContextBuilder
  .forClient()
  .sslProvider(SslProvider.OPENSSL)
  .trustManager(tmf);
  // only if you use client authentication
  .keyManager(new File("client.crt"), new File("client.key"));

SSLOptions sslOptions = new RemoteEndpointAwareNettySSLOptions(builder.build());

Cluster cluster = Cluster.builder()
  .addContactPoint("127.0.0.1")
  .withSSL(sslOptions)
  .build();
PREVIOUS
Speculative query execution
NEXT
Statements
  • 3.11.0.x
    • 4.13.0.x
    • 4.12.0.x
    • 4.11.1.x
    • 4.10.0.x
    • 4.7.2.x
    • 3.11.2.x
    • 3.11.0.x
    • 3.10.2.x
    • 3.7.2.x
  • Scylla Java Driver for Scylla and Apache Cassandra®
  • API Documentation
  • Manual
    • Address resolution
    • Asynchronous programming
    • Authentication
    • Compression
    • Control connection
    • Custom Codecs
    • Custom Payloads
    • Query idempotence
    • Load balancing
    • Logging
    • Metadata
    • Metrics
    • Native protocol
    • Object Mapper
      • Definition of mapped classes
      • Using custom codecs
      • Using the mapper
    • OSGi
    • Paging
    • Connection pooling
    • Query timestamps
    • Reconnection
    • Retries
    • Using the shaded JAR
    • Socket options
    • Speculative query execution
    • SSL
    • Statements
      • Simple statements
      • Prepared statements
      • Built statements
      • Batch statements
    • Using Tuples with the Java driver
    • User-defined types
  • Upgrade guide
    • Migrating from Astyanax
      • Configuration
      • Language change : from Thrift to CQL
      • Queries and Results
  • Frequently Asked Questions
  • Changelog
  • Create an issue
  • Edit this page

On this page

  • SSL
    • Preparing the certificates
      • Client truststore
      • Client keystore
    • Driver configuration
      • JSSE, Property-based
      • JSSE, programmatic
      • Netty
        • Converting your client certificates for OpenSSL
        • Updating your dependencies
        • Configuring the context
Logo
Docs Contact Us About Us
Mail List Icon Slack Icon
© 2022, ScyllaDB. All rights reserved.
Last updated on 25 May 2022.
Powered by Sphinx 4.3.2 & ScyllaDB Theme 1.2.2