Enable JMX server configuration to be in cassandra.yaml

patch by Zhongxiang Zheng; reviewed by Stefan Miklosovic, Maulin Vasavada, Cheng Wang, Jordan West for CASSANDRA-11695

Co-authored-by: Stefan Miklosovic <smiklosovic@apache.org>
Co-authored-by: Sam Tunnicliffe <samt@apache.org>
This commit is contained in:
Zhongxiang Zheng 2016-06-30 18:17:49 +09:00 committed by Stefan Miklosovic
parent 54e4688069
commit 2ff41551a6
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
38 changed files with 1041 additions and 573 deletions

View File

@ -1,4 +1,5 @@
5.1 5.1
* Enable JMX server configuration to be in cassandra.yaml (CASSANDRA-11695)
* Parallelized UCS compactions (CASSANDRA-18802) * Parallelized UCS compactions (CASSANDRA-18802)
* Avoid prepared statement invalidation race when committing schema changes (CASSANDRA-20116) * Avoid prepared statement invalidation race when committing schema changes (CASSANDRA-20116)
* Restore optimization in MultiCBuilder around building one clustering (CASSANDRA-20129) * Restore optimization in MultiCBuilder around building one clustering (CASSANDRA-20129)

View File

@ -88,7 +88,6 @@ New features
generate a password of configured password strength policy upon role creation or alteration generate a password of configured password strength policy upon role creation or alteration
when 'GENERATED PASSWORD' clause is used. Character sets supported are: English, Cyrillic, modern Cyrillic, when 'GENERATED PASSWORD' clause is used. Character sets supported are: English, Cyrillic, modern Cyrillic,
German, Polish and Czech. German, Polish and Czech.
- JMX SSL configuration can be now done in cassandra.yaml via jmx_encryption_options section instead of cassandra-env.sh
- There is new MBean of name org.apache.cassandra.service.snapshot:type=SnapshotManager which exposes user-facing - There is new MBean of name org.apache.cassandra.service.snapshot:type=SnapshotManager which exposes user-facing
snapshot operations. Snapshot-related methods on StorageServiceMBean are still present and functional snapshot operations. Snapshot-related methods on StorageServiceMBean are still present and functional
but marked as deprecated. but marked as deprecated.
@ -102,6 +101,12 @@ New features
compactions. To avoid the possibility of starving background compactions from resources, the number of threads compactions. To avoid the possibility of starving background compactions from resources, the number of threads
used for major compactions is limited to half the available compaction threads by default, and can be controlled used for major compactions is limited to half the available compaction threads by default, and can be controlled
by a new --jobs / -j option of nodetool compact. by a new --jobs / -j option of nodetool compact.
- It is possible to configure JMX server in cassandra.yaml in jmx_server_options configuration section.
JMX SSL configuration can be configured via jmx_encryption_options in jmx_server_options. The old way of
configuring JMX is still present and default, but new way is preferable as it will e.g. not leak credentials for
JMX to JVM parameters. You have to opt-in to use the configuration via cassandra.yaml by uncommenting
the respective configuration sections and by commenting out `configure_jmx` function call in cassandra-env.sh.
Enabling both ways of configuring JMX will result in a node failing to start.
Upgrading Upgrading

View File

@ -52,6 +52,19 @@ if [ -f "$CASSANDRA_CONF/cassandra-env.sh" ]; then
JVM_OPTS="$JVM_OPTS_SAVE" JVM_OPTS="$JVM_OPTS_SAVE"
fi fi
# In case JMX_PORT is not set (when configure_jmx in cassandra-env.sh is commented out),
# try to parse it from cassandra.yaml.
if [ "x$JMX_PORT" = "x" ]; then
if [ -f "$CASSANDRA_CONF/cassandra.yaml" ]; then
JMX_PORT=`grep jmx_port $CASSANDRA_CONF/cassandra.yaml | cut -d ':' -f 2 | tr -d '[[:space:]]'`
fi
fi
# If, by any chance, it is not there either, set it to default.
if [ "x$JMX_PORT" = "x" ]; then
JMX_PORT=7199
fi
# JMX Port passed via cmd line args (-p 9999 / --port 9999 / --port=9999) # JMX Port passed via cmd line args (-p 9999 / --port 9999 / --port=9999)
# should override the value from cassandra-env.sh # should override the value from cassandra-env.sh
ARGS="" ARGS=""

View File

@ -218,55 +218,66 @@ if [ "x$LOCAL_JMX" = "x" ]; then
LOCAL_JMX=yes LOCAL_JMX=yes
fi fi
# Specifies the default port over which Cassandra will be available for configure_jmx()
# JMX connections. {
JMX_PORT=$1
if [ "$LOCAL_JMX" = "yes" ]; then
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.local.port=$JMX_PORT"
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
else
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.port=$JMX_PORT"
# if ssl is enabled the same port cannot be used for both jmx and rmi so either
# pick another value for this property or comment out to use a random port (though see CASSANDRA-7087 for origins)
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT"
# turn on JMX authentication. See below for further options
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true"
# jmx ssl options
# Consider using the jmx_encryption_options section of jmx_server_options in cassandra.yaml instead
# to prevent sensitive information being exposed.
# In case jmx ssl options are configured in both the places - this file and cassandra.yaml, and
# if com.sun.management.jmxremote.ssl is configured to be true here and encryption_options are marked enabled in
# cassandra.yaml, then we will get exception at the startup
#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 -Dcom.sun.management.jmxremote.ssl.enabled.protocols=<enabled-protocols>"
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl.enabled.cipher.suites=<enabled-cipher-suites>"
#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-password>"
fi
# jmx authentication and authorization options. By default, auth is only
# activated for remote connections but they can also be enabled for local only JMX
## Basic file based authn & authz
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"
## Custom auth settings which can be used as alternatives to JMX's out of the box auth utilities.
## JAAS login modules can be used for authentication by uncommenting these two properties.
## Cassandra ships with a LoginModule implementation - org.apache.cassandra.auth.CassandraLoginModule -
## which delegates to the IAuthenticator configured in cassandra.yaml. See the sample JAAS configuration
## file cassandra-jaas.config
#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.login.config=CassandraLogin"
#JVM_OPTS="$JVM_OPTS -Djava.security.auth.login.config=$CASSANDRA_CONF/cassandra-jaas.config"
## Cassandra also ships with a helper for delegating JMX authz calls to the configured IAuthorizer,
## uncomment this to use it. Requires one of the two authentication options to be enabled
#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.authorizer=org.apache.cassandra.auth.jmx.AuthorizationProxy"
}
# If this function call is commented out, then Cassandra will start with no system properties for JMX set whatsoever.
# We will be expecting the settings in jmx_server_options and jmx_encryption_options respectively instead.
# The argument specifies the default port over which Cassandra will be available for JMX connections.
#
# If you comment out configure_jmx method call, then JMX_PORT variable will not be set, which means
# nodetool which sources this file will not see it either and port from cassandra.yaml will be parsed instead,
# if not found there either, it defaults to 7199.
#
# For security reasons, you should not expose this port to the internet. Firewall it if needed. # For security reasons, you should not expose this port to the internet. Firewall it if needed.
JMX_PORT="7199" configure_jmx 7199
if [ "$LOCAL_JMX" = "yes" ]; then
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.local.port=$JMX_PORT"
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
else
JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.port=$JMX_PORT"
# if ssl is enabled the same port cannot be used for both jmx and rmi so either
# pick another value for this property or comment out to use a random port (though see CASSANDRA-7087 for origins)
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT"
# turn on JMX authentication. See below for further options
JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=true"
# jmx ssl options
# Consider using the jmx_encryption_options section of cassandra.yaml instead
# to prevent sensitive information being exposed.
# In case jmx ssl options are configured in both the places - this file and cassandra.yaml, and
# if com.sun.management.jmxremote.ssl is configured to be true here and encryption_options are marked enabled in
# cassandra.yaml, then we will get exception at the startup
#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 -Dcom.sun.management.jmxremote.ssl.enabled.protocols=<enabled-protocols>"
#JVM_OPTS="$JVM_OPTS -Dcom.sun.management.jmxremote.ssl.enabled.cipher.suites=<enabled-cipher-suites>"
#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-password>"
fi
# jmx authentication and authorization options. By default, auth is only
# activated for remote connections but they can also be enabled for local only JMX
## Basic file based authn & authz
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"
## Custom auth settings which can be used as alternatives to JMX's out of the box auth utilities.
## JAAS login modules can be used for authentication by uncommenting these two properties.
## Cassandra ships with a LoginModule implementation - org.apache.cassandra.auth.CassandraLoginModule -
## which delegates to the IAuthenticator configured in cassandra.yaml. See the sample JAAS configuration
## file cassandra-jaas.config
#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.remote.login.config=CassandraLogin"
#JVM_OPTS="$JVM_OPTS -Djava.security.auth.login.config=$CASSANDRA_CONF/cassandra-jaas.config"
## Cassandra also ships with a helper for delegating JMX authz calls to the configured IAuthorizer,
## uncomment this to use it. Requires one of the two authentication options to be enabled
#JVM_OPTS="$JVM_OPTS -Dcassandra.jmx.authorizer=org.apache.cassandra.auth.jmx.AuthorizationProxy"
# To use mx4j, an HTML interface for JMX, add mx4j-tools.jar to the lib/ # To use mx4j, an HTML interface for JMX, add mx4j-tools.jar to the lib/
# directory. # directory.

View File

@ -1721,14 +1721,59 @@ client_encryption_options:
# JMX SSL. # JMX SSL.
# Similar to `client/server_encryption_options`, you can specify PEM-based # Similar to `client/server_encryption_options`, you can specify PEM-based
# key material or customize the SSL configuration using `ssl_context_factory` in `jmx_encryption_options`. # key material or customize the SSL configuration using `ssl_context_factory` in `jmx_encryption_options`.
#jmx_encryption_options: # If you uncomment this section, please be sure that you comment out configure_jmx function call in cassandra-env.sh
# enabled: true # as it is errorneous to have JMX set by two ways, both in cassandra-env.sh and in this yaml.
# cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256] #jmx_server_options:
# accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1] # enabled: true
# keystore: conf/cassandra_ssl.keystore # remote: false
# keystore_password: cassandra # jmx_port: 7199
# truststore: conf/cassandra_ssl.truststore #
# truststore_password: cassandra # Port used by the RMI registry when remote connections are enabled.
# To simplify firewall configs, this can be set to the same as the JMX server port (port). See CASSANDRA-7087.
# However, if ssl is enabled the same port cannot be used for both jmx and rmi so either
# pick another value for this property. Alternatively, comment out or set to 0 to use a random
# port (pre-CASSANDRA-7087 behaviour)
# rmi_port: 7199
#
# jmx ssl options - only apply when remote connections are enabled
#
# jmx_encryption_options:
# enabled: true
# cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]
# accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1]
# keystore: conf/cassandra_ssl.keystore
# keystore_password: cassandra
# truststore: conf/cassandra_ssl.truststore
# truststore_password: cassandra
#
# jmx authentication and authorization options.
# authenticate: false
#
# Options for basic file based authentication & authorization
# password_file: /etc/cassandra/jmxremote.password
# access_file: /etc/cassandra/jmxremote.access
#
# Custom auth settings which can be used as alternatives to JMX's out of the box auth utilities.
# JAAS login modules can be used for authentication using this property.Cassandra ships with a
# LoginModule implementation - org.apache.cassandra.auth.CassandraLoginModule - which delegates
# to the IAuthenticator configured in cassandra.yaml.
#
# login_config_name refers to the Application Name in the JAAS configuration under which the
# desired LoginModule(s) are configured.
# The location of the JAAS config file may be set using the standard JVM mechanism, by setting
# the system property "java.security.auth.login.config". If this property is set, it's value
# will be used to locate the config file. For convenience, if the property is not already set
# at startup, a value can be supplied here via the login_config_file setting.
#
# The Application Name specified must be present in the JAAS config or an error will be thrown
# when authentication is attempted.
# See the sample JAAS configuration file conf/cassandra-jaas.config
# login_config_name: CassandraLogin
# login_config_file: conf/cassandra-jaas.config
#
# Cassandra also ships with a helper for delegating JMX authz calls to the configured IAuthorizer,
# uncomment this to use it. Requires one of the two authentication options to be enabled
# authorizer: org.apache.cassandra.auth.jmx.AuthorizationProxy
# internode_compression controls whether traffic between nodes is # internode_compression controls whether traffic between nodes is
# compressed. # compressed.

View File

