• Apache Cassandra
  • Technical
Securing your Apache Cassandra cluster

The new year has begun, and with it has come a wave of database compromises. Cyber-criminals targeting “low hanging fruit” are using public search engines such as Shodan to discover and exploit unsecured MongoDB, Elasticsearch, Hadoop and Cassandra clusters.

The attack is simple but effective: the attacker logs into an unsecured database, exports the data (or simply deletes it), and leaves a ransom note behind demanding payment in Bitcoin in return for the stolen data.

While the majority of the attacks did targeted other databases, there were a number of Cassandra clusters that were hit. For further information on the attacks themselves, there are some excellent writeups by BleepingComputer and Sophos.

How do I prevent my cluster from attack?

  1. Enable authentication. As authentication is not enabled by default, this is the single most important thing you can do to secure a Cassandra cluster. Simply set the authenticator option to PasswordAuthenticator and authorizer option to CassandraAuthorizer in the cassandra.yaml file to enable password based authentication. If you have a multi-datacenter configuration you must also change the replication class of the system_auth keyspace to NetworkTopologyStrategy. You should also change the default password (see step 2). If your cluster has datacenters spanning multiple regions, you should also enable SSL. If not then your password will be transmitted in plaintext during authentication and could potentially be intercepted.
  2. The second most important thing you must do is to stop using the default superuser account (the “cassandra” account). Create a new superuser account with a different name and a strong password (and ideally a non-superuser account as well), then set the password for the default superuser to a very long, random string and forget it or lock it away somewhere secure.
  3. Ensure your JMX ports are not publicly accessible. While it is possible to secure your JMX port, there is rarely a case where it needs to be accessible via a public address. Check your firewall rules and make sure that this port (7199) is not accessible outside of your private network. While you’re at it, check your other firewall rules. In most cases, the only port that you should need to make publically accessible is your internode port – 7001 (use SSL!), and even then only if you have multiple datacentres in multiple regions.
  4. Don’t use public networks. In the vast majority of cases, if you do not have a multi-datacenter setup as described in point 3, then you do not need to make any Cassandra ports publicly accessible. You will need to modify the listen_address and broadcast_rpc_address configuration options in your cassandra.yaml file to allow your cluster to communicate using only private networks. Cloud provider features such as AWS’s VPC peering and Azure’s Virtual Networks provide flexible methods to connect your application to your cluster privately.
  5. Enable SSL. If you have a cluster spanning multiple regions or need to connect using public networks, then Cassandra’s SSL feature should be used to protect both your inter-node traffic and client connections. While it can be a little tricky to set up, there are some great step-by-step guides out there to help with this process. It is important to note that enabling SSL alone will not protect your cluster. It must be used in combination with password authentication & authorization. You can optionally enable require_client_auth (which authenticates the client’s SSL certificate when the SSL connection is established) for even more protection.

At Instaclustr, we support all of these configurations for our managed clusters.

That’s great, but what if my Cluster has been hit?

By chance, Cassandra itself actually has some level of built-in protection against this style of attack, as by default it will take a snapshot when a table is dropped. Unless the attacker also has access to Cassandra’s JMX interface or direct access to the OS, they cannot remove the snapshot. Restoring snapshots is a simple task: simply copy the snapshot files to the table’s data directory and use nodetool’s reload command to load the SSTables.