我们正在尝试使用 SSL 保护我们的 ElastiCache/Redis 连接。其中一部分是针对 SSL 保护的 Redis docker 容器的 IT 测试。该容器具有所有必要的证书和密钥文件,并且可以毫无问题地与
redis-cli
进行安全连接。
我们创建了一个密钥库和信任库以与我们的 Redisson 客户端一起使用,并按如下方式使用:
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient() throws MalformedURLException {
File truststore = new File("docker/certs/truststore.jks");
File keystore = new File("docker/certs/redis_key_store.p12");
Config config = new Config();
//SingleServerConfig singleServerConfig = config.useSingleServer();
ReplicatedServersConfig elasticacheServersConfig = config.useReplicatedServers();
elasticacheServersConfig
.setSslProtocols(new String[]{"TLSv1.3"})
.setSslCiphers(new String[] { "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256", "TLS_AES_128_GCM_SHA256" })
.setSslEnableEndpointIdentification(false)
.setSslKeystorePassword("password")
.setSslKeystore(keystore.toURI().toURL())
.setSslTruststorePassword("password")
.setSslTruststore(truststore.toURI().toURL())
.setPassword("password");
redisEndpoints()
.stream()
.map(endpoint -> "rediss://" + endpoint.getAddress() + ":" + endpoint.getPort())
.forEach(elasticacheServersConfig::addNodeAddress);
return Redisson.create(config);
}
但是,无法连接,服务器端有这些日志:
Error accepting a client connection: error:0A000416:SSL routines::sslv3 alert certificate unknown
。快速搜索告诉我这是服务器存在的问题,但并不是 100% 清楚这是否是由于证书/密钥造成的(请参阅下面我们为什么这么认为)
当我在 Lettuce 中使用相同的信任库和密钥库时,连接没有问题。其代码是这样的:
@Bean
public RedisConnectionFactory redisConnectionFactory() {
File truststore = new File("docker/certs/truststore.jks");
File keystore = new File("docker/certs/redis_key_store.p12");
var endpoint = new Endpoint().withAddress("127.0.0.1").withPort(63798);
final RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration(endpoint.getAddress(), endpoint.getPort());
redisStandaloneConfiguration.setPassword("password");
final LettuceClientConfiguration.LettuceClientConfigurationBuilder builder = LettuceClientConfiguration
.builder()
.readFrom(ReadFrom.MASTER_PREFERRED)
.commandTimeout(Duration.of(5000, ChronoUnit.MILLIS))
.clientOptions(ClientOptions.builder()
.socketOptions(SocketOptions.builder()
.keepAlive(true)
.build())
.sslOptions(SslOptions.builder()
.keystore(keystore, "password".toCharArray())
.truststore(truststore, "password")
.build())
.build());
builder.useSsl().disablePeerVerification();
return new LettuceConnectionFactory(redisStandaloneConfiguration, builder.build());
}
并使用一些代码,例如:
var connection = redisConnectionFactory.getConnection();
connection.set("test".getBytes(), "1".getBytes());
byte [] g = connection.get("test".getBytes());
connection.close();
明显的区别是,在 Lettuce 中我们可以禁用对等验证。有什么办法可以让这个与Redisson一起工作吗?
不幸的是,我们必须使用Redisson,因为它提供了执行器服务。
您需要设置
sslEnableEndpointIdentification = false
设置。与您为生菜设置的类似disablePeerVerification()