Summary
It's possible to secure JMX authentication which makes JMX compliant utilities such as nodetool, OpsCenter and JConsole ask for password authentication.
Enabling JMX authentication can be a simple way to ensure only certain people can use utilities like nodetool, OpsCenter and JConsole. For example, some system administrators prefer to secure nodetool usage as it can be used to add and remove nodes.
JMX authentication
1) Edit /etc/dse/cassandra/cassandra-env.sh update/add these lines:
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true"
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password"
2) Copy the jmxremote.password.template from /<jre_install_dir>/lib/management/ to /etc/cassandra/ and rename to jmxremote.password:
cp /<jre_install_dir>/lib/management/jmxremote.password.template /etc/cassandra/jmxremote.password
3) Change ownership to cassandra and permission
chown cassandra:cassandra /etc/cassandra/jmxremote.password
chmod 400 /etc/cassandra/jmxremote.password
4) Edit jmxremote.password and add the user and password:
monitorRole QED
controlRole R&D
cassandra cassandra
5) Add cassandra with readwrite permission to /<jre_install_dir>/lib/management/jmxremote.access:
monitorRole readonly
cassandra readwrite
controlRole readwrite \
create javax.management.monitor.*,javax.management.timer.* \
unregister
6) Restart DSE
/etc/init.d/dse restart
7) Run nodetool with user and password:
nodetool -u cassandra -pw cassandra status
Without user and password you will see this error:
root@VM1 cassandra]# nodetool status
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)
OpsCenter Changes
If you are using OpsCenter you need to add the JMX credentials for nodes to connect:
1) In OpsCenter select Edit Cluster, enter user name and password under JMX Username and JMX Password.
2) Restart OpsCenter agent on each node
/etc/init.d/opscenterd restart
3) You can check if the JMX credentials were added to OpsCenter by viewing this file:
/etc/opscenter/clusters/<cluster_name>.conf
It should contain an entry like this:
[jmx]
username = cassandra
password = cassandra
port = 7199
JConsole
If using JConsole you will need to provide username and password when connecting to the host.