diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy index b7442984f2..33130a4ac3 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy @@ -121,7 +121,8 @@ class GateConfig extends RedisHttpSessionConfiguration { */ @Bean JedisPool jedis(@Value('${redis.connection:redis://localhost:6379}') String connection, - @Value('${redis.timeout:2000}') int timeout) { + @Value('${redis.timeout:2000}') int timeout, + @Value('${redis.certificate_location:#{null}}') String certFilePath) { return new JedisPool(new URI(connection), timeout) } diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/PostConnectionConfiguringJedisConnectionFactory.java b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/PostConnectionConfiguringJedisConnectionFactory.java index 5a155601e8..14d2cdac47 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/PostConnectionConfiguringJedisConnectionFactory.java +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/PostConnectionConfiguringJedisConnectionFactory.java @@ -1,13 +1,19 @@ package com.netflix.spinnaker.gate.config; import com.google.common.base.Splitter; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.net.URI; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; import java.util.List; import java.util.Optional; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; @@ -26,6 +32,7 @@ * *

This Redis pool is used for Spring Boot's session management, not for the rate limit storage. */ +@Slf4j @Component public class PostConnectionConfiguringJedisConnectionFactory extends JedisConnectionFactory { @@ -40,11 +47,14 @@ public class PostConnectionConfiguringJedisConnectionFactory extends JedisConnec private volatile boolean ranConfigureRedisAction; + private String password = "keyStorePass"; + @Autowired public PostConnectionConfiguringJedisConnectionFactory( @Value("${redis.connection:redis://localhost:6379}") String connectionUri, @Value("${redis.timeout:2000}") int timeout, - @ConnectionPostProcessor Optional configureRedisAction) { + @Value(value = "${redis.certificate_location:#{null}}") String certFilePath, + @ConnectionPostProcessor Optional configureRedisAction) throws Exception { this.configureRedisAction = configureRedisAction.orElse(new ConfigureNotifyKeyspaceEventsAction()); @@ -63,6 +73,39 @@ public PostConnectionConfiguringJedisConnectionFactory( if (redisUri.getScheme().equals("rediss")) { setUseSsl(true); + String jksFilePath = "/opsmx/conf/redis-truststore.jks"; + String alias = "redis-truststore"; // An alias to identify the certificate in the keystore + char[] password = this.password.toCharArray(); // Keystore password + + FileInputStream certInputStream = null; + FileOutputStream jksOutputStream = null; + + /** + * If SSL is used then below steps add the certificate necessary for connection to redis as a + * java keystore and then add java keystore file's path as a system property for use in + * connection. + */ + try { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + certInputStream = new FileInputStream(certFilePath); + Certificate certificate = certificateFactory.generateCertificate(certInputStream); + + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(null, password); + keyStore.setCertificateEntry(alias, certificate); + jksOutputStream = new FileOutputStream(jksFilePath); + keyStore.store(jksOutputStream, password); + + log.info("Certificate has been added to the KeyStore successfully."); + } catch (Exception e) { + throw e; + } finally { + certInputStream.close(); + jksOutputStream.close(); + } + + System.setProperty("javax.net.ssl.trustStore", "/opsmx/conf/redis-truststore.jks"); + System.setProperty("javax.net.ssl.trustStorePassword", this.password); } }