- Security
- TLS/SSL Encryption
- Using PEM based key material
- SSL Certificate Hot Reloading
- Inter-node Encryption
- Client to Node Encryption
- Roles
- Authentication
- Enabling Password Authentication
- Authorization
- Enabling Internal Authorization
- Caching
- JMX access
- Standard JMX Auth
- Cassandra Integrated Auth
- JMX With SSL
Security
There are three main components to the security features provided by Cassandra: - TLS/SSL encryption for client and inter-node communication
- Client authentication
- Authorization By default, these features are disabled as Cassandra is configured to easily find and be found by other members of a cluster. In other words, an out-of-the-box Cassandra installation presents a large attack surface for a bad actor. Enabling authentication for clients using the binary protocol is not sufficient to protect a cluster. Malicious users able to access internode communication and JMX ports can still:
- Craft internode messages to insert users into authentication schema
- Craft internode messages to truncate or drop schema
sstableloaderto overwritesystem_authtables- Attach to the cluster directly to capture write traffic
Correct configuration of all three security components should negate theses vectors. Therefore, understanding Cassandra’s security features is crucial to configuring your cluster to meet your security needs.
TLS/SSL Encryption
Cassandra provides secure communication between a client machine and a database cluster and between nodes within a cluster. Enabling encryption ensures that data in flight is not compromised and is transferred securely. The options for client-to-node and node-to-node encryption are managed separately and may be configured independently.cassandra.yaml, but this is not recommended unless there are policies in place which dictate certain settings or a need to disable vulnerable ciphers or protocols in cases where the JVM cannot be updated. the java document on FIPS for more details. Cassandra provides flexibility of using Java based key material or completely customizing the SSL context. You can choose any keystore format supported by Java (JKS, PKCS12 etc) as well as other standards like PEM. You can even customize the SSL context creation to use Cloud Native technologies like Kuberenetes Secrets for storing the key material or to integrate with your in-house Key Management System. java documentation on creating keystores. ISslContextCreationFactory interface or extend one of its public subclasses appropriately. You can then use thessl_context_factorysetting forserver_encryption_optionsorclient_encryption_optionssections appropriately. See ssl-factory examples for details. Refer to the below class diagram to understand the class hierarchy.
Using PEM based key material
PEMBasedSSLContextFactoryas thessl_context_factorysetting for the PEM based key material. You can configure this factory with either inline PEM data or with the files having the required PEM data as shown below, -
-client/server_encryption_options: ssl_context_factory: class_name: org.apache.cassandra.security.PEMBasedSslContextFactory parameters: private_key: | -----BEGIN ENCRYPTED PRIVATE KEY----- OR -----BEGIN PRIVATE KEY----- <your base64 encoded private key> -----END ENCRYPTED PRIVATE KEY----- OR -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- <your base64 encoded certificate chain> -----END CERTIFICATE----- private_key_password: "<your password if the private key is encrypted with a password>" trusted_certificates: | -----BEGIN CERTIFICATE----- <your base64 encoded certificate> -----END CERTIFICATE-----
client/server_encryption_options: ssl_context_factory: class_name: org.apache.cassandra.security.PEMBasedSslContextFactory keystore: <file path to the keystore file in the PEM format with the private key and the certificate chain> keystore_password: "<your password if the private key is encrypted with a password>" truststore: <file path to the truststore file in the PEM format>
SSL Certificate Hot Reloading
Beginning with Cassandra 4, Cassandra supports hot reloading of SSL Certificates. If SSL/TLS support is enabled in Cassandra and you are using default file based key material, the node periodically (every 10 minutes) polls the Trust and Key Stores specified in cassandra.yaml. When the files are updated, Cassandra will reload them and use them for subsequent connections. Please note that the Trust & Key Store passwords are part of the yaml so the updated files should also use the same passwords.ssl_context_factorysetting, Cassandra polls (at the same periodic interval mentioned above) your implementation to check if the SSL certificates need to be reloaded. See the ISslContextFactory documentation for more details. If you are using one of the Cassandra’s in-built SSL context factory class (example: PEMBasedSslContextFactory) with file based key material, it supports the hot reloading of the SSL certificates like mentioned above.nodetool reloadsslcommand. Use this if you want to Cassandra to immediately notice the changed certificates.Inter-node Encryption
cassandra.yamlin theserver_encryption_optionssection. To enable inter-node encryption, change theinternode_encryptionsetting from its default value ofnoneto one value from:rack,dcorall.Client to Node Encryption
cassandra.yamlin theclient_encryption_optionssection. There are two primary toggles here for enabling encryption,enabledandoptional. true, client connections are entirely unencrypted.enabledis set totrueandoptionalis set tofalse, all client connections must be secured.true, both encrypted and unencrypted connections are supported using the same port. Client connections using encryption with this configuration will be automatically detected and handled by the server.optionalsetting, separate ports can also be configured for secure and unsecure connections where operational requirements demand it. To do so, setoptionalto false and use thenative_transport_port_sslsetting incassandra.yamlto specify the port to be used for secure client communication.Roles
role_managersetting incassandra.yaml. The default setting usesCassandraRoleManager, an implementation which stores role information in the tables of thesystem_authkeyspace. CQL documentation on roles.Authentication
authenticatorsetting incassandra.yaml. Cassandra ships with two options included in the default distribution.AllowAllAuthenticatorwhich performs no authentication checks and therefore requires no credentials. It is used to disable authentication completely. Note that authentication is a necessary condition of Cassandra’s permissions subsystem, so if authentication is disabled, effectively so are permissions.PasswordAuthenticator, which stores encrypted credentials in a system table. This can be used to enable simple username/password authentication.Enabling Password Authentication
Before enabling client authentication on the cluster, client applications should be pre-configured with their intended credentials. When a connection is initiated, the server will only ask for credentials once authentication is enabled, so setting up the client side config in advance is safe. In contrast, as soon as a server has authentication enabled, any connection attempt without proper credentials will be rejected which may cause availability problems for client applications. Once clients are setup and ready for authentication to be enabled, follow this procedure to enable it on the cluster. Pick a single node in the cluster on which to perform the initial configuration. Ideally, no clients should connect to this node during the setup process, so you may want to remove it from client config, block it at the network level or possibly add a new temporary node to the cluster for this purpose. On that node, perform the following steps:
cqlshsession and change the replication factor of thesystem_authkeyspace. By default, this keyspace usesSimpleReplicationStrategyand areplication_factorof 1. It is recommended to change this for any non-trivial deployment to ensure that should nodes become unavailable, login is still possible. Best practice is to configure a replication factor of 3 to 5 per-DC.ALTER KEYSPACE system_auth WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1': 3, 'DC2': 3};
cassandra.yamlto change theauthenticatoroption like so:authenticator: PasswordAuthenticator
- Restart the node.
cqlshsession using the credentials of the default superuser:$ cqlsh -u cassandra -p cassandra
QUORUM, whereas those for all other users (including superusers) are read atLOCAL_ONE. In the interests of performance and availability, as well as security, operators should create another superuser and disable the default one. This step is optional, but highly recommended. While logged in as the default superuser, create another superuser role which can be used to bootstrap further configuration.
1.# create a new superuserCREATE ROLE dba WITH SUPERUSER = true AND LOGIN = true AND PASSWORD = 'super';
ALTER ROLE cassandra WITH SUPERUSER = false AND LOGIN = false;
- CREATE ROLE statements.
At the end of these steps, the one node is configured to use password authentication. To roll that out across the cluster, repeat steps 2 and 3 on each node in the cluster. Once all nodes have been restarted, authentication will be fully enabled throughout the cluster.
PasswordAuthenticatoralso requires the use of CassandraRoleManager.setting-credentials-for-internal-authentication, CREATE ROLE, ALTER ROLE, ALTER KEYSPACE and GRANT PERMISSION.Authorization
authorizersetting incassandra.yaml. Cassandra ships with two options included in the default distribution.AllowAllAuthorizerwhich performs no checking and so effectively grants all permissions to all roles. This must be used ifAllowAllAuthenticatoris the configured authenticator.CassandraAuthorizer, which does implement full permissions management functionality and stores its data in Cassandra system tables.Enabling Internal Authorization
Permissions are modelled as a whitelist, with the default assumption that a given role has no access to any database resources. The implication of this is that once authorization is enabled on a node, all requests will be rejected until the required permissions have been granted. For this reason, it is strongly recommended to perform the initial setup on a node which is not processing client requests.password-authentication. Perform these steps to enable internal authorization across the cluster: cassandra.yamlto change theauthorizeroption like so:authorizer: CassandraAuthorizer
- Restart the node.
cqlshsession using the credentials of a role with superuser credentials:$ cqlsh -u dba -p super
- GRANT PERMISSION statements. On the other nodes, until configuration is updated and the node restarted, this will have no effect so disruption to clients is avoided.
1. GRANT PERMISSION, GRANT ALL and REVOKE PERMISSION.GRANT SELECT ON ks.t1 TO db_user;
Caching
system_authtables. Furthermore, these reads are in the critical paths of many client operations, and so has the potential to severely impact quality of service. To mitigate this, auth data such as credentials, permissions and role details are cached for a configurable period. The caching can be configured (and even disabled) fromcassandra.yamlor using a JMX client. The JMX interface also supports invalidation of the various caches, but any changes made via JMX are not persistent and will be re-read fromcassandra.yamlwhen the node is restarted. Each cache has 3 options which can be set: Validity Period Controls the expiration of cache entries. After this period, entries are invalidated and removed from the cache. Refresh Rate Controls the rate at which background reads are performed to pick up any changes to the underlying data. While these async refreshes are performed, caches will continue to serve (possibly) stale data. Typically, this will be set to a shorter time than the validity period. Max Entries Controls the upper bound on cache size.cassandra.yamlfollows the convention:
<type>_validity_in_ms<type>_update_interval_in_ms<type>_cache_max_entries<type>is one ofcredentials,permissions, orroles.org.apache.cassandra.authdomain.JMX access
Access control for JMX clients is configured separately to that for CQL. For both authentication and authorization, two providers are available; the first based on standard JMX security and the second which integrates more closely with Cassandra’s own auth subsystem.cassandra-env.shto change theLOCAL_JMXsetting tono. Under the standard configuration, when remote JMX connections are enabled,standard JMX authentication <standard-jmx-auth>is also switched on. Note that by default, local-only connections are not subject to authentication, but this can be enabled. SSL connections. nodetool are correctly configured and working as expected.Standard JMX Auth
cassandra-env.shby the line:
Edit the password file to add username/password pairs:JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password"
Secure the credentials file so that only the user running the Cassandra process can read it :jmx_user jmx_password
$ chown cassandra:cassandra /etc/cassandra/jmxremote.password$ chmod 400 /etc/cassandra/jmxremote.password
cassandra-env.sh:
Then edit the access file to grant your JMX user readwrite permission:#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.access.file=/etc/cassandra/jmxremote.access"
Cassandra must be restarted to pick up the new settings. Using File-Based Password Authentication In JMXjmx_user readwrite
Cassandra Integrated Auth
An alternative to the out-of-the-box JMX auth is to useeCassandra’s own authentication and/or authorization providers for JMX clients. This is potentially more flexible and secure but it come with one major caveat. Namely that it is not available until after a node has joined the ring, because the auth subsystem is not fully configured until that point However, it is often critical for monitoring purposes to have JMX access particularly during bootstrap. So it is recommended, where possible, to use local only JMX auth during bootstrap and then, if remote connectivity is required, to switch to integrated auth once the node has joined the ring and initial setup is complete.cqlsh. Furthermore, fine grained control over exactly which operations are permitted on particular MBeans can be acheived via GRANT PERMISSION.cassandra-env.shto uncomment these lines:
And disable the JMX standard auth by commenting this line:#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.login.config=CassandraLogin"#JVM_OPTS="$JVM_OPTS -Djava.security.auth.login.config=$CASSANDRA_HOME/conf/cassandra-jaas.config"
To enable integrated authorization, uncomment this line:JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password"
Check standard access control is off by ensuring this line is commented out:#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.authorizer=org.apache.cassandra.auth.jmx.AuthorizationProxy"
With integrated authentication and authorization enabled, operators can define specific roles and grant them access to the particular JMX resources that they need. For example, a role with the necessary permissions to use tools such as jconsole or jmc in read-only mode would be defined as:#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.access.file=/etc/cassandra/jmxremote.access"
Fine grained access control to individual MBeans is also supported:CREATE ROLE jmx WITH LOGIN = false;GRANT SELECT ON ALL MBEANS TO jmx;GRANT DESCRIBE ON ALL MBEANS TO jmx;GRANT EXECUTE ON MBEAN 'java.lang:type=Threading' TO jmx;GRANT EXECUTE ON MBEAN 'com.sun.management:type=HotSpotDiagnostic' TO jmx;# Grant the role with necessary permissions to use nodetool commands (including nodetool status) in read-only modeGRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=EndpointSnitchInfo' TO jmx;GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=StorageService' TO jmx;# Grant the jmx role to one with login permissions so that it can access the JMX toolingCREATE ROLE ks_user WITH PASSWORD = 'password' AND LOGIN = true AND SUPERUSER = false;GRANT jmx TO ks_user;
GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=Tables,keyspace=test_keyspace,table=t1' TO ks_user;GRANT EXECUTE ON MBEAN 'org.apache.cassandra.db:type=Tables,keyspace=test_keyspace,table=*' TO ks_owner;
ks_userrole to invoke methods on the MBean representing a single table intest_keyspace, while granting the same permission for all table level MBeans in that keyspace to theks_ownerrole. Adding/removing roles and granting/revoking of permissions is handled dynamically once the initial setup is complete, so no further restarts are required if permissions are altered. Permissions.JMX With SSL
cassandra-env.shto uncomment and set the values of these properties as required:com.sun.management.jmxremote.sslset to true to enable SSLcom.sun.management.jmxremote.ssl.need.client.authset to true to enable validation of client certificatescom.sun.management.jmxremote.registry.sslenables SSL sockets for the RMI registry from which clients obtain the JMX connector stubcom.sun.management.jmxremote.ssl.enabled.protocolsby default, the protocols supported by the JVM will be used, override with a comma-separated list. Note that this is not usually necessary and using the defaults is the preferred option.com.sun.management.jmxremote.ssl.enabled.cipher.suitesby default, the cipher suites supported by the JVM will be used, override with a comma-separated list. Note that this is not usually necessary and using the defaults is the preferred option.javax.net.ssl.keyStoreset the path on the local filesystem of the keystore containing server private keys and public certificatesjavax.net.ssl.keyStorePasswordset the password of the keystore filejavax.net.ssl.trustStoreif validation of client certificates is required, use this property to specify the path of the truststore containing the public certificates of trusted clientsjavax.net.ssl.trustStorePasswordset the password of the truststore file Oracle Java7 Docs, Monitor Java with JMX
