Client TLS Configuration
This section covers TLS configuration for Cassandra clients including cqlsh, Java driver, Python driver, and other language drivers.
cqlsh Configuration
Section titled “cqlsh Configuration”Command Line Options
Section titled “Command Line Options”# Basic SSL connectioncqlsh --ssl hostname
# With explicit CA certificatecqlsh --ssl --ssl-certfile=/path/to/ca-cert.pem hostname
# With client certificate (mutual TLS)cqlsh --ssl \ --ssl-certfile=/path/to/ca-cert.pem \ --ssl-keyfile=/path/to/client-key.pem \ --ssl-usercert=/path/to/client-cert.pem \ hostnamecqlshrc Configuration
Section titled “cqlshrc Configuration”Create ~/.cassandra/cqlshrc:
[connection]hostname = cassandra-node-1.example.comport = 9042
[ssl]# Enable SSLcertfile = /path/to/ca-cert.pem
# Validate server certificatevalidate = true
# Client certificate (for mutual TLS)userkey = /path/to/client-key.pemusercert = /path/to/client-cert.pem
# TLS versionversion = TLSv1_2cqlshrc with Authentication
Section titled “cqlshrc with Authentication”[authentication]username = app_userpassword = app_password
[connection]hostname = cassandra-node-1.example.comport = 9042
[ssl]certfile = /path/to/ca-cert.pemvalidate = trueEnvironment Variables
Section titled “Environment Variables”# Set SSL certificate pathexport SSL_CERTFILE=/path/to/ca-cert.pem
# Use with cqlshcqlsh --ssl hostnameJava Driver Configuration
Section titled “Java Driver Configuration”DataStax Java Driver 4.x
Section titled “DataStax Java Driver 4.x”Programmatic Configuration
Section titled “Programmatic Configuration”import com.datastax.oss.driver.api.core.CqlSession;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManagerFactory;import java.io.FileInputStream;import java.security.KeyStore;
public class CassandraClient {
public static CqlSession createSecureSession() throws Exception { // Load truststore KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load( new FileInputStream("/path/to/truststore.jks"), "truststore_password".toCharArray() );
TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null);
return CqlSession.builder() .addContactPoint(new InetSocketAddress("cassandra-node-1.example.com", 9042)) .withLocalDatacenter("dc1") .withSslContext(sslContext) .withAuthCredentials("username", "password") .build(); }}Mutual TLS Configuration
Section titled “Mutual TLS Configuration”public static CqlSession createMtlsSession() throws Exception { // Load keystore (client certificate) KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load( new FileInputStream("/path/to/client-keystore.p12"), "keystore_password".toCharArray() );
KeyManagerFactory kmf = KeyManagerFactory .getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(keyStore, "keystore_password".toCharArray());
// Load truststore KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load( new FileInputStream("/path/to/truststore.jks"), "truststore_password".toCharArray() );
TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return CqlSession.builder() .addContactPoint(new InetSocketAddress("cassandra-node-1.example.com", 9042)) .withLocalDatacenter("dc1") .withSslContext(sslContext) .build();}File-Based Configuration (application.conf)
Section titled “File-Based Configuration (application.conf)”datastax-java-driver { basic { contact-points = ["cassandra-node-1.example.com:9042"] load-balancing-policy.local-datacenter = dc1 }
advanced.ssl-engine-factory { class = DefaultSslEngineFactory
# Truststore for server certificate validation truststore-path = /path/to/truststore.jks truststore-password = truststore_password
# Keystore for client certificate (mutual TLS) keystore-path = /path/to/client-keystore.p12 keystore-password = keystore_password
# Hostname verification hostname-validation = true
# Cipher suites cipher-suites = [ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" ] }
advanced.auth-provider { class = PlainTextAuthProvider username = app_user password = app_password }}DataStax Java Driver 3.x (Legacy)
Section titled “DataStax Java Driver 3.x (Legacy)”import com.datastax.driver.core.Cluster;import com.datastax.driver.core.SSLOptions;import com.datastax.driver.core.RemoteEndpointAwareJdkSSLOptions;
Cluster cluster = Cluster.builder() .addContactPoint("cassandra-node-1.example.com") .withSSL(RemoteEndpointAwareJdkSSLOptions.builder() .withSSLContext(sslContext) .build()) .withCredentials("username", "password") .build();Python Driver Configuration
Section titled “Python Driver Configuration”Basic SSL Connection
Section titled “Basic SSL Connection”from cassandra.cluster import Clusterfrom cassandra.auth import PlainTextAuthProviderfrom ssl import SSLContext, PROTOCOL_TLS_CLIENT, CERT_REQUIRED
# Create SSL contextssl_context = SSLContext(PROTOCOL_TLS_CLIENT)ssl_context.verify_mode = CERT_REQUIREDssl_context.load_verify_locations('/path/to/ca-cert.pem')
# Create auth providerauth_provider = PlainTextAuthProvider( username='app_user', password='app_password')
# Connect with SSLcluster = Cluster( ['cassandra-node-1.example.com'], port=9042, ssl_context=ssl_context, auth_provider=auth_provider)
session = cluster.connect()Mutual TLS Configuration
Section titled “Mutual TLS Configuration”from cassandra.cluster import Clusterfrom cassandra.auth import PlainTextAuthProviderfrom ssl import SSLContext, PROTOCOL_TLS_CLIENT, CERT_REQUIRED
# Create SSL context with client certificatessl_context = SSLContext(PROTOCOL_TLS_CLIENT)ssl_context.verify_mode = CERT_REQUIREDssl_context.load_verify_locations('/path/to/ca-cert.pem')ssl_context.load_cert_chain( certfile='/path/to/client-cert.pem', keyfile='/path/to/client-key.pem', password='key_password' # If key is encrypted)
cluster = Cluster( ['cassandra-node-1.example.com'], ssl_context=ssl_context, auth_provider=PlainTextAuthProvider('user', 'pass'))Hostname Verification
Section titled “Hostname Verification”from ssl import SSLContext, PROTOCOL_TLS_CLIENT, CERT_REQUIREDimport ssl
ssl_context = SSLContext(PROTOCOL_TLS_CLIENT)ssl_context.verify_mode = CERT_REQUIREDssl_context.check_hostname = True # Enable hostname verificationssl_context.load_verify_locations('/path/to/ca-cert.pem')Node.js Driver Configuration
Section titled “Node.js Driver Configuration”Basic SSL Connection
Section titled “Basic SSL Connection”const cassandra = require('cassandra-driver');const fs = require('fs');
const client = new cassandra.Client({ contactPoints: ['cassandra-node-1.example.com'], localDataCenter: 'dc1', sslOptions: { ca: [fs.readFileSync('/path/to/ca-cert.pem')], rejectUnauthorized: true }, credentials: { username: 'app_user', password: 'app_password' }});
client.connect() .then(() => console.log('Connected')) .catch(err => console.error('Connection error', err));Mutual TLS Configuration
Section titled “Mutual TLS Configuration”const cassandra = require('cassandra-driver');const fs = require('fs');
const client = new cassandra.Client({ contactPoints: ['cassandra-node-1.example.com'], localDataCenter: 'dc1', sslOptions: { ca: [fs.readFileSync('/path/to/ca-cert.pem')], cert: fs.readFileSync('/path/to/client-cert.pem'), key: fs.readFileSync('/path/to/client-key.pem'), rejectUnauthorized: true }});Go Driver Configuration (gocql)
Section titled “Go Driver Configuration (gocql)”Basic SSL Connection
Section titled “Basic SSL Connection”package main
import ( "crypto/tls" "crypto/x509" "io/ioutil" "log"
"github.com/gocql/gocql")
func main() { // Load CA certificate caCert, err := ioutil.ReadFile("/path/to/ca-cert.pem") if err != nil { log.Fatal(err) }
caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert)
// Configure TLS tlsConfig := &tls.Config{ RootCAs: caCertPool, MinVersion: tls.VersionTLS12, }
// Create cluster config cluster := gocql.NewCluster("cassandra-node-1.example.com") cluster.SslOpts = &gocql.SslOptions{ Config: tlsConfig, EnableHostVerification: true, } cluster.Authenticator = gocql.PasswordAuthenticator{ Username: "app_user", Password: "app_password", }
session, err := cluster.CreateSession() if err != nil { log.Fatal(err) } defer session.Close()}Mutual TLS Configuration
Section titled “Mutual TLS Configuration”// Load client certificate and keycert, err := tls.LoadX509KeyPair( "/path/to/client-cert.pem", "/path/to/client-key.pem",)if err != nil { log.Fatal(err)}
tlsConfig := &tls.Config{ RootCAs: caCertPool, Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12,}Connection Testing
Section titled “Connection Testing”Test with OpenSSL
Section titled “Test with OpenSSL”# Test TLS connection to Cassandraopenssl s_client -connect cassandra-node-1.example.com:9042 \ -CAfile /path/to/ca-cert.pem \ -servername cassandra-node-1.example.com
# Show certificate detailsopenssl s_client -connect cassandra-node-1.example.com:9042 \ -CAfile /path/to/ca-cert.pem \ 2>/dev/null | openssl x509 -noout -textTest with cqlsh
Section titled “Test with cqlsh”# Verbose connection testcqlsh --ssl --debug cassandra-node-1.example.comRelated Documentation
Section titled “Related Documentation”- Encryption Overview - Why encryption is essential
- Certificate Types - Generating client certificates
- Cassandra Configuration - Server-side configuration
- Troubleshooting - Common client issues