Enabling JMX authentication and authorization
Steps to enable remote JMX connections.
if [ "$LOCAL_JMX" = "yes" ]; then
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.local.port=$JMX_PORT"
Configuring JMX authentication and authorization can be accomplished using local password and access files to set the usernames, passwords and access permissions.
These two methods work for remote authentication and authorization; the difference is
just the location of the configuration settings in the cassandra-env.sh file. Local
configuration is placed within the if ["$LOCAL_JMX" = "yes']; then
block in the file, whereas remote configuration is placed with the
else
block.
cassandra.yaml
- The cassandra.yaml file is located in the installation_location/conf directory.
Procedure
-
By default, JMX security is disabled and accessible only from localhost
as shown in the following lines from the cassandra-env.sh
file:
if [ "$LOCAL_JMX" = "yes" ]; then JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.local.port=$JMX_PORT"
-
By default, JMX security is disabled and accessible only from localhost
as shown in the following lines from the cassandra-env.sh file:
if [ "$LOCAL_JMX" = "yes" ]; then JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.local.port=$JMX_PORT"
-
Comment out the existing line and add or uncomment the following lines in
either the local or remote block in the cassandra-env.sh
file:
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true" 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" JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.authorizer=org.apache.cassandra.auth.jmx.AuthorizationProxy"
-
And comment out the following lines in the cassandra-env.sh
file:
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password" JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.access.file=/etc/cassandra/jmxremote.access"
-
Change authentication in the cassandra.yaml file to
PasswordAuthenticator
.authenticator: PasswordAuthenticator
-
Change authorization in the cassandra.yaml
file to
CassandraAuthorizer
.authorizer: CassandraAuthorizer
- Restart the database to make the change effective.
-
Check that
nodetool status
requires the username and password in order to execute. The command should fail without authentication if everything is configured correctly.nodetool -u cassandra -pw cassandra status
- Configure Authorization to grant and revoke permissions to database objects, including MBeans.
-
Change
$LOCAL_JMX
tono
. Add the following lines in the remote block in the cassandra-env.sh file:JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true" JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password" JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.access.file=/etc/cassandra/jmxremote.access"
-
Create a password file and add the user and password for JMX-compliant
utilities, specifying the credentials for your environment. The default location
of the password file in the cassandra-env.sh is
/etc/cassandra/jmxremote.password.
cassandra cassandra <new_superuser> <new_superuser_password> <some_other_user> <some_other_user_password> controlRole someOtherHardToRememberPassword
Important: The default superuser account is a security hazard! This account is used only for the purposes of illustration. -
The password file must be secured from unauthorized readers. Change the
ownership of the jmxremote.password file to the user who
starts
cassandra
and change permissions to read only:chown cassandra:cassandra /etc/cassandra/jmxremote.password
chmod 400 /etc/cassandra/jmxremote.password
This example presumes thatcassandra
is run by the default usercassandra
. -
Create an access file and enter the following information. The default location
of the access file in the cassandra-env.sh is
/etc/cassandra/jmxremote.access.
cassandra readwrite <new_superuser> readwrite <some_other_user> readonly controlRole readwrite \ create javax.management.monitor.,javax.management.timer. \ unregister
Important: The default superuser account is a security hazard! This account is used only for the purposes of illustration.Thereadonly
permission allows the JMX client to read an MBean's attributes and receive notifications. Thereadwrite
permission allows the JMX client to set attributes, invoke operations, and create and remove MBeans, in addition to reading an MBean's attributes and receives notifications. -
The access file must be secured from unauthorized readers. Change the ownership
of the jmxremote.access file to the user who starts
cassandra
and change permissions to read only:chown cassandra:cassandra /etc/cassandra/jmxremote.access
chmod 400 /etc/cassandra/jmxremote.access
This example presumes thatcassandra
is run by the default usercassandra
. - Restart the database to make the change effective.
-
Check that
nodetool status
requires the username and password in order to execute. The command should fail without authentication if everything is configured correctly.nodetool status
-
Run nodetool status with the
cassandra
user and password.nodetool -u cassandra -pw cassandra status
-
Generally, JMX settings are inserted into the cassandra-env.sh file. However, these
options can be specified at the command line:
cassandra -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password
-
Ensure the mandatory properties are set for SSL in the cassandra-env.sh file.
For one-way SSL:
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl=true" JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl.need.client.auth=false" JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.keyStore=/path/to/keystore" JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.keyStorePassword=keystore-password"
For two-way SSL:
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl=true" JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl.need.client.auth=true" JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.keyStore=/path/to/keystore" JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.keyStorePassword=keystore-password" JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.trustStore=/path/to/truststore" JVM_OPTS="$JVM_OPTS -Djavax.net.ssl.trustStorePassword=truststore-pass"
For more, see Using nodetool (JMX) with SSL encryption and Using jconsole (JMX) with SSL encryption.
Example
Exception in thread "main" java.lang.SecurityException: Authentication failed! Credentials required at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticationFailure(Unknown Source) at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticate(Unknown Source) at sun.management.jmxremote.ConnectorBootstrap$AccessFileCheckerAuthenticator.authenticate(Unknown Source) at javax.management.remote.rmi.RMIServerImpl.doNewClient(Unknown Source) at javax.management.remote.rmi.RMIServerImpl.newClient(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at sun.rmi.transport.Transport$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Unknown Source) at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) at sun.rmi.server.UnicastRef.invoke(Unknown Source) at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source) at javax.management.remote.rmi.RMIConnector.getConnection(Unknown Source) at javax.management.remote.rmi.RMIConnector.connect(Unknown Source) at javax.management.remote.JMXConnectorFactory.connect(Unknown Source) at org.apache.cassandra.tools.NodeProbe.connect(NodeProbe.java:146) at org.apache.cassandra.tools.NodeProbe.<init>(NodeProbe.java:116) at org.apache.cassandra.tools.NodeCmd.main(NodeCmd.java:1099)