Client TLS protects CQL sessions between application clients and Apache Cassandra nodes from plaintext exposure on the native transport port. Without it, credentials, schema queries, and row data can cross a reachable network segment without encryption even when database authentication is enabled.
Cassandra manages client-to-node encryption under client_encryption_options in /etc/cassandra/cassandra.yaml for package installs. With enabled set to true and optional set to true, encrypted and unencrypted clients can share native_transport_port during a rollout. With optional set to false, clients must negotiate TLS before CQL can proceed.
Use a rolling change and prepare trusted CA material for every client before making TLS mandatory. Examples use package paths, a PKCS12 server keystore, and a cqlsh TLS profile; tarball installs use conf/cassandra.yaml under the Cassandra home, and mutual client certificate authentication also needs a Cassandra truststore plus userkey and usercert entries in the client profile.
Steps to enable Apache Cassandra client TLS:
- Confirm the node is reachable before changing client encryption.
$ cqlsh 10.0.0.10 9042 -e "SHOW HOST" Connected to SG Cluster at 10.0.0.10:9042
Replace 10.0.0.10 with the Cassandra node address that clients use for native transport.
- Create a protected TLS material directory on the selected Cassandra node.
$ sudo install -o cassandra -g cassandra -m 0750 -d /etc/cassandra/tls
- Install the server keystore on the selected node.
$ sudo install -o cassandra -g cassandra -m 0600 server-keystore.p12 /etc/cassandra/tls/server-keystore.p12
Use a certificate whose names match the addresses or hostnames used by clients. Keep the private key and keystore password out of shared transcripts and shell history.
- Back up the active Cassandra configuration file.
$ sudo cp /etc/cassandra/cassandra.yaml /etc/cassandra/cassandra.yaml.pre-client-tls
- Open the active Cassandra configuration file.
$ sudoedit /etc/cassandra/cassandra.yaml
- Set client TLS to transitional mode.
- /etc/cassandra/cassandra.yaml
client_encryption_options: enabled: true optional: true keystore: /etc/cassandra/tls/server-keystore.p12 keystore_password: REPLACE_WITH_KEYSTORE_PASSWORD store_type: PKCS12 require_client_auth: false
optional: true lets encrypted and unencrypted clients connect on the same native transport port while client profiles and application drivers are updated.
Set require_client_auth to true only when Cassandra has a truststore for client certificate issuers and each client presents a matching certificate. - Restart the selected Cassandra node to load the transitional setting.
$ sudo systemctl restart cassandra
Cassandra validates this configuration during startup. If the service fails to start, restore the backup file or fix the keystore path, password, store type, or certificate before moving to another node.
- Check that the node returned to normal ring state.
$ nodetool status Datacenter: datacenter1 ======================= Status=Up/Down |/ State=Normal/Leaving/Joining/Moving -- Address Load Tokens Owns (effective) Host ID Rack UN 10.0.0.10 144.32 KiB 16 100.0% d0b8b726-c680-4b42-bb57-3fa50db70e6a rack1
UN means the node is up and normal from this node's ring view.
Related: How to check Apache Cassandra cluster status with nodetool
Related: How to check Apache Cassandra service status - Create the cqlsh configuration directory on the administration host.
$ mkdir -p ~/.cassandra
- Install the Cassandra CA certificate for cqlsh.
$ install -m 0644 cluster-ca.pem ~/.cassandra/cassandra-ca.pem
Use the CA certificate or certificate bundle that signs the Cassandra server certificate. Do not copy the server private key to client hosts.
- Create a cqlsh TLS profile.
- ~/.cassandra/cqlshrc
[connection] hostname = 10.0.0.10 port = 9042 ssl = true [ssl] certfile = ~/.cassandra/cassandra-ca.pem validate = true
When require_client_auth is true, add userkey and usercert under [ssl] and point them at the client's PEM key and certificate.
- Test an encrypted cqlsh connection.
$ cqlsh --cqlshrc ~/.cassandra/cqlshrc -e "SHOW HOST" Connected to SG Cluster at 10.0.0.10:9042
- Repeat the transitional rollout on each remaining Cassandra node.
Restart one node at a time, wait for UN in nodetool status, and confirm encrypted cqlsh access before changing the next node.
- Update application clients to trust the same Cassandra CA and enable TLS in their driver configuration.
Driver option names differ, but the client must trust the server certificate chain and connect to the same native transport host and port used in the server certificate names.
- Set mandatory client TLS after every client uses encryption.
- /etc/cassandra/cassandra.yaml
client_encryption_options: enabled: true optional: false keystore: /etc/cassandra/tls/server-keystore.p12 keystore_password: REPLACE_WITH_KEYSTORE_PASSWORD store_type: PKCS12 require_client_auth: false
native_transport_port_ssl is deprecated in Cassandra 5.0, so prefer mandatory TLS on native_transport_port unless an existing compatibility plan requires a separate secure port.
- Restart each Cassandra node one at a time to enforce mandatory TLS.
$ sudo systemctl restart cassandra
Wait for each node to return to UN before restarting the next node.
Related: How to check Apache Cassandra service status - Verify that an empty cqlsh profile no longer connects without TLS.
$ cqlsh --cqlshrc /dev/null 10.0.0.10 9042 -e "SHOW HOST" Connection error: ('Unable to connect to any servers', {'10.0.0.10:9042': ConnectionShutdown('Connection to 10.0.0.10:9042 was closed')})The rejection confirms the native transport listener no longer accepts plaintext CQL sessions.
- Verify that the TLS profile can read Cassandra system data.
$ cqlsh --cqlshrc ~/.cassandra/cqlshrc -e "SELECT cluster_name, native_protocol_version FROM system.local;" cluster_name | native_protocol_version --------------+------------------------- SG Cluster | 5 (1 rows)
A successful read from system.local proves the client can negotiate TLS and execute CQL through the secured native transport port.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.