@ -1685,14 +1685,59 @@ client_encryption_options:
# JMX SSL. # JMX SSL.
# Similar to `client/server_encryption_options`, you can specify PEM-based # Similar to `client/server_encryption_options`, you can specify PEM-based
# key material or customize the SSL configuration using `ssl_context_factory` in `jmx_encryption_options`. # key material or customize the SSL configuration using `ssl_context_factory` in `jmx_encryption_options`.
#jmx_encryption_options: # If you uncomment this section, please be sure that you comment out configure_jmx function call in cassandra-env.sh
# enabled: true # as it is errorneous to have JMX set by two ways, both in cassandra-env.sh and in this yaml.
# cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256] #jmx_server_options:
# accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1] # enabled: true
# keystore: conf/cassandra_ssl.keystore # remote: false
# keystore_password: cassandra # jmx_port: 7199
# truststore: conf/cassandra_ssl.truststore #
# truststore_password: cassandra # Port used by the RMI registry when remote connections are enabled.
# To simplify firewall configs, this can be set to the same as the JMX server port (port). See CASSANDRA-7087.
# However, if ssl is enabled the same port cannot be used for both jmx and rmi so either
# pick another value for this property. Alternatively, comment out or set to 0 to use a random
# port (pre-CASSANDRA-7087 behaviour)
# rmi_port: 7199
#
# jmx ssl options - only apply when remote connections are enabled
#
# jmx_encryption_options:
# enabled: true
# cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]
# accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1]
# keystore: conf/cassandra_ssl.keystore
# keystore_password: cassandra
# truststore: conf/cassandra_ssl.truststore
# truststore_password: cassandra
#
# jmx authentication and authorization options.
# authenticate: false
#
# Options for basic file based authentication & authorization
# password_file: /etc/cassandra/jmxremote.password
# access_file: /etc/cassandra/jmxremote.access
#
# Custom auth settings which can be used as alternatives to JMX's out of the box auth utilities.
# JAAS login modules can be used for authentication using this property.Cassandra ships with a
# LoginModule implementation - org.apache.cassandra.auth.CassandraLoginModule - which delegates
# to the IAuthenticator configured in cassandra.yaml.
#
# login_config_name refers to the Application Name in the JAAS configuration under which the
# desired LoginModule(s) are configured.
# The location of the JAAS config file may be set using the standard JVM mechanism, by setting
# the system property "java.security.auth.login.config". If this property is set, it's value
# will be used to locate the config file. For convenience, if the property is not already set
# at startup, a value can be supplied here via the login_config_file setting.
#
# The Application Name specified must be present in the JAAS config or an error will be thrown
# when authentication is attempted.
# See the sample JAAS configuration file conf/cassandra-jaas.config
# login_config_name: CassandraLogin
# login_config_file: conf/cassandra-jaas.config
#
# Cassandra also ships with a helper for delegating JMX authz calls to the configured IAuthorizer,
# uncomment this to use it. Requires one of the two authentication options to be enabled
# authorizer: org.apache.cassandra.auth.jmx.AuthorizationProxy
# internode_compression controls whether traffic between nodes is # internode_compression controls whether traffic between nodes is
# compressed. # compressed.

View File

@ -49,7 +49,7 @@ COMPLEX_OPTIONS = (
'hints_compression', 'hints_compression',
'server_encryption_options', 'server_encryption_options',
'client_encryption_options', 'client_encryption_options',
'jmx_encryption_options', 'jmx_server_options',
'transparent_data_encryption_options', 'transparent_data_encryption_options',
'hinted_handoff_disabled_datacenters', 'hinted_handoff_disabled_datacenters',
'startup_checks', 'startup_checks',

View File

@ -146,6 +146,8 @@ public enum CassandraRelevantProperties
COM_SUN_MANAGEMENT_JMXREMOTE_PASSWORD_FILE("com.sun.management.jmxremote.password.file"), COM_SUN_MANAGEMENT_JMXREMOTE_PASSWORD_FILE("com.sun.management.jmxremote.password.file"),
/** Port number to enable JMX RMI connections - com.sun.management.jmxremote.port */ /** Port number to enable JMX RMI connections - com.sun.management.jmxremote.port */
COM_SUN_MANAGEMENT_JMXREMOTE_PORT("com.sun.management.jmxremote.port"), COM_SUN_MANAGEMENT_JMXREMOTE_PORT("com.sun.management.jmxremote.port"),
/** Enables SSL sockets for the RMI registry from which clients obtain the JMX connector stub */
COM_SUN_MANAGEMENT_JMXREMOTE_REGISTRY_SSL("com.sun.management.jmxremote.registry.ssl"),
/** /**
* The port number to which the RMI connector will be bound - com.sun.management.jmxremote.rmi.port. * The port number to which the RMI connector will be bound - com.sun.management.jmxremote.rmi.port.
* An Integer object that represents the value of the second argument is returned * An Integer object that represents the value of the second argument is returned
@ -287,6 +289,10 @@ public enum CassandraRelevantProperties
IO_NETTY_EVENTLOOP_THREADS("io.netty.eventLoopThreads"), IO_NETTY_EVENTLOOP_THREADS("io.netty.eventLoopThreads"),
IO_NETTY_TRANSPORT_ESTIMATE_SIZE_ON_SUBMIT("io.netty.transport.estimateSizeOnSubmit"), IO_NETTY_TRANSPORT_ESTIMATE_SIZE_ON_SUBMIT("io.netty.transport.estimateSizeOnSubmit"),
IO_NETTY_TRANSPORT_NONATIVE("io.netty.transport.noNative"), IO_NETTY_TRANSPORT_NONATIVE("io.netty.transport.noNative"),
JAVAX_NET_SSL_KEYSTORE("javax.net.ssl.keyStore"),
JAVAX_NET_SSL_KEYSTOREPASSWORD("javax.net.ssl.keyStorePassword"),
JAVAX_NET_SSL_TRUSTSTORE("javax.net.ssl.trustStore"),
JAVAX_NET_SSL_TRUSTSTOREPASSWORD("javax.net.ssl.trustStorePassword"),
JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES("javax.rmi.ssl.client.enabledCipherSuites"), JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES("javax.rmi.ssl.client.enabledCipherSuites"),
JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS("javax.rmi.ssl.client.enabledProtocols"), JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS("javax.rmi.ssl.client.enabledProtocols"),
/** Java class path. */ /** Java class path. */

View File

@ -434,7 +434,8 @@ public class Config
public EncryptionOptions.ServerEncryptionOptions server_encryption_options = new EncryptionOptions.ServerEncryptionOptions(); public EncryptionOptions.ServerEncryptionOptions server_encryption_options = new EncryptionOptions.ServerEncryptionOptions();
public EncryptionOptions client_encryption_options = new EncryptionOptions(); public EncryptionOptions client_encryption_options = new EncryptionOptions();
public EncryptionOptions jmx_encryption_options = new EncryptionOptions();
public JMXServerOptions jmx_server_options;
public InternodeCompression internode_compression = InternodeCompression.none; public InternodeCompression internode_compression = InternodeCompression.none;
@ -1322,7 +1323,8 @@ public class Config
private static final Set<String> SENSITIVE_KEYS = new HashSet<String>() {{ private static final Set<String> SENSITIVE_KEYS = new HashSet<String>() {{
add("client_encryption_options"); add("client_encryption_options");
add("server_encryption_options"); add("server_encryption_options");
add("jmx_encryption_options"); // jmx_server_options output (JMXServerOptions.toString()) doesn't
// include sensitive encryption config so no need to blocklist here
}}; }};
public static void log(Config config) public static void log(Config config)

View File

@ -960,8 +960,19 @@ public class DatabaseDescriptor
if (conf.client_encryption_options != null) if (conf.client_encryption_options != null)
conf.client_encryption_options.applyConfig(); conf.client_encryption_options.applyConfig();
if (conf.jmx_encryption_options != null) if (conf.jmx_server_options == null)
conf.jmx_encryption_options.applyConfig(); {
conf.jmx_server_options = JMXServerOptions.createParsingSystemProperties();
}
else if (JMXServerOptions.isEnabledBySystemProperties())
{
throw new ConfigurationException("Configure either jmx_server_options in cassandra.yaml and comment out " +
"configure_jmx function call in cassandra-env.sh or keep cassandra-env.sh " +
"to call configure_jmx function but you have to keep jmx_server_options " +
"in cassandra.yaml commented out.");
}
conf.jmx_server_options.jmx_encryption_options.applyConfig();
if (conf.snapshot_links_per_second < 0) if (conf.snapshot_links_per_second < 0)
throw new ConfigurationException("snapshot_links_per_second must be >= 0"); throw new ConfigurationException("snapshot_links_per_second must be >= 0");
@ -1310,7 +1321,7 @@ public class DatabaseDescriptor
SSLFactory.validateSslContext("Internode messaging", conf.server_encryption_options, REQUIRED, true); SSLFactory.validateSslContext("Internode messaging", conf.server_encryption_options, REQUIRED, true);
SSLFactory.validateSslContext("Native transport", conf.client_encryption_options, conf.client_encryption_options.getClientAuth(), true); SSLFactory.validateSslContext("Native transport", conf.client_encryption_options, conf.client_encryption_options.getClientAuth(), true);
// For JMX SSL the validation is pretty much the same as the Native transport // For JMX SSL the validation is pretty much the same as the Native transport
SSLFactory.validateSslContext("JMX transport", conf.jmx_encryption_options, conf.jmx_encryption_options.getClientAuth(), true); SSLFactory.validateSslContext("JMX transport", conf.jmx_server_options.jmx_encryption_options, conf.jmx_server_options.jmx_encryption_options.getClientAuth(), true);
SSLFactory.initHotReloading(conf.server_encryption_options, conf.client_encryption_options, false); SSLFactory.initHotReloading(conf.server_encryption_options, conf.client_encryption_options, false);
/* /*
For JMX SSL, the hot reloading of the SSLContext is out of scope for CASSANDRA-18508. For JMX SSL, the hot reloading of the SSLContext is out of scope for CASSANDRA-18508.
@ -3663,9 +3674,9 @@ public class DatabaseDescriptor
return conf.client_encryption_options; return conf.client_encryption_options;
} }
public static EncryptionOptions getJmxEncryptionOptions() public static JMXServerOptions getJmxServerOptions()
{ {
return conf.jmx_encryption_options; return conf.jmx_server_options;
} }
@VisibleForTesting @VisibleForTesting

View File

@ -470,7 +470,12 @@ public class EncryptionOptions
public String[] acceptedProtocolsArray() public String[] acceptedProtocolsArray()
{ {
List<String> ap = getAcceptedProtocols(); List<String> ap = getAcceptedProtocols();
return ap == null ? new String[0] : ap.toArray(new String[0]); return ap == null ? null : ap.toArray(new String[0]);
}
public List<String> getCipherSuites()
{
return sslContextFactoryInstance == null ? null : sslContextFactoryInstance.getCipherSuites();
} }
public String[] cipherSuitesArray() public String[] cipherSuitesArray()

View File

@ -0,0 +1,240 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.config;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_AUTHORIZER;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_LOCAL_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_LOGIN_CONFIG;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_ACCESS_FILE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_PASSWORD_FILE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_RMI_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_PROTOCOLS;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_NEED_CLIENT_AUTH;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTOREPASSWORD;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTOREPASSWORD;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_SECURITY_AUTH_LOGIN_CONFIG;
public class JMXServerOptions
{
//jmx server settings
public final Boolean enabled;
public final Boolean remote;
public final int jmx_port;
public final int rmi_port;
public final Boolean authenticate;
// ssl options
public final EncryptionOptions jmx_encryption_options;
// options for using Cassandra's own authentication mechanisms
public final String login_config_name;
public final String login_config_file;
// location for credentials file if using JVM's file-based authentication
public final String password_file;
// location of standard access file, if using JVM's file-based access control
public final String access_file;
// classname of authorizer if using a custom authz mechanism. Usually, this will
// refer to o.a.c.auth.jmx.AuthorizationProxy which delegates to the IAuthorizer
// configured in cassandra.yaml
public final String authorizer;
public JMXServerOptions()
{
this(true, false, 7199, 0, false,
new EncryptionOptions(), null, null, null,
null, null);
}
public static JMXServerOptions create(boolean enabled, boolean local, int jmxPort, EncryptionOptions options)
{
return new JMXServerOptions(enabled, !local, jmxPort, 0, false,
options, null, null, null,
null, null);
}
public static JMXServerOptions fromDescriptor(boolean enabled, boolean local, int jmxPort)
{
JMXServerOptions from = DatabaseDescriptor.getJmxServerOptions();
return new JMXServerOptions(enabled, !local, jmxPort, jmxPort, from.authenticate,
from.jmx_encryption_options, from.login_config_name, from.login_config_file, from.password_file,
from.access_file, from.authorizer);
}
public JMXServerOptions(Boolean enabled,
Boolean remote,
int jmxPort,
int rmiPort,
Boolean authenticate,
EncryptionOptions jmx_encryption_options,
String loginConfigName,
String loginConfigFile,
String passwordFile,
String accessFile,
String authorizer)
{
this.enabled = enabled;
this.remote = remote;
this.jmx_port = jmxPort;
this.rmi_port = rmiPort;
this.authenticate = authenticate;
this.jmx_encryption_options = jmx_encryption_options;
this.login_config_name = loginConfigName;
this.login_config_file = loginConfigFile;
this.password_file = passwordFile;
this.access_file = accessFile;
this.authorizer = authorizer;
}
@Override
public String toString()
{
// we are not including encryption options on purpose
// as that contains credentials etc.
String jmxOptionsString;
if (jmx_encryption_options == null)
jmxOptionsString = "unspecified";
else
jmxOptionsString = jmx_encryption_options.enabled ? "enabled" : "disabled";
return "JMXServerOptions{" +
"enabled=" + enabled +
", remote=" + remote +
", jmx_port=" + jmx_port +
", rmi_port=" + rmi_port +
", authenticate=" + authenticate +
", jmx_encryption_options=" + jmx_encryption_options +
", login_config_name='" + login_config_name + '\'' +
", login_config_file='" + login_config_file + '\'' +
", password_file='" + password_file + '\'' +
", access_file='" + access_file + '\'' +
", authorizer='" + authorizer + '\'' +
'}';
}
public static boolean isEnabledBySystemProperties()
{
return CASSANDRA_JMX_REMOTE_PORT.isPresent() || CASSANDRA_JMX_LOCAL_PORT.isPresent();
}
public static JMXServerOptions createParsingSystemProperties()
{
int jmxPort;
boolean remote;
if (CASSANDRA_JMX_REMOTE_PORT.isPresent())
{
jmxPort = CASSANDRA_JMX_REMOTE_PORT.getInt();
remote = true;
}
else
{
jmxPort = CASSANDRA_JMX_LOCAL_PORT.getInt(7199);
remote = false;
}
boolean enabled = isEnabledBySystemProperties();
int rmiPort = COM_SUN_MANAGEMENT_JMXREMOTE_RMI_PORT.getInt();
boolean authenticate = COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE.getBoolean();
String loginConfigName = CASSANDRA_JMX_REMOTE_LOGIN_CONFIG.getString();
String loginConfigFile = JAVA_SECURITY_AUTH_LOGIN_CONFIG.getString();
String accessFile = COM_SUN_MANAGEMENT_JMXREMOTE_ACCESS_FILE.getString();
String passwordFile = COM_SUN_MANAGEMENT_JMXREMOTE_PASSWORD_FILE.getString();
String authorizer = CASSANDRA_JMX_AUTHORIZER.getString();
// encryption options
String keystore = JAVAX_NET_SSL_KEYSTORE.getString();
String keystorePassword = JAVAX_NET_SSL_KEYSTOREPASSWORD.getString();
String truststore = JAVAX_NET_SSL_TRUSTSTORE.getString();
String truststorePassword = JAVAX_NET_SSL_TRUSTSTOREPASSWORD.getString();
String rawCipherSuites = COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES.getString();
List<String> cipherSuites = null;
if (rawCipherSuites != null)
cipherSuites = List.of(StringUtils.split(rawCipherSuites, ","));
String rawSslProtocols = COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_PROTOCOLS.getString();
List<String> acceptedProtocols = null;
if (rawSslProtocols != null)
acceptedProtocols = List.of(StringUtils.split(rawSslProtocols, ","));
String requireClientAuth = COM_SUN_MANAGEMENT_JMXREMOTE_SSL_NEED_CLIENT_AUTH.getString("false");
boolean sslEnabled = COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean();
EncryptionOptions encryptionOptions = new EncryptionOptions(new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory", new HashMap<>()),
keystore,
keystorePassword,
truststore,
truststorePassword,
cipherSuites,
null, // protocol
acceptedProtocols,
null, // algorithm
null, // store_type
requireClientAuth,
false, // require endpoint verification
sslEnabled,
false, // optional
null, // max_certificate_validity_period
null); // certificate_validity_warn_threshold
return new JMXServerOptions(enabled, remote, jmxPort, rmiPort, authenticate,
encryptionOptions, loginConfigName, loginConfigFile, passwordFile, accessFile,
authorizer);
}
/**
* Sets the following JMX system properties.
* <pre>
* com.sun.management.jmxremote.ssl=true
* javax.rmi.ssl.client.enabledCipherSuites=&lt;applicable cipher suites provided in the configuration&gt;
* javax.rmi.ssl.client.enabledProtocols=&lt;applicable protocols provided in the configuration&gt;
* </pre>
*
* @param acceptedProtocols for the SSL communication
* @param cipherSuites for the SSL communication
*/
public static void setJmxSystemProperties(List<String> acceptedProtocols, List<String> cipherSuites)
{
COM_SUN_MANAGEMENT_JMXREMOTE_SSL.setBoolean(true);
if (acceptedProtocols != null)
JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS.setString(StringUtils.join(acceptedProtocols, ","));
if (cipherSuites != null)
JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES.setString(StringUtils.join(cipherSuites, ","));
}
}

