Enabling PasswordAuthenticator and SSL

λ.eranga

Dec 14, 2018 · 5 min read

Cassandra allows you to have various security features in node-to-node communication as well and client-to-node communication.

In this article I’m going to cover:

  1. Client-to-Node username/password authentication;
  2. Client-to-Node SSL encryption;
  3. Node-to-Node SSL encryption.

Cassandra can secure the communication between clients to nodes with username/password authentication. It introduce as PasswordAuthenticator. According to the documentation, Cassandra authentication is roles-based and stored internally in Cassandra system tables. Administrators can create, alter, drop, or list roles using CQL commands, with an associated password. Roles can be created with superuser, non-superuser, and login privileges. The internal authentication is used to access Cassandra keyspaces and tables. Following are the steps to enable PasswordAuthenticator.

1.1 Enable PasswordAuthenticator in Cassandra config

Set the authenticator attribute in Cassandra config file,cassandra.yaml to PasswordAuthenticator. By default it comes with AllowAllAuthenticator which allows to login without username/password. The cassandra.yaml file locates in Cassandra config directory(in Linux it locates at /etc/cassandra/cassandar.yaml).

1.2 Connect to Cassandra with default user

By default Cassandra comes with user cassandra, password of this user is cassanddra. I can connect to Cassandra via cqlsh with default Cassandra user’s credentials.

1.3 Create user

After connecting to Cassandra with default username/password we can create a new user/role for us. Then we can login to cluster with a newly created user. If you want, after creating the new user you can remove the default Cassandra user for security purposes. Cassandra user/role information stored in system_auth keyspace. We need to connect to system_auth keyspace and create the new user.

1.4 Connect Cassandra with new user

After setting up the user and roles we can use that user to connect to the cluster with cqlsh.

According to the documentation, client-to-node encryption protects data in flight from client machines to a database cluster using SSL. It establishes a secure channel between the client and the coordinator node. To this, we need to generate certificates for clients and nodes and setup them. Following are the steps to do that.

2.1 Generate certificate authority

Normally server SSL certificates signed by trusted third parties known as the certificate authority. In this scenario, we can generate our own CA and issue certificates for our servers and clients (since Cassandra setup don’t deal with external users). CA simplifying the maintain trust among the nodes and client. Since using CA certificate, Node or client certificates do not need to be added to the trust store(since they will be signed by the CA public key). CA public key will be added to the trust store.

To generate the CA (key pair for certificate authority) we can use openssl. First, we need to define the key pair configs in a file named ca-rahasak.conf. This file list the password of certificate, country, state, email addresses etc.

By using this config we can generate root CA. Below command will generate root CA private key ca.key.pem and root CA public key certificate ca.cer.pem

Finally, we can create a truststore with CA public key by using java keytool command. This truststore can be installed on each Cassandra node. The main purpose of the truststore is to verify incoming connections from the rest of the cluster and clients.

2.2 Generate certificate for the server

Now we need a certificate for Cassandra node. This certificate needs to be signed by the previously created CA. First, generate a public certificate and private key in a keystore by using java keytool command. Below command will generate a keystore named node1.keystore.jks.

To sign the certificate by root CA we need to export the certificate from node1.keystore.jks keystore and generate a Certificate Signing Request(CSR). Below command will generates node1.csr.

Next step is to sign the CSR with the CA public key. We are using openssl command for it. This command will generate a signed certificate node1.cer.signed.

Then the CA public key needs to add into node key store node1.keystore.jks. This step required to trust the certificate chain.

Finally, we can add the signed node certificate node1.cer.signed to the node1.keystore.jks keystore.

2.3 Generate certificate for client

Please repeat steps in section 2.2 to generate certificates for client. In here I’m using the name client1 to generate the certificates.

2.4 Install certificates on server

In here I’m copying the generated keystore and truststore files into node1. I’m putting them in a location /home/cassandra/certs.

2.5 Configure cassandra.yaml

To enable client SSL encryption we need to set client_encryption_option . It includes the locations of node1's keystore/truststore and their passwords details. In here I’m disabling required_client_auth, so I don’t need to set client certificates and keys when connecting to the Cassandra via cqlsh or via a program(ex java/scala).

2.6 Configure cqlsh

I’m going to connect to Cassandra service on node1(ip - 10.4.1.5) from client1(ip - 10.4.1.13) via cqlsh.

To connect to SSL enable Cassandra cluster via cqlsh, I need to configure the cqlsh config file which locates on ~/.cassandra/cqlshrc client machine. I’m using root certificate to enable the SSL connection between client1 and node1. (I can do that since node1 trust the CA certificates and the certificates signed by the root CA). In here I’m not using a separate certificate for the client. Instead directly using root CA. Following are the cqlshrc file configurations.

2.7 Connect with cqlsh

After setting up SSL options on cqlshrc, I can connect to Cassandra service which running on node1 server with cqlsh. To enable SSL with cqlsh it use the flag --ssl.

2.7 Connect with scala/java program

When I’m connecting to SSL enable Cassandra cluster with scala/java program, I need to create cassandra session with SSL. Following is the way to do that. As same as with cqlsh I’m using root CA certificate to enable the SSL connection between Cassandra scala client and Cassandra node1 server. I’m putting the root CA file in the resources folder in scala sbt project. Following is a simpler version of a trait that I have used to build ssl and auth enable Cassandra session.

According to the documentation, node-to-node encryption protects data transferred between nodes in a cluster, including gossip communications, using SSL (Secure Sockets Layer).

3.1 Generate certificates for nodes

Repeat the steps in section 2.2 and generate certificates for each and every node in the Cassandra cluster. Assume I have 3 node cluster(node1, node2, node3) and generated certificates for them.

3.2 Install certificates on the server

Follow the steps on 2.4 and copy the keystores and truststore to each and every node.

3.3 Configure cassandra.yaml

Set server_encryption_options in cassandra.yaml with respective node’s keystore/truststore information like below.

Finally, restart Cassandra service on each node, it will enable SSL communication between Cassandra nodes and protects data transferred between nodes in the cluster.

  1. https://community.kineticdata.com/Kinetic_Request/Kinetic_Request_Core_Edition/Releases/Kinetic_Request_CE_-_Version_1.0.4/Preparing_SSL_Certificates
  2. https://docs.datastax.com/en/cassandra/3.0/cassandra/configuration/secureSSLEncryptTOC.html
  3. http://thelastpickle.com/blog/2015/09/30/hardening-cassandra-step-by-step-part-1-server-to-server.html#byo-certificate-authority
  4. https://github.com/radicalbit/cassandra-ssl-client-to-node-example
  5. https://dzone.com/articles/setting-up-a-cassandra-cluster-with-ssl