Не удается подключиться к Redis в GCP с поддержкой SSL

# #spring-boot #google-cloud-platform #redis #spring-data-redis #google-cloud-memorystore

Вопрос:

Я использую Spring-boot-starter-redis зависимость для подключения к redis (ниже приведен мой фрагмент из зависимости gradle

 dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    compileOnly 'org.projectlombok:lombok:1.18.20'
    annotationProcessor 'org.projectlombok:lombok:1.18.20'
}
 

Сейчас я переезжаю в GCP, и redis в GCP включен SSL, поэтому я настроил свои свойства spring таким образом

 spring.redis.ssl=true
spring.redis.host=xxxxxx
spring.redis.port=6378
 

Это прекрасно работает, когда я отключаю ssl. Но когда я включаю его, я получаю ошибку ниже.. есть ли способ ввести сертификат PEM в конфигурацию Spring ?

 [Request processing failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to xx.xx.xx.xx:6378] with root cause
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[na:na]
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[na:na]
        at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) ~[na:na]
        at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434) ~[na:na]
        at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306) ~[na:na]
        at java.base/sun.security.validator.Validator.validate(Validator.java:264) ~[na:na]
        at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313) ~[na:na]
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:276) ~[na:na]
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:141) ~[na:na]
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1334) ~[na:na]
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1231) ~[na:na]
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1174) ~[na:na]
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392) ~[na:na]
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443) ~[na:na]
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1074) ~[na:na]
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061) ~[na:na]
        at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1008) ~[na:na]
 

пожалуйста, помогите

Комментарии:

1. Я думаю, что проблема в том, что ваш клиент проверяет SSL-сертификат для Redis, и это не удается. Ваш вопрос неясен, используете ли вы автономный Redis, облачное хранилище памяти или Redis Enterprise.

2. Я использую Хранилище облачной памяти

3. Просмотрите эту ссылку: cloud.google.com/memorystore/docs/redis/in-transit-encryption

4. Я рекомендую изменить один из ваших тегов на google-cloud-memorystore

Ответ №1:

Я подошел к этому так

  • spring-boot-starter-data-redis зависимость по умолчанию использует салат-латук
  • Для подключения к Redis через ssl spring.redis.ssl=true необходимо включить свойство.
  • Если центр сертификации сертификата уникален и не является частью JKS Java, то у вас есть два варианта: либо импортировать ключи в JKS, либо отключить SSL-Verification

Цитируя то, что приведено в документах Google, здесь

Например, салат-латук является популярным Java-клиентом для Redis. В их документации приведен пример подключения с использованием протокола TLS (см. Пример 47). Учитывая, что диспетчер безопасности Java по умолчанию не разрешает самозаверяющие сертификаты, в конструкции URI Redis необходимо указать дополнительную опцию .withVerifyPeer(false)

Я отключил SSL Verification его . Соединение по-прежнему будет осуществляться через SSL, но только для проверки я отключил его, настроив компонент.

Также я не беспокоюсь man-in-the-middle-attack , так как мой Redis открыт только для моего кластера GKE.. Так что это решение отлично сработало для меня

 @Configuration
public class RedisSSLConfiguration {

    @Bean
    @ConditionalOnProperty("spring.redis.ssl")
    public LettuceClientConfigurationBuilderCustomizer builderCustomizer() {
        return builder -> builder.useSsl().disablePeerVerification();
    }
}