View File

@ -48,6 +48,7 @@ import org.apache.cassandra.auth.AuthCacheService;
import org.apache.cassandra.concurrent.ScheduledExecutors; import org.apache.cassandra.concurrent.ScheduledExecutors;
import org.apache.cassandra.config.CassandraRelevantProperties; import org.apache.cassandra.config.CassandraRelevantProperties;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.db.Keyspace;
@ -91,8 +92,6 @@ import org.apache.cassandra.utils.logging.VirtualTableAppender;
import static java.util.concurrent.TimeUnit.NANOSECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_FOREGROUND; import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_FOREGROUND;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_LOCAL_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_PID_FILE; import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_PID_FILE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_PORT; import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_CLASS_PATH; import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_CLASS_PATH;
@ -153,42 +152,24 @@ public class CassandraDaemon
// then the JVM agent will have already started up a default JMX connector // then the JVM agent will have already started up a default JMX connector
// server. This behaviour is deprecated, but some clients may be relying // server. This behaviour is deprecated, but some clients may be relying
// on it, so log a warning and skip setting up the server with the settings // on it, so log a warning and skip setting up the server with the settings
// as configured in cassandra-env.(sh|ps1) // as configured in cassandra.yaml or cassandra-env.sh.
// See: CASSANDRA-11540 & CASSANDRA-11725 // See: CASSANDRA-11540 & CASSANDRA-11725
if (COM_SUN_MANAGEMENT_JMXREMOTE_PORT.isPresent()) if (COM_SUN_MANAGEMENT_JMXREMOTE_PORT.isPresent())
{ {
logger.warn("JMX settings in cassandra-env.sh have been bypassed as the JMX connector server is " + logger.warn("JMX settings in cassandra.yaml or cassandra-env.sh have been bypassed as the JMX connector server is " +
"already initialized. Please refer to cassandra-env.(sh|ps1) for JMX configuration info"); "already initialized. Please refer to cassandra.yaml or cassandra-env.sh for JMX configuration info");
return; return;
} }
JAVA_RMI_SERVER_RANDOM_ID.setBoolean(true); JAVA_RMI_SERVER_RANDOM_ID.setBoolean(true);
// If a remote port has been specified then use that to set up a JMX JMXServerOptions jmxServerOptions = DatabaseDescriptor.getJmxServerOptions();
// connector server which can be accessed remotely. Otherwise, look if (!jmxServerOptions.enabled)
// for the local port property and create a server which is bound
// only to the loopback address. Auth options are applied to both
// remote and local-only servers, but currently SSL is only
// available for remote.
// If neither is remote nor local port is set in cassandra-env.(sh|ps)
// then JMX is effectively disabled.
boolean localOnly = false;
String jmxPort = CASSANDRA_JMX_REMOTE_PORT.getString();
if (jmxPort == null)
{
localOnly = true;
jmxPort = CASSANDRA_JMX_LOCAL_PORT.getString();
}
if (jmxPort == null)
return; return;
try try
{ {
jmxServer = JMXServerUtils.createJMXServer(Integer.parseInt(jmxPort), localOnly); jmxServer = JMXServerUtils.createJMXServer(jmxServerOptions);
if (jmxServer == null)
return;
} }
catch (IOException e) catch (IOException e)
{ {

View File

@ -54,6 +54,7 @@ import net.jpountz.lz4.LZ4Factory;
import org.apache.cassandra.config.CassandraRelevantProperties; import org.apache.cassandra.config.CassandraRelevantProperties;
import org.apache.cassandra.config.Config; import org.apache.cassandra.config.Config;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.config.StartupChecksOptions; import org.apache.cassandra.config.StartupChecksOptions;
import org.apache.cassandra.cql3.QueryProcessor; import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.UntypedResultSet; import org.apache.cassandra.cql3.UntypedResultSet;
@ -74,7 +75,6 @@ import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.JavaUtils; import org.apache.cassandra.utils.JavaUtils;
import org.apache.cassandra.utils.NativeLibrary; import org.apache.cassandra.utils.NativeLibrary;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_LOCAL_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_PORT; import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.IGNORE_KERNEL_BUG_1057843_CHECK; import static org.apache.cassandra.config.CassandraRelevantProperties.IGNORE_KERNEL_BUG_1057843_CHECK;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_VERSION; import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_VERSION;
@ -312,17 +312,21 @@ public class StartupChecks
{ {
if (options.isDisabled(getStartupCheckType())) if (options.isDisabled(getStartupCheckType()))
return; return;
String jmxPort = CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_PORT.getString();
if (jmxPort == null) JMXServerOptions jmxServerOptions = DatabaseDescriptor.getJmxServerOptions();
if (!jmxServerOptions.enabled)
{ {
logger.warn("JMX is not enabled to receive remote connections. Please see cassandra-env.sh for more info."); logger.warn("JMX connection server is not enabled for either local or remote connections. " +
jmxPort = CassandraRelevantProperties.CASSANDRA_JMX_LOCAL_PORT.toString(); "Please see jmx_server_options in cassandra.yaml for more info");
if (jmxPort == null) }
logger.error(CASSANDRA_JMX_LOCAL_PORT.getKey() + " missing from cassandra-env.sh, unable to start local JMX service."); if (!jmxServerOptions.remote)
{
logger.warn("JMX is not enabled to receive remote connections. " +
"Please see jmx_server_options in cassandra.yaml for more info.");
} }
else else
{ {
logger.info("JMX is enabled to receive remote connections on port: {}", jmxPort); logger.info("JMX is enabled to receive remote connections on port: {}", jmxServerOptions.jmx_port);
} }
} }
}; };

View File

@ -33,7 +33,6 @@ import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException; import java.rmi.NotBoundException;
import java.rmi.Remote; import java.rmi.Remote;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import java.rmi.registry.Registry;
import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject; import java.rmi.server.UnicastRemoteObject;
@ -49,20 +48,17 @@ import javax.net.ssl.SSLException;
import javax.security.auth.Subject; import javax.security.auth.Subject;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.cassandra.auth.jmx.AuthenticationProxy; import org.apache.cassandra.auth.jmx.AuthenticationProxy;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.CassandraRelevantProperties;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.utils.jmx.DefaultJmxSocketFactory; import org.apache.cassandra.utils.jmx.DefaultJmxSocketFactory;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_AUTHORIZER;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_LOGIN_CONFIG;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_ACCESS_FILE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_PASSWORD_FILE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_RMI_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_RMI_SERVER_HOSTNAME; import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_RMI_SERVER_HOSTNAME;
public class JMXServerUtils public class JMXServerUtils
@ -74,13 +70,12 @@ public class JMXServerUtils
* inaccessable. * inaccessable.
*/ */
@VisibleForTesting @VisibleForTesting
public static JMXConnectorServer createJMXServer(int port, String hostname, boolean local) public static JMXConnectorServer createJMXServer(JMXServerOptions options, String hostname) throws IOException
throws IOException
{ {
Map<String, Object> env = new HashMap<>(); Map<String, Object> env = new HashMap<>();
InetAddress serverAddress = null; InetAddress serverAddress = null;
if (local) if (!options.remote)
{ {
serverAddress = InetAddress.getLoopbackAddress(); serverAddress = InetAddress.getLoopbackAddress();
JAVA_RMI_SERVER_HOSTNAME.setString(serverAddress.getHostAddress()); JAVA_RMI_SERVER_HOSTNAME.setString(serverAddress.getHostAddress());
@ -88,18 +83,18 @@ public class JMXServerUtils
// Configure the RMI client & server socket factories, including SSL config. // Configure the RMI client & server socket factories, including SSL config.
// CASSANDRA-18508: Make JMX SSL to be configured in cassandra.yaml // CASSANDRA-18508: Make JMX SSL to be configured in cassandra.yaml
env.putAll(configureJmxSocketFactories(serverAddress, local)); env.putAll(configureJmxSocketFactories(serverAddress, options));
// configure the RMI registry // configure the RMI registry
Registry registry = new JmxRegistry(port, JmxRegistry registry = new JmxRegistry(options.jmx_port,
(RMIClientSocketFactory) env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE), (RMIClientSocketFactory) env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE),
(RMIServerSocketFactory) env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE), (RMIServerSocketFactory) env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE),
"jmxrmi"); "jmxrmi");
// Configure authn, using a JMXAuthenticator which either wraps a set log LoginModules configured // Configure authn, using a JMXAuthenticator which either wraps a set log LoginModules configured
// via a JAAS configuration entry, or one which delegates to the standard file based authenticator. // via a JAAS configuration entry, or one which delegates to the standard file based authenticator.
// Authn is disabled if com.sun.management.jmxremote.authenticate=false // Authn is disabled if com.sun.management.jmxremote.authenticate=false
env.putAll(configureJmxAuthentication()); env.putAll(configureJmxAuthentication(options));
// Secure credential passing to avoid deserialization attacks // Secure credential passing to avoid deserialization attacks
env.putAll(configureSecureCredentials()); env.putAll(configureSecureCredentials());
@ -107,7 +102,7 @@ public class JMXServerUtils
// If not, but a location for the standard access file is set in system properties, the // If not, but a location for the standard access file is set in system properties, the
// return value is null, and an entry is added to the env map detailing that location // return value is null, and an entry is added to the env map detailing that location
// If neither method is specified, no access control is applied // If neither method is specified, no access control is applied
MBeanServerForwarder authzProxy = configureJmxAuthorization(env); MBeanServerForwarder authzProxy = configureJmxAuthorization(options, env);
// Mark the JMX server as a permanently exported object. This allows the JVM to exit with the // Mark the JMX server as a permanently exported object. This allows the JVM to exit with the
// server running and also exempts it from the distributed GC scheduler which otherwise would // server running and also exempts it from the distributed GC scheduler which otherwise would
@ -121,7 +116,7 @@ public class JMXServerUtils
// Set the port used to create subsequent connections to exported objects over RMI. This simplifies // Set the port used to create subsequent connections to exported objects over RMI. This simplifies
// configuration in firewalled environments, but it can't be used in conjuction with SSL sockets. // configuration in firewalled environments, but it can't be used in conjuction with SSL sockets.
// See: CASSANDRA-7087 // See: CASSANDRA-7087
int rmiPort = COM_SUN_MANAGEMENT_JMXREMOTE_RMI_PORT.getInt(); int rmiPort = options.rmi_port;
// We create the underlying RMIJRMPServerImpl so that we can manually bind it to the registry, // We create the underlying RMIJRMPServerImpl so that we can manually bind it to the registry,
// rather then specifying a binding address in the JMXServiceURL and letting it be done automatically // rather then specifying a binding address in the JMXServiceURL and letting it be done automatically
@ -142,14 +137,14 @@ public class JMXServerUtils
jmxServer.setMBeanServerForwarder(authzProxy); jmxServer.setMBeanServerForwarder(authzProxy);
jmxServer.start(); jmxServer.start();
((JmxRegistry)registry).setRemoteServerStub(server.toStub()); registry.setRemoteServerStub(server.toStub());
logJmxServiceUrl(serverAddress, port); logJmxServiceUrl(serverAddress, options.jmx_port);
return jmxServer; return jmxServer;
} }
public static JMXConnectorServer createJMXServer(int port, boolean local) throws IOException public static JMXConnectorServer createJMXServer(JMXServerOptions serverOptions) throws IOException
{ {
return createJMXServer(port, null, local); return createJMXServer(serverOptions, null);
} }
private static Map<String, Object> configureSecureCredentials() private static Map<String, Object> configureSecureCredentials()
@ -159,10 +154,10 @@ public class JMXServerUtils
return env; return env;
} }
private static Map<String, Object> configureJmxAuthentication() private static Map<String, Object> configureJmxAuthentication(JMXServerOptions options)
{ {
Map<String, Object> env = new HashMap<>(); Map<String, Object> env = new HashMap<>();
if (!COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE.getBoolean()) if (!options.authenticate)
return env; return env;
// If authentication is enabled, initialize the appropriate JMXAuthenticator // If authentication is enabled, initialize the appropriate JMXAuthenticator
@ -176,14 +171,30 @@ public class JMXServerUtils
// before creating the authenticator. If no password file has been // before creating the authenticator. If no password file has been
// explicitly set, it's read from the default location // explicitly set, it's read from the default location
// $JAVA_HOME/lib/management/jmxremote.password // $JAVA_HOME/lib/management/jmxremote.password
String configEntry = CASSANDRA_JMX_REMOTE_LOGIN_CONFIG.getString(); String configEntry = options.login_config_name;
if (configEntry != null) if (configEntry != null)
{ {
if (Strings.isNullOrEmpty(CassandraRelevantProperties.JAVA_SECURITY_AUTH_LOGIN_CONFIG.getString()))
{
if (Strings.isNullOrEmpty(options.login_config_file))
{
throw new ConfigurationException(String.format("Login config name %s specified for JMX auth, but no " +
"configuration is available. Please set config " +
"location in cassandra.yaml or with the " +
"'%s' system property",
configEntry,
CassandraRelevantProperties.JAVA_SECURITY_AUTH_LOGIN_CONFIG.getKey()));
}
else
{
CassandraRelevantProperties.JAVA_SECURITY_AUTH_LOGIN_CONFIG.setString(options.login_config_file);
}
}
env.put(JMXConnectorServer.AUTHENTICATOR, new AuthenticationProxy(configEntry)); env.put(JMXConnectorServer.AUTHENTICATOR, new AuthenticationProxy(configEntry));
} }
else else
{ {
String passwordFile = COM_SUN_MANAGEMENT_JMXREMOTE_PASSWORD_FILE.getString(); String passwordFile = options.password_file;
if (passwordFile != null) if (passwordFile != null)
{ {
// stash the password file location where JMXPluggableAuthenticator expects it // stash the password file location where JMXPluggableAuthenticator expects it
@ -195,14 +206,14 @@ public class JMXServerUtils
return env; return env;
} }
private static MBeanServerForwarder configureJmxAuthorization(Map<String, Object> env) private static MBeanServerForwarder configureJmxAuthorization(JMXServerOptions options, Map<String, Object> env)
{ {
// If a custom authz proxy is supplied (Cassandra ships with AuthorizationProxy, which // If a custom authz proxy is supplied (Cassandra ships with AuthorizationProxy, which
// delegates to its own role based IAuthorizer), then instantiate and return one which // delegates to its own role based IAuthorizer), then instantiate and return one which
// can be set as the JMXConnectorServer's MBeanServerForwarder. // can be set as the JMXConnectorServer's MBeanServerForwarder.
// If no custom proxy is supplied, check system properties for the location of the // If no custom proxy is supplied, check system properties for the location of the
// standard access file & stash it in env // standard access file & stash it in env
String authzProxyClass = CASSANDRA_JMX_AUTHORIZER.getString(); String authzProxyClass = options.authorizer;
if (authzProxyClass != null) if (authzProxyClass != null)
{ {
final InvocationHandler handler = FBUtilities.construct(authzProxyClass, "JMX authz proxy"); final InvocationHandler handler = FBUtilities.construct(authzProxyClass, "JMX authz proxy");
@ -213,7 +224,7 @@ public class JMXServerUtils
} }
else else
{ {
String accessFile = COM_SUN_MANAGEMENT_JMXREMOTE_ACCESS_FILE.getString(); String accessFile = options.access_file;
if (accessFile != null) if (accessFile != null)
{ {
env.put("jmx.remote.x.access.file", accessFile); env.put("jmx.remote.x.access.file", accessFile);
@ -227,18 +238,16 @@ public class JMXServerUtils
* for configuring this. * for configuring this.
* *
* @param serverAddress the JMX server is bound to * @param serverAddress the JMX server is bound to
* @param localOnly {@code true} if the JMX server only allows local connections; {@code false} if the JMX server * @param serverOptions options for JMX server, either from {@code cassandra.yaml} or parsed as system properties from {@code cassandra-env.sh}.
* allows the remote connections.
* @return Map&lt;String, Object@gt; containing {@code jmx.remote.rmi.client.socket.factory}, {@code jmx.remote.rmi.server.socket.factory} * @return Map&lt;String, Object@gt; containing {@code jmx.remote.rmi.client.socket.factory}, {@code jmx.remote.rmi.server.socket.factory}
* and {@code com.sun.jndi.rmi.factory.socket} properties for the client and server socket factories. * and {@code com.sun.jndi.rmi.factory.socket} properties for the client and server socket factories.
* @throws SSLException if it fails to configure the socket factories with the given input * @throws SSLException if it fails to configure the socket factories with the given input
*
* @see DefaultJmxSocketFactory * @see DefaultJmxSocketFactory
*/ */
@VisibleForTesting @VisibleForTesting
public static Map<String, Object> configureJmxSocketFactories(InetAddress serverAddress, boolean localOnly) throws SSLException public static Map<String, Object> configureJmxSocketFactories(InetAddress serverAddress, JMXServerOptions serverOptions) throws SSLException
{ {
return new DefaultJmxSocketFactory().configure(serverAddress, localOnly, DatabaseDescriptor.getJmxEncryptionOptions()); return new DefaultJmxSocketFactory().configure(serverAddress, serverOptions, serverOptions.jmx_encryption_options);
} }
@VisibleForTesting @VisibleForTesting

View File

@ -24,19 +24,11 @@ import java.util.Map;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.cassandra.config.JMXServerOptions;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_PROTOCOLS;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_NEED_CLIENT_AUTH;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS;
/** /**
* Abstracts out the most common workflow in setting up the SSL client and server socket factorires for JMX. * Abstracts out the most common workflow in setting up the SSL client and server socket factorires for JMX.
@ -66,8 +58,7 @@ abstract public class AbstractJmxSocketFactory
* </pre> * </pre>
* *
* @param serverAddress the JMX server is bound to * @param serverAddress the JMX server is bound to
* @param localOnly {@code true} if the JMX server only allows local connections; {@code false} if the JMX server * @param serverOptions JMX server options
* allows the remote connections.
* @param jmxEncryptionOptions {@link EncryptionOptions} used for the SSL configuration in case of the remote * @param jmxEncryptionOptions {@link EncryptionOptions} used for the SSL configuration in case of the remote
* connections. Could be {@code null} if system properties are * connections. Could be {@code null} if system properties are
* used instead as per <a href="https://docs.oracle.com/en/java/javase/17/management/monitoring-and-management-using-jmx-technology.html#GUID-F08985BB-629A-4FBF-A0CB-8762DF7590E0">Java Documentation</a> * used instead as per <a href="https://docs.oracle.com/en/java/javase/17/management/monitoring-and-management-using-jmx-technology.html#GUID-F08985BB-629A-4FBF-A0CB-8762DF7590E0">Java Documentation</a>
@ -75,67 +66,30 @@ abstract public class AbstractJmxSocketFactory
* and {@code com.sun.jndi.rmi.factory.socket} properties for the client and server socket factories. * and {@code com.sun.jndi.rmi.factory.socket} properties for the client and server socket factories.
* @throws SSLException if it fails to configure the socket factories with the given input * @throws SSLException if it fails to configure the socket factories with the given input
*/ */
public Map<String, Object> configure(InetAddress serverAddress, boolean localOnly, public Map<String, Object> configure(InetAddress serverAddress,
JMXServerOptions serverOptions,
EncryptionOptions jmxEncryptionOptions) throws SSLException EncryptionOptions jmxEncryptionOptions) throws SSLException
{ {
Map<String, Object> env = new HashMap<>(); Map<String, Object> env = new HashMap<>();
boolean jmxRemoteSslSystemConfigProvided = COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean();
// We check for the enabled jmx_encryption_options here because in case of no configuration provided in cassandra.yaml // We check for the enabled jmx_encryption_options here because in case of no configuration provided in cassandra.yaml
// it will default to empty/non-null encryption options. Hence, we consider it set only if 'enabled' flag is set to true // it will default to empty/non-null encryption options. Hence, we consider it set only if 'enabled' flag is set to true
boolean jmxEncryptionOptionsProvided = jmxEncryptionOptions != null boolean jmxEncryptionOptionsProvided = jmxEncryptionOptions != null && jmxEncryptionOptions.getEnabled() != null && jmxEncryptionOptions.getEnabled();
&& jmxEncryptionOptions.getEnabled() != null
&& jmxEncryptionOptions.getEnabled();
if (jmxRemoteSslSystemConfigProvided && jmxEncryptionOptionsProvided) if (jmxEncryptionOptionsProvided)
{ {
throw new ConfigurationException("Please specify JMX SSL configuration in either cassandra-env.sh or " + if (jmxEncryptionOptions.getEnabled())
"cassandra.yaml, not in both locations"); JMXServerOptions.setJmxSystemProperties(jmxEncryptionOptions.getAcceptedProtocols(), jmxEncryptionOptions.getCipherSuites());
}
boolean requireClientAuth = false; logger.info("Enabling JMX SSL using jmx_encryption_options");
String[] ciphers = null; boolean requireClientAuth = jmxEncryptionOptions.getClientAuth() == EncryptionOptions.ClientAuth.REQUIRED;
String[] protocols = null; String[] ciphers = jmxEncryptionOptions.cipherSuitesArray();
SSLContext sslContext = null; String[] protocols = jmxEncryptionOptions.acceptedProtocolsArray();
SSLContext sslContext = jmxEncryptionOptions.sslContextFactoryInstance.createJSSESslContext(jmxEncryptionOptions.getClientAuth());
if (jmxRemoteSslSystemConfigProvided)
{
logger.info("Enabling JMX SSL using environment file properties");
logger.warn("Consider using the jmx_encryption_options section of cassandra.yaml instead to prevent " +
"sensitive information being exposed");
requireClientAuth = COM_SUN_MANAGEMENT_JMXREMOTE_SSL_NEED_CLIENT_AUTH.getBoolean();
String protocolList = COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_PROTOCOLS.getString();
if (protocolList != null)
{
JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS.setString(protocolList);
protocols = StringUtils.split(protocolList, ',');
}
String cipherList = COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES.getString();
if (cipherList != null)
{
JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES.setString(cipherList);
ciphers = StringUtils.split(cipherList, ',');
}
configureSslClientSocketFactory(env, serverAddress);
configureSslServerSocketFactory(env, serverAddress, ciphers, protocols, requireClientAuth);
}
else if (jmxEncryptionOptionsProvided)
{
logger.info("Enabling JMX SSL using jmx_encryption_options from cassandra.yaml");
// Here we can continue to use the SslRMIClientSocketFactory for client sockets.
// However, we should still set System properties for cipher_suites and enabled_protocols
// to have the same behavior as cassandra-env.sh based JMX SSL settings
setJmxSystemProperties(jmxEncryptionOptions);
requireClientAuth = jmxEncryptionOptions.getClientAuth() == EncryptionOptions.ClientAuth.REQUIRED;
ciphers = jmxEncryptionOptions.cipherSuitesArray();
protocols = jmxEncryptionOptions.acceptedProtocolsArray();
sslContext = jmxEncryptionOptions.sslContextFactoryInstance
.createJSSESslContext(jmxEncryptionOptions.getClientAuth());
configureSslClientSocketFactory(env, serverAddress); configureSslClientSocketFactory(env, serverAddress);
configureSslServerSocketFactory(env, serverAddress, ciphers, protocols, requireClientAuth, sslContext); configureSslServerSocketFactory(env, serverAddress, ciphers, protocols, requireClientAuth, sslContext);
} }
else if (localOnly) else if (!serverOptions.remote)
{ {
configureLocalSocketFactories(env, serverAddress); configureLocalSocketFactories(env, serverAddress);
} }
@ -159,19 +113,6 @@ abstract public class AbstractJmxSocketFactory
*/ */
abstract public void configureSslClientSocketFactory(Map<String, Object> env, InetAddress serverAddress); abstract public void configureSslClientSocketFactory(Map<String, Object> env, InetAddress serverAddress);
/**
* Configures SSL based server socket factory based on system config for key/trust stores.
*
* @param env output param containing the configured socket factories
* @param serverAddress the JMX server is bound to
* @param enabledCipherSuites for the SSL communication
* @param enabledProtocols for the SSL communication
* @param needClientAuth {@code true} if it requires the client-auth; {@code false} otherwise
*/
abstract public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress,
String[] enabledCipherSuites, String[] enabledProtocols,
boolean needClientAuth);
/** /**
* Configures SSL based server socket factory based on custom SSLContext. * Configures SSL based server socket factory based on custom SSLContext.
* *
@ -185,24 +126,4 @@ abstract public class AbstractJmxSocketFactory
abstract public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress, abstract public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress,
String[] enabledCipherSuites, String[] enabledProtocols, String[] enabledCipherSuites, String[] enabledProtocols,
boolean needClientAuth, SSLContext sslContext); boolean needClientAuth, SSLContext sslContext);
/**
* Sets the following JMX system properties.
* <pre>
* com.sun.management.jmxremote.ssl=true
* javax.rmi.ssl.client.enabledCipherSuites=&lt;applicable cipher suites provided in the configuration&gt;
* javax.rmi.ssl.client.enabledProtocols=&lt;applicable protocols provided in the configuration&gt;
* </pre>
*
* @param jmxEncryptionOptions for the SSL communication
*/
private void setJmxSystemProperties(EncryptionOptions jmxEncryptionOptions)
{
COM_SUN_MANAGEMENT_JMXREMOTE_SSL.setBoolean(true);
if (jmxEncryptionOptions.getAcceptedProtocols() != null)
JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS.setString(StringUtils.join(jmxEncryptionOptions.getAcceptedProtocols(), ","));
if (jmxEncryptionOptions.cipherSuitesArray() != null)
JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES.setString(StringUtils.join(jmxEncryptionOptions.cipherSuitesArray(), ","));
}
} }

View File

@ -53,15 +53,6 @@ public final class DefaultJmxSocketFactory extends AbstractJmxSocketFactory
env.put("com.sun.jndi.rmi.factory.socket", clientFactory); env.put("com.sun.jndi.rmi.factory.socket", clientFactory);
} }
@Override
public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress, String[] enabledCipherSuites,
String[] enabledProtocols, boolean needClientAuth)
{
SslRMIServerSocketFactory serverFactory = new SslRMIServerSocketFactory(enabledCipherSuites, enabledProtocols, needClientAuth);
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory);
logJmxSslConfig(serverFactory);
}
@Override @Override
public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress, String[] enabledCipherSuites, public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress, String[] enabledCipherSuites,
String[] enabledProtocols, boolean needClientAuth, SSLContext sslContext) String[] enabledProtocols, boolean needClientAuth, SSLContext sslContext)

View File

@ -48,89 +48,91 @@ seed_provider:
- seeds: "127.0.0.1:7012" - seeds: "127.0.0.1:7012"
endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch
dynamic_snitch: true dynamic_snitch: true
jmx_encryption_options: jmx_server_options:
enabled: false enabled: true
cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256] jmx_encryption_options:
accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1] enabled: false
ssl_context_factory: cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]
class_name: org.apache.cassandra.security.PEMBasedSslContextFactory accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1]
parameters: ssl_context_factory:
private_key: | class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
-----BEGIN ENCRYPTED PRIVATE KEY----- parameters:
MIIE6jAcBgoqhkiG9w0BDAEDMA4ECOWqSzq5PBIdAgIFxQSCBMjXsCK30J0aT3J/ private_key: |
g5kcbmevTOY1pIhJGbf5QYYrMUPiuDK2ydxIbiPzoTE4/S+OkCeHhlqwn/YydpBl -----BEGIN ENCRYPTED PRIVATE KEY-----
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
FujZhqbKUDbYAcqTkoQ= RheVmxkef9ErxJiq7hsAsGrSJvMtJuDKIasnD14SOEwD/7jRAq6WdL9VLpxtzlOw
-----END ENCRYPTED PRIVATE KEY----- pWnIl8kUCO3WoaG9Jf+ZTIv2hnxJhaSzYrdXzGPNnaWKhBlwnXJRvQEdrIxZOimP
-----BEGIN CERTIFICATE----- FujZhqbKUDbYAcqTkoQ=
MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV -----END ENCRYPTED PRIVATE KEY-----
bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD -----BEGIN CERTIFICATE-----
VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV
Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh
a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx
FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu
MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw
ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2 MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d
TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy
TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2
YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto
N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA
iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD
IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v
6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh
qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv
HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru 6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG
n3MVF9w= qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa
-----END CERTIFICATE----- HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru
private_key_password: "cassandra" n3MVF9w=
trusted_certificates: | -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- private_key_password: "cassandra"
MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV trusted_certificates: |
bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD -----BEGIN CERTIFICATE-----
VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV
Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh
a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx
FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu
MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw
ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2 MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d
TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy
TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2
YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto
N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA
iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD
IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v
6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh
qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv
HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru 6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG
n3MVF9w= qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa
-----END CERTIFICATE----- HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru
n3MVF9w=
-----END CERTIFICATE-----
incremental_backups: true incremental_backups: true
concurrent_compactors: 4 concurrent_compactors: 4
compaction_throughput: 0MiB/s compaction_throughput: 0MiB/s

