Spring Data Cassandra プロジェクト v1.3.0 を使用していますが、Cassandra クラスター (v2.0.17) の SSL を構成できません。Sprint Data Cassandra のドキュメントによると、DataStax Java Driver (2.0.X) を使用して Cassandra 2.X をサポートしているため、問題はないはずです。cassandra クラスター Bean を初期化する私の Java cassandra 構成は次のとおりです。
@Autowired
private Environment env;
@Bean
public CassandraClusterFactoryBean cluster() {
SSLContext context = null;
try {
context = getSSLContext(
env.getProperty("cassandra.connection.ssl.trustStorePath"),
env.getProperty("cassandra.connection.ssl.trustStorePassword"),
env.getProperty("cassandra.connection.ssl.keyStorePath"),
env.getProperty("cassandra.connection.ssl.keyStorePassword"));
} catch (Exception ex) {
log.warn("Error setting SSL context for Cassandra.");
}
// Default cipher suites supported by C*
String[] cipherSuites = { "TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA" };
CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
cluster.setContactPoints(env.getProperty("cassandra.contactpoints"));
cluster.setPort(Integer.parseInt(env.getProperty("cassandra.port")));
cluster.setSslOptions(new SSLOptions(context, cipherSuites));
cluster.setSslEnabled(true);
return cluster;
}
@Bean
public CassandraMappingContext mappingContext() {
return new BasicCassandraMappingContext();
}
@Bean
public CassandraConverter converter() {
return new MappingCassandraConverter(mappingContext());
}
@Bean
public CassandraSessionFactoryBean session() throws Exception {
CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
session.setCluster(cluster().getObject());
session.setKeyspaceName(env.getProperty("cassandra.keyspace"));
session.setConverter(converter());
session.setSchemaAction(SchemaAction.NONE);
return session;
}
@Bean
public CassandraOperations cassandraTemplate() throws Exception {
return new CassandraTemplate(session().getObject());
}
private static SSLContext getSSLContext(String truststorePath,
String truststorePassword, String keystorePath,
String keystorePassword) throws Exception {
FileInputStream tsf = new FileInputStream(truststorePath);
FileInputStream ksf = new FileInputStream(keystorePath);
SSLContext ctx = SSLContext.getInstance("SSL");
KeyStore ts = KeyStore.getInstance("JKS");
ts.load(tsf, truststorePassword.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ts);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(ksf, keystorePassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
.getDefaultAlgorithm());
kmf.init(ks, keystorePassword.toCharArray());
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
new SecureRandom());
return ctx;
}
SSL コンテキストを設定するための環境プロパティが適切に入力されており、cassandra 構成ファイルで使用されているのと同じキーストアとトラストストアであることを確認しました。以下は、クライアントからノードへの暗号化を有効にすることに関する私の cassandra 構成です。
server_encryption_options:
internode_encryption: all
keystore: /usr/share/ssl/cassandra_client.jks
keystore_password: cassandra
truststore: /usr/share/ssl/cassandra_client_trust.jks
truststore_password: cassandra
# More advanced defaults below:
# protocol: TLS
# algorithm: SunX509
store_type: JKS
cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA] #,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
# require_client_auth: true
# enable or disable client/server encryption.
client_encryption_options:
enabled: true
keystore: /usr/share/ssl/cassandra_client.jks
keystore_password: cassandra
require_client_auth: true
# Set trustore and truststore_password if require_client_auth is true
truststore: /usr/share/ssl/cassandra_client_trust.jks
truststore_password: cassandra
# More advanced defaults below:
# protocol: TLS
# algorithm: SunX509
store_type: JKS
cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA] #,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
クライアント アプリケーションを起動すると、cassandra クラスターの初期化中に次のエラーが表示されます。
17:02:39,330 WARN [org.springframework.web.context.support.XmlWebApplicationContext] (ServerService Thread Pool -- 58) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.cassandra.core.CassandraOperations com.cloudistics.cldtx.mwc.service.CassandraServiceImpl.cassandraOperations; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraTemplate' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.CassandraOperations]: Factory method 'cassandraTemplate' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'session' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Invocation of init method failed; nested exception is com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /127.0.0.1:9042 (com.datastax.driver.core.ConnectionException: [/127.0.0.1:9042] Unexpected error during transport initialization (com.datastax.driver.core.OperationTimedOutException: [/127.0.0.1:9042] Operation timed out)))17:02:39,330 WARN [org.springframework.web.context.support.XmlWebApplicationContext] (ServerService Thread Pool -- 58) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.cassandra.core.CassandraOperations com.cloudistics.cldtx.mwc.service.CassandraServiceImpl.cassandraOperations; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraTemplate' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.CassandraOperations]: Factory method 'cassandraTemplate' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'session' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Invocation of init method failed; nested exception is com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /127.0.0.1:9042 (com.datastax.driver.core.ConnectionException: [/127.0.0.1:9042] Unexpected error during transport initialization (com.datastax.driver.core.OperationTimedOutException: [/127.0.0.1:9042] Operation timed out)))
誰かがこれについて洞察を持っているなら、それは大歓迎です。Datastax でこれらの手順に従って、サーバー証明書を準備し、クライアントからノードへの暗号化を有効にしました。