From: priyanshu Date: Thu, 14 Mar 2019 15:48:06 +0000 (+0530) Subject: Secure cassandra support on WF BE X-Git-Tag: 1.4.0~2 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=91d1f6c223464dbc62fbca330110c7c46ac2028e;p=sdc%2Fsdc-workflow-designer.git Secure cassandra support on WF BE 1. Added support for secure cassandra on WF BE. 2. By default the SSL is not enabled. 3. updated ReadMe. Change-Id: I2ddb5ebf091fd70c9693e7cc325fb44d03949dd6 Issue-ID: SDC-2194 Signed-off-by: priyanshu --- diff --git a/README.md b/README.md index 87b980cb..a391684b 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,11 @@ messages. You can also see the logs of the initialization container using `docke `docker run -d -e SDC_PROTOCL=http/https -e SDC_ENDPOINT=: -e SDC_USER= -e SDC_PASSWORD= -e CS_HOSTS= -e CS_PORT= -e CS_AUTHENTICATE=true/false -e CS_USER= -e CS_PASSWORD= --e SSL_ENABLED=true/false -e SSL_KEY_PASSWORD= -e SSL_KEYSTORE_PATH= --e SSL_KEYSTORE_TYPE= -e JAVA_OPTIONS= nexus3.onap.org:10001/onap/workflow-backend:latest` +-e CS_SSL_ENABLED=true/false --volume : +-e CS_TRUST_STORE_PATH= -e CS_TRUST_STORE_PASSWORD= +-e SERVER_SSL_ENABLED=true/false -e SERVER_SSL_KEY_PASSWORD= +-e SERVER_SSL_KEYSTORE_PATH= -e SERVER_SSL_KEYSTORE_TYPE= +-e JAVA_OPTIONS= nexus3.onap.org:10001/onap/workflow-backend:latest` ### Environment Variables @@ -123,14 +126,21 @@ assumed if this variable is not specified. - CS_PASSWORD — Cassandra password if CS_AUTHENTICATE is *true*. -- SSL_ENABLED — whether ssl authentication must be used to connect to application. A *false* will be +- CS_SSL_ENABLED — whether ssl authentication must be used to connect to Cassandra. A *false* will be assumed if this variable is not specified. -- SSL_KEY_PASSWORD — SSL key password if SSL_ENABLED is *true*. +- CS_TRUST_STORE_PATH — Cassandra Truststore path if CS_SSL_ENABLED is *true*. -- SSL_KEYSTORE_PATH — SSL Keystore path if SSL_ENABLED is *true*. +- CS_TRUST_STORE_PASSWORD — Cassandra Truststore password if CS_SSL_ENABLED is *true*. -- SSL_KEYSTORE_TYPE — SSL Keystore type if SSL_ENABLED is *true*. +- SERVER_SSL_ENABLED — whether ssl authentication must be used to connect to application. A *false* will be +assumed if this variable is not specified. + +- SERVER_SSL_KEY_PASSWORD — SSL key password if SERVER_SSL_ENABLED is *true*. + +- SERVER_SSL_KEYSTORE_PATH — SSL Keystore path if SERVER_SSL_ENABLED is *true*. + +- SERVER_SSL_KEYSTORE_TYPE — SSL Keystore type if SERVER_SSL_ENABLED is *true*. - JAVA_OPTIONS — optionally, JVM (Java Virtual Machine) arguments. diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java index 23e8643b..700b1b9f 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java @@ -16,23 +16,44 @@ package org.onap.sdc.workflow.server.config; +import com.datastax.driver.core.RemoteEndpointAwareJdkSSLOptions; +import com.datastax.driver.core.SSLOptions; +import java.io.FileInputStream; +import java.security.KeyStore; +import java.security.SecureRandom; import javax.annotation.PostConstruct; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.cassandra.ClusterBuilderCustomizer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ZusammenConfig { - @Value("${zusammen-tenant:workflow}") + @Value("${spring.data.cassandra.keyspace-name}") private String tenant; - @Value("${spring.data.cassandra.contact-points:localhost}") + @Value("${spring.data.cassandra.contact-points}") private String cassandraAddress; - @Value("${spring.data.cassandra.username:}") + @Value("${spring.data.cassandra.username}") private String cassandraUser; - @Value("${spring.data.cassandra.password:}") + @Value("${spring.data.cassandra.password}") private String cassandraPassword; - @Value("${zusammen.cassandra.isAuthenticate:false}") + @Value("${zusammen.cassandra.isAuthenticate}") private String cassandraAuth; + @Value("${spring.data.cassandra.ssl}") + private String cassandraSSL; + @Value("${zusammen.cassandra.trustStorePath}") + private String cassandraTrustStorePath; + @Value("${zusammen.cassandra.trustStorePassword}") + private String cassandraTrustStorePassword; + + private static final String[] CIPHER_SUITES = {"TLS_RSA_WITH_AES_128_CBC_SHA"}; + private static final String KEYSTORE_TYPE = "JKS"; + private static final String SECURE_SOCKET_PROTOCOL = "SSL"; @PostConstruct public void init() { @@ -40,9 +61,36 @@ public class ZusammenConfig { System.setProperty("cassandra.user", cassandraUser); System.setProperty("cassandra.password", cassandraPassword); System.setProperty("cassandra.authenticate", Boolean.toString(Boolean.valueOf(cassandraAuth))); + System.setProperty("cassandra.ssl", Boolean.toString(Boolean.valueOf(cassandraSSL))); + System.setProperty("cassandra.truststore", cassandraTrustStorePath); + System.setProperty("cassandra.truststore.password", cassandraTrustStorePassword); } public String getTenant() { return tenant; } + + @Bean + @ConditionalOnProperty("spring.data.cassandra.ssl") + ClusterBuilderCustomizer clusterBuilderCustomizer() { + SSLOptions sslOptions = RemoteEndpointAwareJdkSSLOptions + .builder() + .withSSLContext(getSslContext()) + .withCipherSuites(CIPHER_SUITES).build(); + return builder -> builder.withSSL(sslOptions); + } + + private SSLContext getSslContext() { + try (FileInputStream tsf = new FileInputStream(cassandraTrustStorePath)) { + SSLContext ctx = SSLContext.getInstance(SECURE_SOCKET_PROTOCOL); + KeyStore ts = KeyStore.getInstance(KEYSTORE_TYPE); + ts.load(tsf, cassandraTrustStorePassword.toCharArray()); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(ts); + ctx.init(null, tmf.getTrustManagers(), new SecureRandom()); + return ctx; + } catch (Exception ex) { + throw new BeanCreationException(ex.getMessage(), ex); + } + } } \ No newline at end of file diff --git a/workflow-designer-be/src/main/resources/application-dev.properties b/workflow-designer-be/src/main/resources/application-dev.properties index 97d81ac3..98eda721 100644 --- a/workflow-designer-be/src/main/resources/application-dev.properties +++ b/workflow-designer-be/src/main/resources/application-dev.properties @@ -17,10 +17,10 @@ server.servlet.context-path=/ http.port=${HTTP_PORT:8080} server.port=${SERVER_PORT:8443} -server.ssl.enabled=${SSL_ENABLED:false} -server.ssl.key-password=${SSL_KEY_PASSWORD:} -server.ssl.key-store=${SSL_KEYSTORE_PATH:} -server.ssl.key-store-type=${SSL_KEYSTORE_TYPE:} +server.ssl.enabled=${SERVER_SSL_ENABLED:false} +server.ssl.key-password=${SERVER_SSL_KEY_PASSWORD:} +server.ssl.key-store=${SERVER_SSL_KEYSTORE_PATH:} +server.ssl.key-store-type=${SERVER_SSL_KEYSTORE_TYPE:} sdc.be.protocol=${SDC_PROTOCOL:} sdc.be.endpoint=${SDC_ENDPOINT:} @@ -34,6 +34,9 @@ spring.data.cassandra.port=${CS_PORT:9042} spring.data.cassandra.username=${CS_USER:} spring.data.cassandra.password=${CS_PASSWORD:} zusammen.cassandra.isAuthenticate=${CS_AUTHENTICATE:false} +spring.data.cassandra.ssl=${CS_SSL_ENABLED:false} +zusammen.cassandra.trustStorePath=${CS_TRUST_STORE_PATH:} +zusammen.cassandra.trustStorePassword=${CS_TRUST_STORE_PASSWORD:} #Actuators management.endpoint.health.show-details=always diff --git a/workflow-designer-be/src/main/resources/application.properties b/workflow-designer-be/src/main/resources/application.properties index 1ff8311a..d189fbb0 100644 --- a/workflow-designer-be/src/main/resources/application.properties +++ b/workflow-designer-be/src/main/resources/application.properties @@ -17,10 +17,10 @@ server.servlet.context-path=/ http.port=${HTTP_PORT:8080} server.port=${SERVER_PORT:8443} -server.ssl.enabled=${SSL_ENABLED:false} -server.ssl.key-password=${SSL_KEY_PASSWORD:} -server.ssl.key-store=${SSL_KEYSTORE_PATH:} -server.ssl.key-store-type=${SSL_KEYSTORE_TYPE:} +server.ssl.enabled=${SERVER_SSL_ENABLED:false} +server.ssl.key-password=${SERVER_SSL_KEY_PASSWORD:} +server.ssl.key-store=${SERVER_SSL_KEYSTORE_PATH:} +server.ssl.key-store-type=${SERVER_SSL_KEYSTORE_TYPE:} sdc.be.protocol=${SDC_PROTOCOL:} sdc.be.endpoint=${SDC_ENDPOINT:} @@ -33,7 +33,10 @@ spring.data.cassandra.keyspace-name=workflow spring.data.cassandra.port=${CS_PORT:9042} spring.data.cassandra.username=${CS_USER:} spring.data.cassandra.password=${CS_PASSWORD:} -zusammen.cassandra.isAuthenticate=${CS_AUTHENTICATE:true} +zusammen.cassandra.isAuthenticate=${CS_AUTHENTICATE:false} +spring.data.cassandra.ssl=${CS_SSL_ENABLED:false} +zusammen.cassandra.trustStorePath=${CS_TRUST_STORE_PATH:} +zusammen.cassandra.trustStorePassword=${CS_TRUST_STORE_PASSWORD:} #Actuators management.endpoint.health.show-details=always