View File

@ -48,89 +48,91 @@ seed_provider:
- seeds: "127.0.0.1:7012" - seeds: "127.0.0.1:7012"
endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch
dynamic_snitch: true dynamic_snitch: true
jmx_encryption_options: jmx_server_options:
enabled: true enabled: true
cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256] jmx_encryption_options:
accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1] enabled: true
ssl_context_factory: cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]
class_name: org.apache.cassandra.security.PEMBasedSslContextFactory accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1]
parameters: ssl_context_factory:
private_key: | class_name: org.apache.cassandra.security.PEMBasedSslContextFactory
-----BEGIN ENCRYPTED PRIVATE KEY----- parameters:
MIIE6jAcBgoqhkiG9w0BDAEDMA4ECOWqSzq5PBIdAgIFxQSCBMjXsCK30J0aT3J/ private_key: |
g5kcbmevTOY1pIhJGbf5QYYrMUPiuDK2ydxIbiPzoTE4/S+OkCeHhlqwn/YydpBl -----BEGIN ENCRYPTED PRIVATE KEY-----
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
FujZhqbKUDbYAcqTkoQ= RheVmxkef9ErxJiq7hsAsGrSJvMtJuDKIasnD14SOEwD/7jRAq6WdL9VLpxtzlOw
-----END ENCRYPTED PRIVATE KEY----- pWnIl8kUCO3WoaG9Jf+ZTIv2hnxJhaSzYrdXzGPNnaWKhBlwnXJRvQEdrIxZOimP
-----BEGIN CERTIFICATE----- FujZhqbKUDbYAcqTkoQ=
MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV -----END ENCRYPTED PRIVATE KEY-----
bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD -----BEGIN CERTIFICATE-----
VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV
Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh
a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx
FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu
MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw
ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2 MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d
TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy
TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2
YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto
N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA
iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD
IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v
6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh
qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv
HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru 6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG
n3MVF9w= qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa
-----END CERTIFICATE----- HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru
private_key_password: "cassandra" n3MVF9w=
trusted_certificates: | -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- private_key_password: "cassandra"
MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV trusted_certificates: |
bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD -----BEGIN CERTIFICATE-----
VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh MIIDkTCCAnmgAwIBAgIETxH5JDANBgkqhkiG9w0BAQsFADB5MRAwDgYDVQQGEwdV
Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu VQQKEwdVbmtub3duMRQwEgYDVQQLDAtzc2xfdGVzdGluZzEZMBcGA1UEAxMQQXBh
a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw Y2hlIENhc3NhbmRyYTAeFw0xNjAzMTgyMTI4MDJaFw0xNjA2MTYyMTI4MDJaMHkx
FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A EDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vu
MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d a25vd24xEDAOBgNVBAoTB1Vua25vd24xFDASBgNVBAsMC3NzbF90ZXN0aW5nMRkw
ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy FwYDVQQDExBBcGFjaGUgQ2Fzc2FuZHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2 MIIBCgKCAQEAjkmVX/HS49cS8Hn6o26IGwMIcEV3d7ZhH0GNcx8rnSRd10dU9F6d
TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto ugSjbwGFMcWUQzYNejN6az0Wb8JIQyXRPTWjfgaWTyVGr0bGTnxg6vwhzfI/9jzy
TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA q59xv29OuSY1dxmY31f0pZ9OOw3mabWksjoO2TexfKoxqsRHJ8PrM1f8E84Z4xo2
YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD TJXGzpuIxRkAJ+sVDqKEAhrKAfRYMSgdJ7zRt8VXv9ngjX20uA2m092NcH0Kmeto
N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v TmuWUtK8E/qcN7ULN8xRWNUn4hu6mG6mayk4XliGRqI1VZupqh+MgNqHznuTd0bA
iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh YrQsFPw9HaZ2hvVnJffJ5l7njAekZNOL+wIDAQABoyEwHzAdBgNVHQ4EFgQUcdiD
IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv N6aylI91kAd34Hl2AzWY51QwDQYJKoZIhvcNAQELBQADggEBAG9q29ilUgCWQP5v
6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG iHkZHj10gXGEoMkdfrPBf8grC7dpUcaw1Qfku/DJ7kPvMALeEsmFDk/t78roeNbh
qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa IYBLJlzI1HZN6VPtpWQGsqxltAy5XN9Xw9mQM/tu70ShgsodGmE1UoW6eE5+/GMv
HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru 6Fg+zLuICPvs2cFNmWUvukN5LW146tJSYCv0Q/rCPB3m9dNQ9pBxrzPUHXw4glwG
n3MVF9w= qGnGddXmOC+tSW5lDLLG1BRbKv4zxv3UlrtIjqlJtZb/sQMT6WtG2ihAz7SKOBHa
-----END CERTIFICATE----- HOWUwuPTetWIuJCKP7P4mWWtmSmjLy+BFX5seNEngn3RzJ2L8uuTJQ/88OsqgGru
n3MVF9w=
-----END CERTIFICATE-----
incremental_backups: true incremental_backups: true
concurrent_compactors: 4 concurrent_compactors: 4
compaction_throughput: 0MiB/s compaction_throughput: 0MiB/s

View File

@ -48,14 +48,16 @@ seed_provider:
- seeds: "127.0.0.1:7012" - seeds: "127.0.0.1:7012"
endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch
dynamic_snitch: true dynamic_snitch: true
jmx_encryption_options: jmx_server_options:
enabled: true enabled: true
cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256] jmx_encryption_options:
accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1] enabled: true
keystore: test/conf/cassandra_ssl_test.keystore cipher_suites: [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]
keystore_password: cassandra accepted_protocols: [TLSv1.2,TLSv1.3,TLSv1.1]
truststore: test/conf/cassandra_ssl_test.truststore keystore: test/conf/cassandra_ssl_test.keystore
truststore_password: cassandra keystore_password: cassandra
truststore: test/conf/cassandra_ssl_test.truststore
truststore_password: cassandra
incremental_backups: true incremental_backups: true
concurrent_compactors: 4 concurrent_compactors: 4
compaction_throughput: 0MiB/s compaction_throughput: 0MiB/s

View File

