mirror of https://github.com/apache/cassandra
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:
parent
54e4688069
commit
2ff41551a6
|
|
@ -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)
|
||||||
|
|
|
||||||
7
NEWS.txt
7
NEWS.txt
|
|
@ -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
|
||||||
|
|
|
||||||
13
bin/nodetool
13
bin/nodetool
|
|
@ -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=""
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
|
|
@ -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. */
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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=<applicable cipher suites provided in the configuration>
|
||||||
|
* javax.rmi.ssl.client.enabledProtocols=<applicable protocols provided in the configuration>
|
||||||
|
* </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, ","));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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<String, Object@gt; containing {@code jmx.remote.rmi.client.socket.factory}, {@code jmx.remote.rmi.server.socket.factory}
|
* @return Map<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
|
||||||
|
|
|
||||||
|
|
@ -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=<applicable cipher suites provided in the configuration>
|
|
||||||
* javax.rmi.ssl.client.enabledProtocols=<applicable protocols provided in the configuration>
|
|
||||||
* </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(), ","));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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()));
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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"));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue