From 99e290861c9685dc604b5b4eac1b77f37406a899 Mon Sep 17 00:00:00 2001 From: Haitao Zhang Date: Tue, 20 Feb 2024 21:24:17 -0800 Subject: [PATCH] make http listener ssl config swappable (#12455) * make http listener ssl config swappable * extract common code as a method --- .../apache/pinot/common/utils/TlsUtils.java | 31 +++++++++++++------ .../common/utils/grpc/GrpcQueryClient.java | 6 +--- .../core/transport/grpc/GrpcQueryServer.java | 6 +--- .../pinot/core/util/ListenerConfigUtil.java | 19 ++---------- 4 files changed, 26 insertions(+), 36 deletions(-) diff --git a/pinot-common/src/main/java/org/apache/pinot/common/utils/TlsUtils.java b/pinot-common/src/main/java/org/apache/pinot/common/utils/TlsUtils.java index 6e46bcd96df3..054c072a135d 100644 --- a/pinot-common/src/main/java/org/apache/pinot/common/utils/TlsUtils.java +++ b/pinot-common/src/main/java/org/apache/pinot/common/utils/TlsUtils.java @@ -317,11 +317,7 @@ private static final class SSLContextHolder { * @param tlsConfig TLS config */ public static SslContext buildClientContext(TlsConfig tlsConfig) { - SSLFactory sslFactory = createSSLFactory(tlsConfig); - if (isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getKeyStorePath()) - && isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getTrustStorePath())) { - enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig); - } + SSLFactory sslFactory = createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig); SslContextBuilder sslContextBuilder = SslContextBuilder.forClient().sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider())); sslFactory.getKeyManagerFactory().ifPresent(sslContextBuilder::keyManager); @@ -342,11 +338,7 @@ public static SslContext buildServerContext(TlsConfig tlsConfig) { if (tlsConfig.getKeyStorePath() == null) { throw new IllegalArgumentException("Must provide key store path for secured server"); } - SSLFactory sslFactory = createSSLFactory(tlsConfig); - if (isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getKeyStorePath()) - && isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getTrustStorePath())) { - enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig); - } + SSLFactory sslFactory = createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig); SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(sslFactory.getKeyManagerFactory().get()) .sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider())); sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager); @@ -502,6 +494,25 @@ static void registerFile(WatchService watchService, Map> key keyPathMap.get(key).add(path.getFileName()); } + /** + * Create a {@link SSLFactory} instance with identity material and trust material swappable for a given TlsConfig, + * and nables auto renewal of the {@link SSLFactory} instance when + * 1. the {@link SSLFactory} is created with a key manager and trust manager swappable + * 2. the key store is null or a local file + * 3. the trust store is null or a local file + * 4. the key store or trust store file changes. + * @param tlsConfig {@link TlsConfig} + * @return a {@link SSLFactory} instance with identity material and trust material swappable + */ + public static SSLFactory createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(TlsConfig tlsConfig) { + SSLFactory sslFactory = createSSLFactory(tlsConfig); + if (isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getKeyStorePath()) + && isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getTrustStorePath())) { + enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig); + } + return sslFactory; + } + /** * Create a {@link SSLFactory} instance with identity material and trust material swappable for a given TlsConfig * @param tlsConfig {@link TlsConfig} diff --git a/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java b/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java index 94621fa176d7..35af62de228d 100644 --- a/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java +++ b/pinot-common/src/main/java/org/apache/pinot/common/utils/grpc/GrpcQueryClient.java @@ -73,11 +73,7 @@ private SslContext buildSslContext(TlsConfig tlsConfig) { LOGGER.info("Building gRPC SSL context"); SslContext sslContext = CLIENT_SSL_CONTEXTS_CACHE.computeIfAbsent(tlsConfig.hashCode(), tlsConfigHashCode -> { try { - SSLFactory sslFactory = TlsUtils.createSSLFactory(tlsConfig); - if (TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getKeyStorePath()) - && TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getTrustStorePath())) { - TlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig); - } + SSLFactory sslFactory = TlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig); SslContextBuilder sslContextBuilder = SslContextBuilder.forClient(); sslFactory.getKeyManagerFactory().ifPresent(sslContextBuilder::keyManager); sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager); diff --git a/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java b/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java index 0b9621e1e140..70f14e10cf8a 100644 --- a/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java +++ b/pinot-core/src/main/java/org/apache/pinot/core/transport/grpc/GrpcQueryServer.java @@ -98,11 +98,7 @@ private SslContext buildGRpcSslContext(TlsConfig tlsConfig) } SslContext sslContext = SERVER_SSL_CONTEXTS_CACHE.computeIfAbsent(tlsConfig.hashCode(), tlsConfigHashCode -> { try { - SSLFactory sslFactory = TlsUtils.createSSLFactory(tlsConfig); - if (TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getKeyStorePath()) - && TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getTrustStorePath())) { - TlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig); - } + SSLFactory sslFactory = TlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig); SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(sslFactory.getKeyManagerFactory().get()) .sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider())); sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager); diff --git a/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java b/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java index a75f62060048..bce2cfe36d87 100644 --- a/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java +++ b/pinot-core/src/main/java/org/apache/pinot/core/util/ListenerConfigUtil.java @@ -34,6 +34,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import nl.altindag.ssl.SSLFactory; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.pinot.common.config.TlsConfig; @@ -44,7 +45,6 @@ import org.apache.pinot.spi.utils.CommonConstants; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.server.NetworkListener; -import org.glassfish.grizzly.ssl.SSLContextConfigurator; import org.glassfish.grizzly.ssl.SSLEngineConfigurator; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder; @@ -263,21 +263,8 @@ public static int findLastTlsPort(List configs, int defaultValue } private static SSLEngineConfigurator buildSSLEngineConfigurator(TlsConfig tlsConfig) { - SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator(); - - if (tlsConfig.getKeyStorePath() != null) { - Preconditions.checkNotNull(tlsConfig.getKeyStorePassword(), "key store password required"); - sslContextConfigurator.setKeyStoreFile(cacheInTempFile(tlsConfig.getKeyStorePath()).getAbsolutePath()); - sslContextConfigurator.setKeyStorePass(tlsConfig.getKeyStorePassword()); - } - - if (tlsConfig.getTrustStorePath() != null) { - Preconditions.checkNotNull(tlsConfig.getKeyStorePassword(), "trust store password required"); - sslContextConfigurator.setTrustStoreFile(cacheInTempFile(tlsConfig.getTrustStorePath()).getAbsolutePath()); - sslContextConfigurator.setTrustStorePass(tlsConfig.getTrustStorePassword()); - } - - return new SSLEngineConfigurator(sslContextConfigurator).setClientMode(false) + SSLFactory sslFactory = TlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig); + return new SSLEngineConfigurator(sslFactory.getSslContext()).setClientMode(false) .setNeedClientAuth(tlsConfig.isClientAuthEnabled()).setEnabledProtocols(new String[]{"TLSv1.2"}); }