@ -57,16 +57,6 @@ class CollectingSslRMIServerSocketFactoryImpl implements RMICloseableServerSocke
this.sslSocketFactory = sslContext.getSocketFactory(); this.sslSocketFactory = sslContext.getSocketFactory();
} }
public CollectingSslRMIServerSocketFactoryImpl(InetAddress bindAddress, String[] enabledCipherSuites,
String[] enabledProtocols, boolean needClientAuth)
{
this.bindAddress = bindAddress;
this.enabledCipherSuites = enabledCipherSuites;
this.enabledProtocols = enabledProtocols;
this.needClientAuth = needClientAuth;
this.sslSocketFactory = getDefaultSSLSocketFactory();
}
public String[] getEnabledCipherSuites() public String[] getEnabledCipherSuites()
{ {
return enabledCipherSuites; return enabledCipherSuites;

View File

@ -35,6 +35,7 @@ import com.google.common.util.concurrent.Uninterruptibles;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.distributed.api.IInstance; import org.apache.cassandra.distributed.api.IInstance;
import org.apache.cassandra.distributed.api.IInstanceConfig; import org.apache.cassandra.distributed.api.IInstanceConfig;
import org.apache.cassandra.distributed.shared.JMXUtil; import org.apache.cassandra.distributed.shared.JMXUtil;
@ -91,12 +92,24 @@ public class IsolatedJmx
((MBeanWrapper.DelegatingMbeanWrapper) MBeanWrapper.instance).setDelegate(wrapper); ((MBeanWrapper.DelegatingMbeanWrapper) MBeanWrapper.instance).setDelegate(wrapper);
// CASSANDRA-18508: Sensitive JMX SSL configuration options can be easily exposed // CASSANDRA-18508: Sensitive JMX SSL configuration options can be easily exposed
Map<String, Object> encryptionOptionsMap = (Map<String, Object>) config.getParams().get("jmx_encryption_options"); Map<String, Object> jmxServerOptionsMap = (Map<String, Object>) config.getParams().get("jmx_server_options");
EncryptionOptions jmxEncryptionOptions = getJmxEncryptionOptions(encryptionOptionsMap); EncryptionOptions jmxEncryptionOptions;
if (jmxServerOptionsMap == null)
{
JMXServerOptions parsingSystemProperties = JMXServerOptions.createParsingSystemProperties();
jmxEncryptionOptions = parsingSystemProperties.jmx_encryption_options;
jmxEncryptionOptions.applyConfig();
}
else
{
jmxEncryptionOptions = getJmxEncryptionOptions(jmxServerOptionsMap);
}
// Here the `localOnly` is always passed as true as it is for the local isolated JMX testing // Here the `localOnly` is always passed as true as it is for the local isolated JMX testing
// However if the `jmxEncryptionOptions` are provided or JMX SSL configuration is set it will configure // However if the `jmxEncryptionOptions` are provided or JMX SSL configuration is set it will configure
// the socket factories appropriately. // the socket factories appropriately.
Map<String, Object> socketFactories = new IsolatedJmxSocketFactory().configure(addr, true, jmxEncryptionOptions); JMXServerOptions jmxServerOptions = JMXServerOptions.create(true, true, jmxPort, jmxEncryptionOptions);
Map<String, Object> socketFactories = new IsolatedJmxSocketFactory().configure(addr, jmxServerOptions, jmxServerOptions.jmx_encryption_options);
serverSocketFactory = (RMICloseableServerSocketFactory) socketFactories.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE); serverSocketFactory = (RMICloseableServerSocketFactory) socketFactories.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE);
clientSocketFactory = (RMICloseableClientSocketFactory) socketFactories.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE); clientSocketFactory = (RMICloseableClientSocketFactory) socketFactories.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE);
Map<String, Object> env = new HashMap<>(socketFactories); Map<String, Object> env = new HashMap<>(socketFactories);
@ -148,12 +161,17 @@ public class IsolatedJmx
/** /**
* Builds {@code EncryptionOptions} from the map based SSL configuration properties. * Builds {@code EncryptionOptions} from the map based SSL configuration properties.
* *
* @param encryptionOptionsMap of SSL configuration properties * @param jmxServerOptionsMap of jmx server configuration properties
* @return EncryptionOptions built object * @return EncryptionOptions built object
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private EncryptionOptions getJmxEncryptionOptions(Map<String, Object> encryptionOptionsMap) private EncryptionOptions getJmxEncryptionOptions(Map<String, Object> jmxServerOptionsMap)
{ {
if (jmxServerOptionsMap == null)
return null;
Map<String, Object> encryptionOptionsMap = (Map<String, Object>) jmxServerOptionsMap.get("jmx_encryption_options");
if (encryptionOptionsMap == null) if (encryptionOptionsMap == null)
{ {
return null; return null;

View File

@ -22,16 +22,19 @@ import java.net.InetAddress;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.management.remote.rmi.RMIConnectorServer;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.cassandra.config.CassandraRelevantProperties;
import org.apache.cassandra.utils.RMIClientSocketFactoryImpl; import org.apache.cassandra.utils.RMIClientSocketFactoryImpl;
import org.apache.cassandra.utils.jmx.AbstractJmxSocketFactory; import org.apache.cassandra.utils.jmx.AbstractJmxSocketFactory;
import static javax.management.remote.rmi.RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE;
import static javax.management.remote.rmi.RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS;
/** /**
* JMX Socket factory used for the isolated JMX testing. * JMX Socket factory used for the isolated JMX testing.
*/ */
@ -43,35 +46,21 @@ public class IsolatedJmxSocketFactory extends AbstractJmxSocketFactory
public void configureLocalSocketFactories(Map<String, Object> env, InetAddress serverAddress) public void configureLocalSocketFactories(Map<String, Object> env, InetAddress serverAddress)
{ {
CollectingRMIServerSocketFactoryImpl serverSocketFactory = new CollectingRMIServerSocketFactoryImpl(serverAddress); CollectingRMIServerSocketFactoryImpl serverSocketFactory = new CollectingRMIServerSocketFactoryImpl(serverAddress);
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
serverSocketFactory);
RMIClientSocketFactoryImpl clientSocketFactory = new RMIClientSocketFactoryImpl(serverAddress); RMIClientSocketFactoryImpl clientSocketFactory = new RMIClientSocketFactoryImpl(serverAddress);
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, env.put(RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverSocketFactory);
clientSocketFactory); env.put(RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientSocketFactory);
} }
@Override @Override
public void configureSslClientSocketFactory(Map<String, Object> env, InetAddress serverAddress) public void configureSslClientSocketFactory(Map<String, Object> env, InetAddress serverAddress)
{ {
RMISslClientSocketFactoryImpl clientFactory = new RMISslClientSocketFactoryImpl(serverAddress, RMISslClientSocketFactoryImpl clientFactory = new RMISslClientSocketFactoryImpl(serverAddress,
CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES.getString(), JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES.getString(),
CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS.getString()); JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS.getString());
env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientFactory); env.put(RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientFactory);
env.put("com.sun.jndi.rmi.factory.socket", clientFactory); env.put("com.sun.jndi.rmi.factory.socket", clientFactory);
} }
@Override
public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress, String[] enabledCipherSuites,
String[] enabledProtocols, boolean needClientAuth)
{
CollectingSslRMIServerSocketFactoryImpl serverFactory = new CollectingSslRMIServerSocketFactoryImpl(serverAddress,
enabledCipherSuites,
enabledProtocols,
needClientAuth);
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory);
logJmxSslConfig(serverFactory);
}
@Override @Override
public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress, String[] enabledCipherSuites, public void configureSslServerSocketFactory(Map<String, Object> env, InetAddress serverAddress, String[] enabledCipherSuites,
String[] enabledProtocols, boolean needClientAuth, SSLContext sslContext) String[] enabledProtocols, boolean needClientAuth, SSLContext sslContext)
@ -81,7 +70,7 @@ public class IsolatedJmxSocketFactory extends AbstractJmxSocketFactory
enabledProtocols, enabledProtocols,
needClientAuth, needClientAuth,
sslContext); sslContext);
env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory); env.put(RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, serverFactory);
logJmxSslConfig(serverFactory); logJmxSslConfig(serverFactory);
} }

View File

