added ssl support for redis
This commit is contained in:
parent
1bcea1a3fc
commit
b2b5573a61
@ -548,6 +548,14 @@ redis:
|
||||
db: "${REDIS_DB:0}"
|
||||
# db password
|
||||
password: "${REDIS_PASSWORD:}"
|
||||
# ssl config
|
||||
ssl:
|
||||
enabled: "${TB_REDIS_SSL_ENABLED:true}"
|
||||
truststoreLocation: "${TB_REDIS_SSL_TRUSTSTORE_LOCATION:}"
|
||||
truststorePassword: "${TB_REDIS_SSL_TRUSTSTORE_PASSWORD:}"
|
||||
# client authentication could be optional and depends on redis server configuration
|
||||
keystoreLocation: "${TB_REDIS_SSL_KEYSTORE_LOCATION:}"
|
||||
keystorePassword: "${TB_REDIS_SSL_KEYSTORE_PASSWORD:}"
|
||||
# pool config
|
||||
pool_config:
|
||||
maxTotal: "${REDIS_POOL_CONFIG_MAX_TOTAL:128}"
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
package org.thingsboard.server.cache;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cache.CacheManager;
|
||||
@ -35,6 +37,12 @@ import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import java.io.FileInputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -44,6 +52,7 @@ import java.util.List;
|
||||
@ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis")
|
||||
@EnableCaching
|
||||
@Data
|
||||
@Slf4j
|
||||
public abstract class TBRedisCacheConfiguration {
|
||||
|
||||
private static final String COMMA = ",";
|
||||
@ -90,6 +99,9 @@ public abstract class TBRedisCacheConfiguration {
|
||||
return loadFactory();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private TbRedisSslCredentialsConfiguration redisSslCredentials;
|
||||
|
||||
protected abstract JedisConnectionFactory loadFactory();
|
||||
|
||||
/**
|
||||
@ -149,4 +161,33 @@ public abstract class TBRedisCacheConfiguration {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected SSLSocketFactory createSslSocketFactory() {
|
||||
try {
|
||||
KeyStore trustStore = KeyStore.getInstance("jks");
|
||||
trustStore.load(new FileInputStream(redisSslCredentials.getTruststoreLocation()), redisSslCredentials.getTruststorePassword().toCharArray());
|
||||
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
|
||||
trustManagerFactory.init(trustStore);
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
|
||||
// client authentication is optional
|
||||
if (redisSslCredentials.getKeystoreLocation() != null && redisSslCredentials.getKeystorePassword() != null) {
|
||||
KeyStore keyStore = KeyStore.getInstance("pkcs12");
|
||||
keyStore.load(new FileInputStream(redisSslCredentials.getKeystoreLocation()), redisSslCredentials.getKeystorePassword().toCharArray());
|
||||
|
||||
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX");
|
||||
keyManagerFactory.init(keyStore, redisSslCredentials.getKeystorePassword().toCharArray());
|
||||
|
||||
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
|
||||
} else {
|
||||
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
|
||||
}
|
||||
return sslContext.getSocketFactory();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
|
||||
@Configuration
|
||||
@ -39,15 +40,29 @@ public class TBRedisClusterConfiguration extends TBRedisCacheConfiguration {
|
||||
@Value("${redis.password:}")
|
||||
private String password;
|
||||
|
||||
@Value("${redis.ssl.enabled:}")
|
||||
private boolean useSsl;
|
||||
|
||||
public JedisConnectionFactory loadFactory() {
|
||||
RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
|
||||
clusterConfiguration.setClusterNodes(getNodes(clusterNodes));
|
||||
clusterConfiguration.setMaxRedirects(maxRedirects);
|
||||
clusterConfiguration.setPassword(password);
|
||||
if (useDefaultPoolConfig) {
|
||||
return new JedisConnectionFactory(clusterConfiguration);
|
||||
} else {
|
||||
return new JedisConnectionFactory(clusterConfiguration, buildPoolConfig());
|
||||
return new JedisConnectionFactory(clusterConfiguration, buildClientConfig());
|
||||
}
|
||||
|
||||
private JedisClientConfiguration buildClientConfig() {
|
||||
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfigurationBuilder = JedisClientConfiguration.builder();
|
||||
if (!useDefaultPoolConfig) {
|
||||
jedisClientConfigurationBuilder
|
||||
.usePooling()
|
||||
.poolConfig(buildPoolConfig());
|
||||
}
|
||||
if (useSsl) {
|
||||
jedisClientConfigurationBuilder
|
||||
.useSsl()
|
||||
.sslSocketFactory(createSslSocketFactory());
|
||||
}
|
||||
return jedisClientConfigurationBuilder.build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
|
||||
@Configuration
|
||||
@ -42,6 +43,9 @@ public class TBRedisSentinelConfiguration extends TBRedisCacheConfiguration {
|
||||
@Value("${redis.db:}")
|
||||
private Integer database;
|
||||
|
||||
@Value("${redis.ssl.enabled:}")
|
||||
private boolean useSsl;
|
||||
|
||||
@Value("${redis.password:}")
|
||||
private String password;
|
||||
|
||||
@ -52,11 +56,21 @@ public class TBRedisSentinelConfiguration extends TBRedisCacheConfiguration {
|
||||
redisSentinelConfiguration.setSentinelPassword(sentinelPassword);
|
||||
redisSentinelConfiguration.setPassword(password);
|
||||
redisSentinelConfiguration.setDatabase(database);
|
||||
if (useDefaultPoolConfig) {
|
||||
return new JedisConnectionFactory(redisSentinelConfiguration);
|
||||
} else {
|
||||
return new JedisConnectionFactory(redisSentinelConfiguration, buildPoolConfig());
|
||||
}
|
||||
return new JedisConnectionFactory(redisSentinelConfiguration, buildClientConfig());
|
||||
}
|
||||
|
||||
private JedisClientConfiguration buildClientConfig() {
|
||||
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfigurationBuilder = JedisClientConfiguration.builder();
|
||||
if (!useDefaultPoolConfig) {
|
||||
jedisClientConfigurationBuilder
|
||||
.usePooling()
|
||||
.poolConfig(buildPoolConfig());
|
||||
}
|
||||
if (useSsl) {
|
||||
jedisClientConfigurationBuilder
|
||||
.useSsl()
|
||||
.sslSocketFactory(createSslSocketFactory());
|
||||
}
|
||||
return jedisClientConfigurationBuilder.build();
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,32 +57,36 @@ public class TBRedisStandaloneConfiguration extends TBRedisCacheConfiguration {
|
||||
@Value("${redis.password:}")
|
||||
private String password;
|
||||
|
||||
@Value("${redis.ssl.enabled:}")
|
||||
private boolean useSsl;
|
||||
|
||||
public JedisConnectionFactory loadFactory() {
|
||||
RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();
|
||||
standaloneConfiguration.setHostName(host);
|
||||
standaloneConfiguration.setPort(port);
|
||||
standaloneConfiguration.setDatabase(db);
|
||||
standaloneConfiguration.setPassword(password);
|
||||
if (useDefaultClientConfig) {
|
||||
return new JedisConnectionFactory(standaloneConfiguration);
|
||||
} else {
|
||||
return new JedisConnectionFactory(standaloneConfiguration, buildClientConfig());
|
||||
}
|
||||
return new JedisConnectionFactory(standaloneConfiguration, buildClientConfig());
|
||||
}
|
||||
|
||||
private JedisClientConfiguration buildClientConfig() {
|
||||
if (usePoolConfig) {
|
||||
return JedisClientConfiguration.builder()
|
||||
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfigurationBuilder = JedisClientConfiguration.builder();
|
||||
if (!useDefaultClientConfig) {
|
||||
jedisClientConfigurationBuilder
|
||||
.clientName(clientName)
|
||||
.connectTimeout(Duration.ofMillis(connectTimeout))
|
||||
.readTimeout(Duration.ofMillis(readTimeout))
|
||||
.usePooling().poolConfig(buildPoolConfig())
|
||||
.build();
|
||||
} else {
|
||||
return JedisClientConfiguration.builder()
|
||||
.clientName(clientName)
|
||||
.connectTimeout(Duration.ofMillis(connectTimeout))
|
||||
.readTimeout(Duration.ofMillis(readTimeout)).build();
|
||||
.readTimeout(Duration.ofMillis(readTimeout));
|
||||
}
|
||||
if (useSsl) {
|
||||
jedisClientConfigurationBuilder
|
||||
.useSsl()
|
||||
.sslSocketFactory(createSslSocketFactory());
|
||||
}
|
||||
if (usePoolConfig) {
|
||||
jedisClientConfigurationBuilder
|
||||
.usePooling()
|
||||
.poolConfig(buildPoolConfig());
|
||||
}
|
||||
return jedisClientConfigurationBuilder.build();
|
||||
}
|
||||
}
|
||||
36
common/cache/src/main/java/org/thingsboard/server/cache/TbRedisSslCredentialsConfiguration.java
vendored
Normal file
36
common/cache/src/main/java/org/thingsboard/server/cache/TbRedisSslCredentialsConfiguration.java
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright © 2016-2023 The Thingsboard Authors
|
||||
*
|
||||
* Licensed 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.thingsboard.server.cache;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "redis.ssl")
|
||||
@Data
|
||||
public class TbRedisSslCredentialsConfiguration {
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
private String truststoreLocation;
|
||||
|
||||
private String truststorePassword;
|
||||
|
||||
private String keystoreLocation;
|
||||
|
||||
private String keystorePassword;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user