scylla-jmx: Allow ssl, auth etc options for JMX connector
Actually removes a bunch of code to manage the JMX connector, since as of jdk8u102, the standard jmx connector answers to property setting bind address -> can restrict access. Note that the RMI connector will now (as is jdk normal) _bind_ to 0.0.0.0, but it will not answer non-local requests if "remote" is not enabled. This is the default jdk behaviour. In any case, we rely on setting the appropriate properties instead, and also allow pass-through of -D flags to java, which in turn means those who wish can turn on both auth and ssl, set key/trust stores etc etc. Message-Id: <1485357178-20714-1-git-send-email-calle@scylladb.com>
This commit is contained in:
parent
557b346c07
commit
ac8743269c
@ -3,12 +3,16 @@
|
|||||||
# Copyright (C) 2015 Cloudius Systems, Ltd.
|
# Copyright (C) 2015 Cloudius Systems, Ltd.
|
||||||
|
|
||||||
JMX_PORT="7199"
|
JMX_PORT="7199"
|
||||||
API_ADDR=""
|
JMX_ADDR=
|
||||||
API_PORT=""
|
|
||||||
|
API_ADDR=
|
||||||
|
API_PORT=
|
||||||
|
|
||||||
CONF_FILE=""
|
CONF_FILE=""
|
||||||
DEBUG=""
|
DEBUG=""
|
||||||
PARAM_HELP="-h"
|
PARAM_HELP="-h"
|
||||||
PARAM_JMX_PORT="-jp"
|
PARAM_JMX_PORT="-jp"
|
||||||
|
PARAM_JMX_ADDR="-ja"
|
||||||
PARAM_API_PORT="-p"
|
PARAM_API_PORT="-p"
|
||||||
PARAM_ADDR="-a"
|
PARAM_ADDR="-a"
|
||||||
PARAM_LOCATION="-l"
|
PARAM_LOCATION="-l"
|
||||||
@ -20,6 +24,11 @@ ALLOW_DEBUG="-d"
|
|||||||
REMOTE=0
|
REMOTE=0
|
||||||
HOSTNAME=`hostname`
|
HOSTNAME=`hostname`
|
||||||
|
|
||||||
|
|
||||||
|
PROPERTIES=
|
||||||
|
JMX_AUTH=-Dcom.sun.management.jmxremote.authenticate=false
|
||||||
|
JMX_SSL=-Dcom.sun.management.jmxremote.ssl=false
|
||||||
|
|
||||||
print_help() {
|
print_help() {
|
||||||
cat <<HLPEND
|
cat <<HLPEND
|
||||||
|
|
||||||
@ -35,6 +44,7 @@ This script receives the following command line arguments:
|
|||||||
$PARAM_JMX_PORT <port> - The jmx port to open
|
$PARAM_JMX_PORT <port> - The jmx port to open
|
||||||
$PARAM_API_PORT <port> - The API port to connect to
|
$PARAM_API_PORT <port> - The API port to connect to
|
||||||
$PARAM_ADDR <address> - The API address to connect to
|
$PARAM_ADDR <address> - The API address to connect to
|
||||||
|
$PARAM_JMX_ADDR <address> - JMX bind address
|
||||||
$PARAM_FILE <file> - A configuration file to use
|
$PARAM_FILE <file> - A configuration file to use
|
||||||
$PARAM_LOCATION <location> - The location of the jmx proxy jar file
|
$PARAM_LOCATION <location> - The location of the jmx proxy jar file
|
||||||
$ALLOW_REMOTE - When set allow remote jmx connectivity
|
$ALLOW_REMOTE - When set allow remote jmx connectivity
|
||||||
@ -61,6 +71,10 @@ do
|
|||||||
JMX_PORT=$2
|
JMX_PORT=$2
|
||||||
shift 2
|
shift 2
|
||||||
;;
|
;;
|
||||||
|
"$PARAM_JMX_ADDR")
|
||||||
|
JMX_ADDR=-Dcom.sun.management.jmxremote.host=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
"$PARAM_LOCATION")
|
"$PARAM_LOCATION")
|
||||||
LOCATION=$2
|
LOCATION=$2
|
||||||
LOCATION_SCRIPTS="$2"
|
LOCATION_SCRIPTS="$2"
|
||||||
@ -82,6 +96,26 @@ do
|
|||||||
DEBUG="-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:7690,server=y,suspend=n"
|
DEBUG="-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:7690,server=y,suspend=n"
|
||||||
shift 1
|
shift 1
|
||||||
;;
|
;;
|
||||||
|
-Dcom.sun.management.jmxremote.host=*)
|
||||||
|
JMX_ADDR=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-Dcom.sun.management.jmxremote.authenticate=*)
|
||||||
|
JMX_AUTH=$1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-Dcom.sun.management.jmxremote.ssl=*)
|
||||||
|
JMX_SSL=$1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-Dcom.sun.management.jmxremote.local.only=*)
|
||||||
|
JMX_LOCAL=$1
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
|
-D*)
|
||||||
|
PROPERTIES="$PROPERTIES $1"
|
||||||
|
shift 1
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown parameter: $1"
|
echo "Unknown parameter: $1"
|
||||||
print_help
|
print_help
|
||||||
@ -89,11 +123,20 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ $REMOTE -eq 0 ]; then
|
||||||
if [ $REMOTE -eq 1 ]; then
|
if [ -z $JMX_ADDR ]; then
|
||||||
REMOTE="-Djavax.management.builder.initial=com.scylladb.jmx.utils.APIBuilder -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=$JMX_PORT -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=$HOSTNAME"
|
JMX_ADDR=-Dcom.sun.management.jmxremote.host=localhost
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
REMOTE="-Dcassandra.jmx.local.port=$JMX_PORT"
|
if [ -z $JMX_LOCAL ]; then
|
||||||
|
JMX_LOCAL=-Dcom.sun.management.jmxremote.local.only=false
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$LOCATION_SCRIPTS"/symlinks/scylla-jmx $API_ADDR $API_PORT $DEBUG $CONF_FILE $REMOTE -Xmx256m -XX:+UseSerialGC -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -jar $LOCATION/scylla-jmx-1.0.jar
|
exec "$LOCATION_SCRIPTS"/symlinks/scylla-jmx $DEBUG \
|
||||||
|
$API_PORT $API_ADDR $CONF_FILE -Xmx256m -XX:+UseSerialGC \
|
||||||
|
$JMX_AUTH $JMX_SSL $JMX_ADDR $JMX_LOCAL \
|
||||||
|
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=$JMX_PORT \
|
||||||
|
-Djava.rmi.server.hostname=$HOSTNAME -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT \
|
||||||
|
-Djavax.management.builder.initial=com.scylladb.jmx.utils.APIBuilder \
|
||||||
|
$PROPERTIES -jar $LOCATION/scylla-jmx-1.0.jar
|
||||||
|
@ -4,22 +4,11 @@
|
|||||||
package com.scylladb.jmx.main;
|
package com.scylladb.jmx.main;
|
||||||
|
|
||||||
import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
|
import static java.lang.management.ManagementFactory.getPlatformMBeanServer;
|
||||||
import static java.rmi.registry.LocateRegistry.createRegistry;
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static javax.net.ServerSocketFactory.getDefault;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.rmi.server.RMIServerSocketFactory;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.management.MBeanServer;
|
import javax.management.MBeanServer;
|
||||||
import javax.management.remote.JMXConnectorServer;
|
|
||||||
import javax.management.remote.JMXServiceURL;
|
|
||||||
import javax.management.remote.rmi.RMIConnectorServer;
|
|
||||||
|
|
||||||
import org.apache.cassandra.db.commitlog.CommitLog;
|
import org.apache.cassandra.db.commitlog.CommitLog;
|
||||||
import org.apache.cassandra.db.compaction.CompactionManager;
|
import org.apache.cassandra.db.compaction.CompactionManager;
|
||||||
@ -42,88 +31,31 @@ public class Main {
|
|||||||
private static final APIConfig config = new APIConfig();
|
private static final APIConfig config = new APIConfig();
|
||||||
public static final APIClient client = new APIClient(config);
|
public static final APIClient client = new APIClient(config);
|
||||||
|
|
||||||
private static JMXConnectorServer jmxServer = null;
|
|
||||||
|
|
||||||
private static void setupJmx() {
|
|
||||||
System.setProperty("javax.management.builder.initial", "com.scylladb.jmx.utils.APIBuilder");
|
|
||||||
String jmxPort = System.getProperty("com.sun.management.jmxremote.port");
|
|
||||||
|
|
||||||
if (jmxPort == null) {
|
|
||||||
System.out.println("JMX is not enabled to receive remote connections.");
|
|
||||||
|
|
||||||
jmxPort = System.getProperty("cassandra.jmx.local.port", "7199");
|
|
||||||
String address = System.getProperty("jmx.address", "localhost");
|
|
||||||
if (address.equals("localhost")) {
|
|
||||||
System.setProperty("java.rmi.server.hostname", InetAddress.getLoopbackAddress().getHostAddress());
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
System.setProperty("java.rmi.server.hostname", InetAddress.getByName(address).getHostAddress());
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
RMIServerSocketFactory serverFactory = pPort -> getDefault().createServerSocket(pPort, 0,
|
|
||||||
InetAddress.getLoopbackAddress());
|
|
||||||
createRegistry(Integer.valueOf(jmxPort), null, serverFactory);
|
|
||||||
|
|
||||||
StringBuffer url = new StringBuffer();
|
|
||||||
url.append("service:jmx:");
|
|
||||||
url.append("rmi://").append(address).append("/jndi/");
|
|
||||||
url.append("rmi://").append(address).append(":").append(jmxPort).append("/jmxrmi");
|
|
||||||
System.out.println(url);
|
|
||||||
Map<String, Object> env = new HashMap<>();
|
|
||||||
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory);
|
|
||||||
|
|
||||||
jmxServer = new RMIConnectorServer(new JMXServiceURL(url.toString()), env, getPlatformMBeanServer());
|
|
||||||
|
|
||||||
jmxServer.start();
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Error starting local jmx server: " + e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
System.out.println("JMX is enabled to receive remote connections on port: " + jmxPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
System.out.println("Connecting to " + config.getBaseUrl());
|
System.out.println("Connecting to " + config.getBaseUrl());
|
||||||
System.out.println("Starting the JMX server");
|
System.out.println("Starting the JMX server");
|
||||||
|
|
||||||
setupJmx();
|
MBeanServer server = getPlatformMBeanServer();
|
||||||
|
for (Class<? extends APIMBean> clazz : asList(StorageService.class, StorageProxy.class, MessagingService.class,
|
||||||
|
CommitLog.class, Gossiper.class, EndpointSnitchInfo.class, FailureDetector.class, CacheService.class,
|
||||||
|
CompactionManager.class, GCInspector.class, StreamManager.class)) {
|
||||||
|
Constructor<? extends APIMBean> c = clazz.getDeclaredConstructor(APIClient.class);
|
||||||
|
APIMBean m = c.newInstance(client);
|
||||||
|
server.registerMBean(m, null);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MBeanServer server = getPlatformMBeanServer();
|
// forces check for dynamically created mbeans
|
||||||
for (Class<? extends APIMBean> clazz : asList(StorageService.class, StorageProxy.class,
|
server.queryNames(null, null);
|
||||||
MessagingService.class, CommitLog.class, Gossiper.class, EndpointSnitchInfo.class,
|
} catch (IllegalStateException e) {
|
||||||
FailureDetector.class, CacheService.class, CompactionManager.class, GCInspector.class,
|
// ignore this. Just means we started before scylla.
|
||||||
StreamManager.class)) {
|
}
|
||||||
Constructor<? extends APIMBean> c = clazz.getDeclaredConstructor(APIClient.class);
|
|
||||||
APIMBean m = c.newInstance(client);
|
|
||||||
server.registerMBean(m, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
String jmxPort = System.getProperty("com.sun.management.jmxremote.port");
|
||||||
// forces check for dynamically created mbeans
|
System.out.println("JMX is enabled to receive remote connections on port: " + jmxPort);
|
||||||
server.queryNames(null, null);
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
// ignore this. Just means we started before scylla.
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Thread.sleep(Long.MAX_VALUE);
|
Thread.sleep(Long.MAX_VALUE);
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
// make sure to kill the server otherwise we can hang. Not an issue
|
|
||||||
// when killed perhaps, but any exception above etc would leave a
|
|
||||||
// zombie.
|
|
||||||
if (jmxServer != null) {
|
|
||||||
jmxServer.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user