@ -37,7 +37,13 @@ import org.apache.cassandra.distributed.shared.WithProperties;
import org.apache.cassandra.distributed.test.AbstractEncryptionOptionsImpl; import org.apache.cassandra.distributed.test.AbstractEncryptionOptionsImpl;
import org.apache.cassandra.utils.jmx.JMXSslPropertiesUtil; import org.apache.cassandra.utils.jmx.JMXSslPropertiesUtil;
import static java.util.Map.of;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_LOCAL_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES; import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTOREPASSWORD;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTOREPASSWORD;
/** /**
* Distributed tests for JMX SSL configuration via the system properties OR the encryption options in the cassandra.yaml. * Distributed tests for JMX SSL configuration via the system properties OR the encryption options in the cassandra.yaml.
@ -62,7 +68,9 @@ public class JMXSslConfigDistributedTest extends AbstractEncryptionOptionsImpl
.build(); .build();
try (Cluster cluster = builder().withNodes(1).withConfig(c -> { try (Cluster cluster = builder().withNodes(1).withConfig(c -> {
c.with(Feature.JMX).set("jmx_encryption_options", encryptionOptionsMap); c.with(Feature.JMX).set("jmx_server_options", of("enabled",
true,
"jmx_encryption_options", encryptionOptionsMap));
}).start()) }).start())
{ {
Map<String, Object> jmxEnv = new HashMap<>(); Map<String, Object> jmxEnv = new HashMap<>();
@ -85,7 +93,8 @@ public class JMXSslConfigDistributedTest extends AbstractEncryptionOptionsImpl
.build(); .build();
try (Cluster cluster = builder().withNodes(1).withConfig(c -> { try (Cluster cluster = builder().withNodes(1).withConfig(c -> {
c.with(Feature.JMX).set("jmx_encryption_options", encryptionOptionsMap); c.with(Feature.JMX).set("jmx_server_options", of("enabled", true,
"jmx_encryption_options", encryptionOptionsMap));
}).start()) }).start())
{ {
Map<String, Object> jmxEnv = new HashMap<>(); Map<String, Object> jmxEnv = new HashMap<>();
@ -99,8 +108,8 @@ public class JMXSslConfigDistributedTest extends AbstractEncryptionOptionsImpl
public void testSystemSettings() throws Throwable public void testSystemSettings() throws Throwable
{ {
COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES.reset(); COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES.reset();
try (WithProperties withProperties = JMXSslPropertiesUtil.use(true, false, try (WithProperties withProperties = JMXSslPropertiesUtil.use(true, false, "TLSv1.2,TLSv1.3,TLSv1.1")
"TLSv1.2,TLSv1.3,TLSv1.1")) .set(CASSANDRA_JMX_LOCAL_PORT, 7199))
{ {
setKeystoreProperties(withProperties); setKeystoreProperties(withProperties);
try (Cluster cluster = builder().withNodes(1).withConfig(c -> { try (Cluster cluster = builder().withNodes(1).withConfig(c -> {
@ -120,13 +129,11 @@ public class JMXSslConfigDistributedTest extends AbstractEncryptionOptionsImpl
public void testInvalidKeystorePath() throws Throwable public void testInvalidKeystorePath() throws Throwable
{ {
try (Cluster cluster = builder().withNodes(1).withConfig(c -> { try (Cluster cluster = builder().withNodes(1).withConfig(c -> {
c.with(Feature.JMX).set("jmx_encryption_options", c.with(Feature.JMX).set("jmx_server_options", of("enabled", true,
ImmutableMap.<String, Object>builder() "jmx_encryption_options", of("enabled", true,
.put("enabled", true) "keystore", "/path/to/bad/keystore/that/should/not/exist",
.put("keystore", "/path/to/bad/keystore/that/should/not/exist") "keystore_password", "cassandra",
.put("keystore_password", "cassandra") "accepted_protocols", Arrays.asList("TLSv1.2", "TLSv1.3", "TLSv1.1"))));
.put("accepted_protocols", Arrays.asList("TLSv1.2", "TLSv1.3", "TLSv1.1"))
.build());
}).createWithoutStarting()) }).createWithoutStarting())
{ {
assertCannotStartDueToConfigurationException(cluster); assertCannotStartDueToConfigurationException(cluster);
@ -141,12 +148,11 @@ public class JMXSslConfigDistributedTest extends AbstractEncryptionOptionsImpl
public void testDisabledEncryptionOptions() throws Throwable public void testDisabledEncryptionOptions() throws Throwable
{ {
try (Cluster cluster = builder().withNodes(1).withConfig(c -> { try (Cluster cluster = builder().withNodes(1).withConfig(c -> {
c.with(Feature.JMX).set("jmx_encryption_options", c.with(Feature.JMX).set("jmx_server_options", of("enabled", true,
ImmutableMap.builder() "jmx_encryption_options",
.put("enabled", false) of("enabled", false,
.put("keystore", "/path/to/bad/keystore/that/should/not/exist") "keystore", "/path/to/bad/keystore/that/should/not/exist",
.put("keystore_password", "cassandra") "keystore_password", "cassandra")));
.build());
}).start()) }).start())
{ {
JMXTestsUtil.testAllValidGetters(cluster, null); JMXTestsUtil.testAllValidGetters(cluster, null);
@ -155,10 +161,10 @@ public class JMXSslConfigDistributedTest extends AbstractEncryptionOptionsImpl
private void setKeystoreProperties(WithProperties properties) private void setKeystoreProperties(WithProperties properties)
{ {
properties.with("javax.net.ssl.trustStore", (String) validFileBasedKeystores.get("truststore"), properties.with(JAVAX_NET_SSL_TRUSTSTORE.getKey(), (String) validFileBasedKeystores.get("truststore"),
"javax.net.ssl.trustStorePassword", (String) validFileBasedKeystores.get("truststore_password"), JAVAX_NET_SSL_TRUSTSTOREPASSWORD.getKey(), (String) validFileBasedKeystores.get("truststore_password"),
"javax.net.ssl.keyStore", (String) validFileBasedKeystores.get("keystore"), JAVAX_NET_SSL_KEYSTORE.getKey(), (String) validFileBasedKeystores.get("keystore"),
"javax.net.ssl.keyStorePassword", (String) validFileBasedKeystores.get("keystore_password")); JAVAX_NET_SSL_KEYSTOREPASSWORD.getKey(), (String) validFileBasedKeystores.get("keystore_password"));
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -1,4 +1,4 @@
// Delegates authentication to a stub login module, hardcoded to authenticate as a particular user - see JMXAuthTest // Delegates authentication to a stub login module, hardcoded to authenticate as a particular user - see JMXAuthTest
TestLogin { TestLogin {
org.apache.cassandra.auth.jmx.JMXAuthTest$StubLoginModule REQUIRED role_name=test_role; org.apache.cassandra.auth.jmx.AbstractJMXAuthTest$StubLoginModule REQUIRED role_name=test_role;
}; };

View File

@ -19,14 +19,16 @@
package org.apache.cassandra.auth.jmx; package org.apache.cassandra.auth.jmx;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.file.Paths;
import java.rmi.server.RMISocketFactory; import java.rmi.server.RMISocketFactory;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.management.JMX; import javax.management.JMX;
import javax.management.MBeanServerConnection; import javax.management.MBeanServerConnection;
import javax.management.ObjectName; import javax.management.ObjectName;
import javax.management.remote.*; import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXServiceURL;
import javax.security.auth.Subject; import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
@ -34,76 +36,35 @@ import javax.security.auth.spi.LoginModule;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.apache.cassandra.auth.*; import org.apache.cassandra.auth.AuthenticatedUser;
import org.apache.cassandra.auth.CassandraPrincipal;
import org.apache.cassandra.auth.IAuthorizer;
import org.apache.cassandra.auth.JMXResource;
import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.auth.RoleResource;
import org.apache.cassandra.auth.StubAuthorizer;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.ColumnFamilyStoreMBean; import org.apache.cassandra.db.ColumnFamilyStoreMBean;
import org.apache.cassandra.utils.JMXServerUtils; import org.apache.cassandra.utils.JMXServerUtils;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_AUTHORIZER;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_LOGIN_CONFIG;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_SECURITY_AUTH_LOGIN_CONFIG;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
public class JMXAuthTest extends CQLTester @Ignore
public abstract class AbstractJMXAuthTest extends CQLTester
{ {
private static JMXConnectorServer jmxServer; private static JMXConnectorServer jmxServer;
private static MBeanServerConnection connection; private static MBeanServerConnection connection;
private RoleResource role; private RoleResource role;
private String tableName; private String tableName;
private JMXResource tableMBean; private JMXResource tableMBean;
@FunctionalInterface
private interface MBeanAction
{
void execute();
}
@BeforeClass
public static void setupClass() throws Exception
{
setupAuthorizer();
setupJMXServer();
}
private static void setupAuthorizer()
{
try
{
IAuthorizer authorizer = new StubAuthorizer();
Field authorizerField = DatabaseDescriptor.class.getDeclaredField("authorizer");
authorizerField.setAccessible(true);
authorizerField.set(null, authorizer);
DatabaseDescriptor.setPermissionsValidity(0);
}
catch (IllegalAccessException | NoSuchFieldException e)
{
throw new RuntimeException(e);
}
}
private static void setupJMXServer() throws Exception
{
String config = Paths.get(ClassLoader.getSystemResource("auth/cassandra-test-jaas.conf").toURI()).toString();
COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE.setBoolean(true);
JAVA_SECURITY_AUTH_LOGIN_CONFIG.setString(config);
CASSANDRA_JMX_REMOTE_LOGIN_CONFIG.setString("TestLogin");
CASSANDRA_JMX_AUTHORIZER.setString(NoSuperUserAuthorizationProxy.class.getName());
jmxServer = JMXServerUtils.createJMXServer(9999, "localhost", true);
jmxServer.start();
JMXServiceURL jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
Map<String, Object> env = new HashMap<>();
env.put("com.sun.jndi.rmi.factory.socket", RMISocketFactory.getDefaultSocketFactory());
JMXConnector jmxc = JMXConnectorFactory.connect(jmxUrl, env);
connection = jmxc.getMBeanServerConnection();
}
@Before @Before
public void setup() throws Throwable public void setup() throws Throwable
{ {
@ -193,6 +154,42 @@ public class JMXAuthTest extends CQLTester
assertPermissionOnResource(Permission.EXECUTE, JMXResource.root(), proxy::estimateKeys); assertPermissionOnResource(Permission.EXECUTE, JMXResource.root(), proxy::estimateKeys);
} }
protected static void setupJMXServer(JMXServerOptions jmxServerOptions) throws Exception
{
jmxServerOptions.jmx_encryption_options.applyConfig();
jmxServer = JMXServerUtils.createJMXServer(jmxServerOptions, "localhost");
jmxServer.start();
JMXServiceURL jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
Map<String, Object> env = new HashMap<>();
env.put("com.sun.jndi.rmi.factory.socket", RMISocketFactory.getDefaultSocketFactory());
JMXConnector jmxc = JMXConnectorFactory.connect(jmxUrl, env);
connection = jmxc.getMBeanServerConnection();
}
protected static void setupAuthorizer()
{
try
{
IAuthorizer authorizer = new StubAuthorizer();
Field authorizerField = DatabaseDescriptor.class.getDeclaredField("authorizer");
authorizerField.setAccessible(true);
authorizerField.set(null, authorizer);
DatabaseDescriptor.setPermissionsValidity(0);
}
catch (IllegalAccessException | NoSuchFieldException e)
{
throw new RuntimeException(e);
}
}
@FunctionalInterface
private interface MBeanAction
{
void execute();
}
private void assertPermissionOnResource(Permission permission, private void assertPermissionOnResource(Permission permission,
JMXResource resource, JMXResource resource,
MBeanAction action) MBeanAction action)
@ -238,12 +235,14 @@ public class JMXAuthTest extends CQLTester
private CassandraPrincipal principal; private CassandraPrincipal principal;
private Subject subject; private Subject subject;
public StubLoginModule(){} public StubLoginModule()
{
}
public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)
{ {
this.subject = subject; this.subject = subject;
principal = new CassandraPrincipal((String)options.get("role_name")); principal = new CassandraPrincipal((String) options.get("role_name"));
} }
public boolean login() throws LoginException public boolean login() throws LoginException

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.auth.jmx;
import java.nio.file.Paths;
import org.junit.BeforeClass;
import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.config.JMXServerOptions;
/**
* Tests via server options normally constructed in cassandra.yaml.
*/
public class JMXAuthJMXServerOptionsTest extends AbstractJMXAuthTest
{
@BeforeClass
public static void setupClass() throws Exception
{
setupAuthorizer();
setupJMXServer(getJMXServerOptions());
}
private static JMXServerOptions getJMXServerOptions() throws Exception
{
String config = Paths.get(ClassLoader.getSystemResource("auth/cassandra-test-jaas.conf").toURI()).toString();
return new JMXServerOptions(true, false, 9999, 0, true,
new EncryptionOptions(), "TestLogin", config, null, null,
NoSuperUserAuthorizationProxy.class.getName());
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.auth.jmx;
import java.nio.file.Paths;
import org.junit.BeforeClass;
import org.apache.cassandra.config.JMXServerOptions;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_AUTHORIZER;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_LOCAL_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_LOGIN_CONFIG;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVA_SECURITY_AUTH_LOGIN_CONFIG;
/**
* Tests via system properties normally set in cassandra-env.sh
*/
public class JMXAuthSystemPropertiesTest extends AbstractJMXAuthTest
{
@BeforeClass
public static void setupClass() throws Exception
{
setupAuthorizer();
setupJMXServer(getJMXServerOptions());
}
private static JMXServerOptions getJMXServerOptions() throws Exception
{
String config = Paths.get(ClassLoader.getSystemResource("auth/cassandra-test-jaas.conf").toURI()).toString();
COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE.setBoolean(true);
JAVA_SECURITY_AUTH_LOGIN_CONFIG.setString(config);
CASSANDRA_JMX_REMOTE_LOGIN_CONFIG.setString("TestLogin");
CASSANDRA_JMX_AUTHORIZER.setString(NoSuperUserAuthorizationProxy.class.getName());
CASSANDRA_JMX_LOCAL_PORT.setInt(9999);
return JMXServerOptions.createParsingSystemProperties();
}
}

View File

@ -144,6 +144,7 @@ public class DatabaseDescriptorRefTest
"org.apache.cassandra.config.GuardrailsOptions$Config", "org.apache.cassandra.config.GuardrailsOptions$Config",
"org.apache.cassandra.config.GuardrailsOptions$ConsistencyLevels", "org.apache.cassandra.config.GuardrailsOptions$ConsistencyLevels",
"org.apache.cassandra.config.GuardrailsOptions$TableProperties", "org.apache.cassandra.config.GuardrailsOptions$TableProperties",
"org.apache.cassandra.config.JMXServerOptions",
"org.apache.cassandra.config.ParameterizedClass", "org.apache.cassandra.config.ParameterizedClass",
"org.apache.cassandra.config.RepairConfig", "org.apache.cassandra.config.RepairConfig",
"org.apache.cassandra.config.RepairRetrySpec", "org.apache.cassandra.config.RepairRetrySpec",

View File

@ -115,6 +115,7 @@ import org.apache.cassandra.config.Config;
import org.apache.cassandra.config.DataStorageSpec; import org.apache.cassandra.config.DataStorageSpec;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.config.EncryptionOptions;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.config.YamlConfigurationLoader; import org.apache.cassandra.config.YamlConfigurationLoader;
import org.apache.cassandra.cql3.functions.FunctionName; import org.apache.cassandra.cql3.functions.FunctionName;
import org.apache.cassandra.cql3.functions.types.ParseUtils; import org.apache.cassandra.cql3.functions.types.ParseUtils;
@ -190,7 +191,6 @@ import org.apache.cassandra.utils.TimeUUID;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_LOCAL_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_DRIVER_CONNECTION_TIMEOUT_MS; import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_DRIVER_CONNECTION_TIMEOUT_MS;
import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_DRIVER_READ_TIMEOUT_MS; import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_DRIVER_READ_TIMEOUT_MS;
import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_RANDOM_SEED; import static org.apache.cassandra.config.CassandraRelevantProperties.TEST_RANDOM_SEED;
@ -397,7 +397,7 @@ public abstract class CQLTester
InetAddress loopback = InetAddress.getLoopbackAddress(); InetAddress loopback = InetAddress.getLoopbackAddress();
jmxHost = loopback.getHostAddress(); jmxHost = loopback.getHostAddress();
jmxPort = getAutomaticallyAllocatedPort(loopback); jmxPort = getAutomaticallyAllocatedPort(loopback);
jmxServer = JMXServerUtils.createJMXServer(jmxPort, true); jmxServer = JMXServerUtils.createJMXServer(JMXServerOptions.fromDescriptor(true, true, jmxPort));
jmxServer.start(); jmxServer.start();
} }
@ -518,7 +518,7 @@ public abstract class CQLTester
public static List<String> buildNodetoolArgs(List<String> args) public static List<String> buildNodetoolArgs(List<String> args)
{ {
int port = jmxPort == 0 ? CASSANDRA_JMX_LOCAL_PORT.getInt(7199) : jmxPort; int port = jmxPort == 0 ? DatabaseDescriptor.getJmxServerOptions().jmx_port : jmxPort;
String host = jmxHost == null ? "127.0.0.1" : jmxHost; String host = jmxHost == null ? "127.0.0.1" : jmxHost;
List<String> allArgs = new ArrayList<>(); List<String> allArgs = new ArrayList<>();
allArgs.add("bin/nodetool"); allArgs.add("bin/nodetool");

View File

@ -32,6 +32,7 @@ import com.datastax.driver.core.Row;
import org.apache.cassandra.config.Config; import org.apache.cassandra.config.Config;
import org.apache.cassandra.config.DurationSpec; import org.apache.cassandra.config.DurationSpec;
import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.InternodeEncryption; import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions.InternodeEncryption;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.config.ParameterizedClass; import org.apache.cassandra.config.ParameterizedClass;
import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.security.SSLFactory; import org.apache.cassandra.security.SSLFactory;
@ -52,7 +53,8 @@ public class SettingsTableTest extends CQLTester
config = new Config(); config = new Config();
config.client_encryption_options.applyConfig(); config.client_encryption_options.applyConfig();
config.server_encryption_options.applyConfig(); config.server_encryption_options.applyConfig();
config.jmx_encryption_options.applyConfig(); config.jmx_server_options = new JMXServerOptions();
config.jmx_server_options.jmx_encryption_options.applyConfig();
config.sstable_preemptive_open_interval = null; config.sstable_preemptive_open_interval = null;
config.index_summary_resize_interval = null; config.index_summary_resize_interval = null;
config.cache_load_timeout = new DurationSpec.IntSecondsBound(0); config.cache_load_timeout = new DurationSpec.IntSecondsBound(0);

View File

@ -21,9 +21,9 @@ package org.apache.cassandra.tools;
import java.util.Collections; import java.util.Collections;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.junit.Test; import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester; import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.tools.ToolRunner.ToolResult; import org.apache.cassandra.tools.ToolRunner.ToolResult;
@ -35,6 +35,7 @@ public class ToolsEnvsConfigsTest
@Test @Test
public void testJDKEnvInfoDefaultCleaners() public void testJDKEnvInfoDefaultCleaners()
{ {
DatabaseDescriptor.daemonInitialization();
ToolResult tool = ToolRunner.invoke(ImmutableMap.of("_JAVA_OPTIONS", "-Djava.net.preferIPv4Stack=true"), ToolResult tool = ToolRunner.invoke(ImmutableMap.of("_JAVA_OPTIONS", "-Djava.net.preferIPv4Stack=true"),
null, null,
CQLTester.buildNodetoolArgs(Collections.emptyList())); CQLTester.buildNodetoolArgs(Collections.emptyList()));

View File

@ -19,6 +19,7 @@ package org.apache.cassandra.tools.nodetool;
import org.junit.Test; import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.tools.ToolRunner; import org.apache.cassandra.tools.ToolRunner;
public class SjkTest public class SjkTest
@ -26,6 +27,7 @@ public class SjkTest
@Test @Test
public void sjkHelpReturnsRc0() public void sjkHelpReturnsRc0()
{ {
DatabaseDescriptor.daemonInitialization();
ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("sjk", "--help"); ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("sjk", "--help");
tool.assertOnExitCode(); tool.assertOnExitCode();
} }

View File

@ -0,0 +1,67 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.utils.jmx;
import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.distributed.shared.WithProperties;
import org.apache.cassandra.exceptions.ConfigurationException;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_CONFIG;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_JMX_REMOTE_PORT;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_PROTOCOLS;
import static org.apache.cassandra.config.CassandraRelevantProperties.COM_SUN_MANAGEMENT_JMXREMOTE_SSL_NEED_CLIENT_AUTH;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTOREPASSWORD;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTOREPASSWORD;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
public class DuplicateJMXConfigurationTest
{
@Test
public void testDuplicateConfiguration()
{
String enabledProtocols = "TLSv1.2,TLSv1.3,TLSv1.1";
String cipherSuites = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
try (WithProperties props = new WithProperties().set(CASSANDRA_CONFIG, "cassandra-jmx-sslconfig.yaml")
.set(CASSANDRA_JMX_REMOTE_PORT, 7199)
.set(COM_SUN_MANAGEMENT_JMXREMOTE_AUTHENTICATE, true)
.set(COM_SUN_MANAGEMENT_JMXREMOTE_SSL, true)
.set(COM_SUN_MANAGEMENT_JMXREMOTE_SSL_NEED_CLIENT_AUTH, true)
.set(COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_PROTOCOLS, enabledProtocols)
.set(COM_SUN_MANAGEMENT_JMXREMOTE_SSL_ENABLED_CIPHER_SUITES, cipherSuites)
.set(JAVAX_NET_SSL_KEYSTORE, "test/conf/cassandra_ssl_test.keystore")
.set(JAVAX_NET_SSL_TRUSTSTORE, "test/conf/cassandra_ssl_test.truststore")
.set(JAVAX_NET_SSL_KEYSTOREPASSWORD, "cassandra")
.set(JAVAX_NET_SSL_TRUSTSTOREPASSWORD, "cassandra"))
{
assertThatThrownBy(DatabaseDescriptor::daemonInitialization)
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining("Configure either jmx_server_options in cassandra.yaml and comment out configure_jmx function " +
"call in cassandra-env.sh or keep cassandra-env.sh to call configure_jmx function but you have to keep " +
"jmx_server_options in cassandra.yaml commented out.");
}
}
}

View File

@ -30,10 +30,15 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.distributed.shared.WithProperties; import org.apache.cassandra.distributed.shared.WithProperties;
import org.apache.cassandra.utils.JMXServerUtils; import org.apache.cassandra.utils.JMXServerUtils;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_CONFIG; import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_CONFIG;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_KEYSTOREPASSWORD;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTORE;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_NET_SSL_TRUSTSTOREPASSWORD;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES; import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES;
import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS; import static org.apache.cassandra.config.CassandraRelevantProperties.JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS;
@ -68,10 +73,15 @@ public class JMXSslConfigTest
String enabledProtocols = "TLSv1.2,TLSv1.3,TLSv1.1"; String enabledProtocols = "TLSv1.2,TLSv1.3,TLSv1.1";
String cipherSuites = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; String cipherSuites = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
try (WithProperties ignored = JMXSslPropertiesUtil.use(true, true, enabledProtocols, try (WithProperties ignored = JMXSslPropertiesUtil.use(true, true, enabledProtocols, cipherSuites)
cipherSuites)) .set(JAVAX_NET_SSL_KEYSTORE, "test/conf/cassandra_ssl_test.keystore")
.set(JAVAX_NET_SSL_TRUSTSTORE, "test/conf/cassandra_ssl_test.truststore")
.set(JAVAX_NET_SSL_KEYSTOREPASSWORD, "cassandra")
.set(JAVAX_NET_SSL_TRUSTSTOREPASSWORD, "cassandra"))
{ {
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, false); JMXServerOptions options = JMXServerOptions.createParsingSystemProperties();
options.jmx_encryption_options.applyConfig();
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, options);
Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE)); Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE));
Assert.assertTrue("RMI_SERVER_SOCKET_FACTORY must be of SslRMIServerSocketFactory type", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE) instanceof SslRMIServerSocketFactory); Assert.assertTrue("RMI_SERVER_SOCKET_FACTORY must be of SslRMIServerSocketFactory type", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE) instanceof SslRMIServerSocketFactory);
Assert.assertNotNull("ClientSocketFactory must not be null", env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE)); Assert.assertNotNull("ClientSocketFactory must not be null", env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE));
@ -90,7 +100,8 @@ public class JMXSslConfigTest
InetAddress serverAddress = InetAddress.getLoopbackAddress(); InetAddress serverAddress = InetAddress.getLoopbackAddress();
try (WithProperties ignored = JMXSslPropertiesUtil.use(false)) try (WithProperties ignored = JMXSslPropertiesUtil.use(false))
{ {
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, true); JMXServerOptions options = JMXServerOptions.fromDescriptor(true, true, 7199);
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, options);
Assert.assertNull("ClientSocketFactory must be null", env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE)); Assert.assertNull("ClientSocketFactory must be null", env.get(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE));
Assert.assertNull("com.sun.jndi.rmi.factory.socket must not be set in the env", env.get("com.sun.jndi.rmi.factory.socket")); Assert.assertNull("com.sun.jndi.rmi.factory.socket must not be set in the env", env.get("com.sun.jndi.rmi.factory.socket"));

View File

@ -31,9 +31,8 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.distributed.shared.WithProperties; import org.apache.cassandra.distributed.shared.WithProperties;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.utils.JMXServerUtils; import org.apache.cassandra.utils.JMXServerUtils;
import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_CONFIG; import static org.apache.cassandra.config.CassandraRelevantProperties.CASSANDRA_CONFIG;
@ -66,15 +65,15 @@ public class JMXSslConfiguredWithYamlFileOptionsTest
@Test @Test
public void testYamlFileJmxEncryptionOptions() throws SSLException public void testYamlFileJmxEncryptionOptions() throws SSLException
{ {
EncryptionOptions jmxEncryptionOptions = DatabaseDescriptor.getJmxEncryptionOptions(); JMXServerOptions serverOptions = DatabaseDescriptor.getJmxServerOptions();
String expectedProtocols = StringUtils.join(jmxEncryptionOptions.getAcceptedProtocols(), ","); String expectedProtocols = StringUtils.join(serverOptions.jmx_encryption_options.getAcceptedProtocols(), ",");
String expectedCipherSuites = StringUtils.join(jmxEncryptionOptions.cipherSuitesArray(), ","); String expectedCipherSuites = StringUtils.join(serverOptions.jmx_encryption_options.cipherSuitesArray(), ",");
InetAddress serverAddress = InetAddress.getLoopbackAddress(); InetAddress serverAddress = InetAddress.getLoopbackAddress();
try (WithProperties ignored = JMXSslPropertiesUtil.use(false)) try (WithProperties ignored = JMXSslPropertiesUtil.use(false))
{ {
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, false); Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, serverOptions);
Assert.assertTrue("com.sun.management.jmxremote.ssl must be true", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean()); Assert.assertTrue("com.sun.management.jmxremote.ssl must be true", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean());
Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE)); Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE));
Assert.assertTrue("RMI_SERVER_SOCKET_FACTORY must be of JMXSslRMIServerSocketFactory type", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE) instanceof SslRMIServerSocketFactory); Assert.assertTrue("RMI_SERVER_SOCKET_FACTORY must be of JMXSslRMIServerSocketFactory type", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE) instanceof SslRMIServerSocketFactory);
@ -84,21 +83,4 @@ public class JMXSslConfiguredWithYamlFileOptionsTest
Assert.assertEquals("javax.rmi.ssl.client.enabledCipherSuites must match", expectedCipherSuites, JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES.getString()); Assert.assertEquals("javax.rmi.ssl.client.enabledCipherSuites must match", expectedCipherSuites, JAVAX_RMI_SSL_CLIENT_ENABLED_CIPHER_SUITES.getString());
} }
} }
/**
* Tests for the error scenario when the JMX SSL configuration is provided as
* system configuration as well as encryption_options.
*
* @throws SSLException
*/
@Test(expected = ConfigurationException.class)
public void testDuplicateConfig() throws SSLException
{
InetAddress serverAddress = InetAddress.getLoopbackAddress();
try (WithProperties ignored = JMXSslPropertiesUtil.use(true))
{
JMXServerUtils.configureJmxSocketFactories(serverAddress, false);
}
}
} }

View File

@ -29,6 +29,7 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.distributed.shared.WithProperties; import org.apache.cassandra.distributed.shared.WithProperties;
import org.apache.cassandra.utils.JMXServerUtils; import org.apache.cassandra.utils.JMXServerUtils;
@ -71,7 +72,7 @@ public class JMXSslDisabledEncryptionOptionsTest
try (WithProperties ignored = JMXSslPropertiesUtil.use(false)) try (WithProperties ignored = JMXSslPropertiesUtil.use(false))
{ {
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, false); Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, JMXServerOptions.fromDescriptor(true, false, 7199));
Assert.assertTrue("no properties must be set", env.isEmpty()); Assert.assertTrue("no properties must be set", env.isEmpty());
Assert.assertFalse("com.sun.management.jmxremote.ssl must be false", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean()); Assert.assertFalse("com.sun.management.jmxremote.ssl must be false", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean());
Assert.assertNull("javax.rmi.ssl.client.enabledProtocols must be null", JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS.getString()); Assert.assertNull("javax.rmi.ssl.client.enabledProtocols must be null", JAVAX_RMI_SSL_CLIENT_ENABLED_PROTOCOLS.getString());
@ -90,7 +91,7 @@ public class JMXSslDisabledEncryptionOptionsTest
try (WithProperties ignored = JMXSslPropertiesUtil.use(false)) try (WithProperties ignored = JMXSslPropertiesUtil.use(false))
{ {
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, true); Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, JMXServerOptions.fromDescriptor(true, true, 7199));
Assert.assertFalse("com.sun.management.jmxremote.ssl must be false", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean()); Assert.assertFalse("com.sun.management.jmxremote.ssl must be false", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean());
Assert.assertNull("com.sun.jndi.rmi.factory.socket must be null", env.get("com.sun.jndi.rmi.factory.socket")); Assert.assertNull("com.sun.jndi.rmi.factory.socket must be null", env.get("com.sun.jndi.rmi.factory.socket"));
Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE)); Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE));

View File

@ -31,7 +31,7 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.EncryptionOptions; import org.apache.cassandra.config.JMXServerOptions;
import org.apache.cassandra.distributed.shared.WithProperties; import org.apache.cassandra.distributed.shared.WithProperties;
import org.apache.cassandra.utils.JMXServerUtils; import org.apache.cassandra.utils.JMXServerUtils;
@ -63,15 +63,15 @@ public class JMXSslPEMConfigTest
@Test @Test
public void testPEMBasedJmxSslConfig() throws SSLException public void testPEMBasedJmxSslConfig() throws SSLException
{ {
EncryptionOptions jmxEncryptionOptions = DatabaseDescriptor.getJmxEncryptionOptions(); JMXServerOptions serverOptions = DatabaseDescriptor.getJmxServerOptions();
String expectedProtocols = StringUtils.join(jmxEncryptionOptions.getAcceptedProtocols(), ","); String expectedProtocols = StringUtils.join(serverOptions.jmx_encryption_options.getAcceptedProtocols(), ",");
String expectedCipherSuites = StringUtils.join(jmxEncryptionOptions.cipherSuitesArray(), ","); String expectedCipherSuites = StringUtils.join(serverOptions.jmx_encryption_options.cipherSuitesArray(), ",");
InetAddress serverAddress = InetAddress.getLoopbackAddress(); InetAddress serverAddress = InetAddress.getLoopbackAddress();
try (WithProperties ignored = JMXSslPropertiesUtil.use(false)) try (WithProperties ignored = JMXSslPropertiesUtil.use(false))
{ {
Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, false); Map<String, Object> env = JMXServerUtils.configureJmxSocketFactories(serverAddress, serverOptions);
Assert.assertTrue("com.sun.management.jmxremote.ssl must be true", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean()); Assert.assertTrue("com.sun.management.jmxremote.ssl must be true", COM_SUN_MANAGEMENT_JMXREMOTE_SSL.getBoolean());
Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE)); Assert.assertNotNull("ServerSocketFactory must not be null", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE));
Assert.assertTrue("RMI_SERVER_SOCKET_FACTORY must be of JMXSslRMIServerSocketFactory type", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE) instanceof SslRMIServerSocketFactory); Assert.assertTrue("RMI_SERVER_SOCKET_FACTORY must be of JMXSslRMIServerSocketFactory type", env.get(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE) instanceof SslRMIServerSocketFactory);