This is an automated email from the ASF dual-hosted git repository.
xiangfu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new c72eadf4a7 add insecure mode when Pinot uses TLS connections (#12525)
c72eadf4a7 is described below
commit c72eadf4a704e6836428605635580de6ff0165a8
Author: Haitao Zhang <[email protected]>
AuthorDate: Mon Mar 11 10:44:46 2024 -0700
add insecure mode when Pinot uses TLS connections (#12525)
* add insecure mode when Pinot uses TLS connections
* add test cases
---
.../broker/broker/helix/BaseBrokerStarter.java | 5 +
.../pinot/common/utils/grpc/GrpcQueryClient.java | 5 +-
.../common/utils/tls/JvmDefaultSslContext.java | 2 +-
.../pinot/common/utils/tls/PinotInsecureMode.java | 38 ++++++
.../pinot/common/utils/tls/RenewableTlsUtils.java | 41 ++++--
.../apache/pinot/common/utils/tls/TlsUtils.java | 11 +-
.../pinot/common/utils/tls/TlsUtilsTest.java | 140 ++++++++++++++++-----
.../pinot/controller/BaseControllerStarter.java | 5 +
.../pinot/core/transport/grpc/GrpcQueryServer.java | 5 +-
.../apache/pinot/core/util/ListenerConfigUtil.java | 5 +-
.../org/apache/pinot/minion/BaseMinionStarter.java | 5 +
.../server/starter/helix/BaseServerStarter.java | 5 +
.../apache/pinot/spi/utils/CommonConstants.java | 3 +
13 files changed, 223 insertions(+), 47 deletions(-)
diff --git
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
index 5b0a254f80..3bf78a56d6 100644
---
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
+++
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
@@ -62,6 +62,7 @@ import org.apache.pinot.common.utils.ServiceStartableUtils;
import org.apache.pinot.common.utils.ServiceStatus;
import org.apache.pinot.common.utils.config.TagNameUtils;
import org.apache.pinot.common.utils.helix.HelixHelper;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
import org.apache.pinot.common.utils.tls.TlsUtils;
import org.apache.pinot.common.version.PinotVersion;
import org.apache.pinot.core.query.executor.sql.SqlQueryExecutor;
@@ -138,6 +139,10 @@ public abstract class BaseBrokerStarter implements
ServiceStartable {
_clusterName = brokerConf.getProperty(Helix.CONFIG_OF_CLUSTER_NAME);
ServiceStartableUtils.applyClusterConfig(_brokerConf, _zkServers,
_clusterName, ServiceRole.BROKER);
+ PinotInsecureMode.setPinotInInsecureMode(
+
Boolean.valueOf(_brokerConf.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+ CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
if (_brokerConf.getProperty(MultiStageQueryRunner.KEY_OF_QUERY_RUNNER_PORT,
MultiStageQueryRunner.DEFAULT_QUERY_RUNNER_PORT) == 0) {
_brokerConf.setProperty(MultiStageQueryRunner.KEY_OF_QUERY_RUNNER_PORT,
NetUtils.findOpenPort());
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 3ba78d98d6..ac05ec70d3 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
@@ -36,6 +36,7 @@ import org.apache.pinot.common.config.GrpcConfig;
import org.apache.pinot.common.config.TlsConfig;
import org.apache.pinot.common.proto.PinotQueryServerGrpc;
import org.apache.pinot.common.proto.Server;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
import org.apache.pinot.common.utils.tls.RenewableTlsUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,7 +74,9 @@ public class GrpcQueryClient {
LOGGER.info("Building gRPC SSL context");
SslContext sslContext =
CLIENT_SSL_CONTEXTS_CACHE.computeIfAbsent(tlsConfig.hashCode(),
tlsConfigHashCode -> {
try {
- SSLFactory sslFactory =
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+ SSLFactory sslFactory =
+
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+ tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
sslFactory.getKeyManagerFactory().ifPresent(sslContextBuilder::keyManager);
sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager);
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
index ecd424ef45..ef678e4391 100644
---
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
+++
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/JvmDefaultSslContext.java
@@ -100,7 +100,7 @@ public class JvmDefaultSslContext {
Optional.ofNullable(System.getProperty(JVM_TRUST_STORE_PASSWORD))
.map(String::trim).filter(StringUtils::isNotBlank).orElse(null);
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(jvmSslFactory,
jvmKeystoreType, jvmKeyStorePath,
- jvmKeystorePassword, jvmTrustStoreType, jvmTrustStorePath,
jvmTrustStorePassword, null, null, false);
+ jvmKeystorePassword, jvmTrustStoreType, jvmTrustStorePath,
jvmTrustStorePassword, null, null, () -> false);
}
_initialized = true;
LOGGER.info("Successfully initialized mvm default SSL context");
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/PinotInsecureMode.java
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/PinotInsecureMode.java
new file mode 100644
index 0000000000..23e57d3b6b
--- /dev/null
+++
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/PinotInsecureMode.java
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.pinot.common.utils.tls;
+
+/**
+ * This class is used to determine if Pinot is running in insecure mode. This
is used to determine if Pinot components
+ * should use trust all CA certificates when using TLS.
+ */
+public class PinotInsecureMode {
+ private static volatile boolean _pinotInInsecureMode = false;
+
+ private PinotInsecureMode() {
+ }
+
+ public static synchronized void setPinotInInsecureMode(boolean
pinotInInsecureMode) {
+ _pinotInInsecureMode = pinotInInsecureMode;
+ }
+
+ public static synchronized boolean isPinotInInsecureMode() {
+ return _pinotInInsecureMode;
+ }
+}
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
index e8cb6140c8..8c50dfaf59 100644
---
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
+++
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/RenewableTlsUtils.java
@@ -20,6 +20,7 @@ package org.apache.pinot.common.utils.tls;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
@@ -68,10 +69,26 @@ public class RenewableTlsUtils {
* @return a {@link SSLFactory} instance with identity material and trust
material swappable
*/
public static SSLFactory
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(TlsConfig tlsConfig) {
- SSLFactory sslFactory = createSSLFactory(tlsConfig);
+ return createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig,
() -> false);
+ }
+
+ /**
+ * 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}
+ * @param insecureModeSupplier a supplier to check if using insecure mode
+ * @return a {@link SSLFactory} instance with identity material and trust
material swappable
+ */
+ public static SSLFactory
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+ TlsConfig tlsConfig, Supplier<Boolean> insecureModeSupplier) {
+ SSLFactory sslFactory = createSSLFactory(tlsConfig,
insecureModeSupplier.get());
if
(TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getKeyStorePath())
&&
TlsUtils.isKeyOrTrustStorePathNullOrHasFileScheme(tlsConfig.getTrustStorePath()))
{
- enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig);
+ enableAutoRenewalFromFileStoreForSSLFactory(sslFactory, tlsConfig,
insecureModeSupplier);
}
return sslFactory;
}
@@ -79,13 +96,14 @@ public class RenewableTlsUtils {
/**
* Create a {@link SSLFactory} instance with identity material and trust
material swappable for a given TlsConfig
* @param tlsConfig {@link TlsConfig}
+ * @param insecureMode if true, trust all certificates
* @return a {@link SSLFactory} instance with identity material and trust
material swappable
*/
- private static SSLFactory createSSLFactory(TlsConfig tlsConfig) {
+ private static SSLFactory createSSLFactory(TlsConfig tlsConfig, boolean
insecureMode) {
return createSSLFactory(
tlsConfig.getKeyStoreType(), tlsConfig.getKeyStorePath(),
tlsConfig.getKeyStorePassword(),
tlsConfig.getTrustStoreType(), tlsConfig.getTrustStorePath(),
tlsConfig.getTrustStorePassword(),
- null, null, true, tlsConfig.isInsecure());
+ null, null, true, tlsConfig.isInsecure() || insecureMode);
}
static SSLFactory createSSLFactory(
@@ -147,18 +165,21 @@ public class RenewableTlsUtils {
* 4. the key store or trust store file changes.
* @param sslFactory the {@link SSLFactory} to enable key manager and trust
manager auto renewal
* @param tlsConfig the {@link TlsConfig} to get the key store and trust
store information
+ * @param insecureModeSupplier a supplier to check if using insecure mode
*/
@VisibleForTesting
- static void enableAutoRenewalFromFileStoreForSSLFactory(SSLFactory
sslFactory, TlsConfig tlsConfig) {
+ static void enableAutoRenewalFromFileStoreForSSLFactory(
+ SSLFactory sslFactory, TlsConfig tlsConfig, Supplier<Boolean>
insecureModeSupplier) {
enableAutoRenewalFromFileStoreForSSLFactory(sslFactory,
tlsConfig.getKeyStoreType(), tlsConfig.getKeyStorePath(),
tlsConfig.getKeyStorePassword(),
tlsConfig.getTrustStoreType(), tlsConfig.getTrustStorePath(),
tlsConfig.getTrustStorePassword(),
- null, null, tlsConfig.isInsecure());
+ null, null, () -> tlsConfig.isInsecure() ||
insecureModeSupplier.get());
}
static void enableAutoRenewalFromFileStoreForSSLFactory(SSLFactory
sslFactory, String keyStoreType,
String keyStorePath, String keyStorePassword, String trustStoreType,
String trustStorePath,
- String trustStorePassword, String sslContextProtocol, SecureRandom
secureRandom, boolean isInsecure) {
+ String trustStorePassword, String sslContextProtocol, SecureRandom
secureRandom,
+ Supplier<Boolean> insecureModeSupplier) {
try {
URL keyStoreURL = keyStorePath == null ? null :
TlsUtils.makeKeyOrTrustStoreUrl(keyStorePath);
URL trustStoreURL = trustStorePath == null ? null :
TlsUtils.makeKeyOrTrustStoreUrl(trustStorePath);
@@ -190,7 +211,7 @@ public class RenewableTlsUtils {
reloadSslFactoryWhenFileStoreChanges(sslFactory,
keyStoreType, keyStorePath, keyStorePassword,
trustStoreType, trustStorePath, trustStorePassword,
- sslContextProtocol, secureRandom, isInsecure);
+ sslContextProtocol, secureRandom, insecureModeSupplier);
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -204,7 +225,7 @@ public class RenewableTlsUtils {
static void reloadSslFactoryWhenFileStoreChanges(SSLFactory baseSslFactory,
String keyStoreType, String keyStorePath, String keyStorePassword,
String trustStoreType, String trustStorePath, String trustStorePassword,
- String sslContextProtocol, SecureRandom secureRandom, boolean isInsecure)
+ String sslContextProtocol, SecureRandom secureRandom, Supplier<Boolean>
insecureModeSupplier)
throws IOException, URISyntaxException, InterruptedException {
LOGGER.info("Enable auto renewal of SSLFactory {} when key store {} or
trust store {} changes",
baseSslFactory, keyStorePath, trustStorePath);
@@ -230,7 +251,7 @@ public class RenewableTlsUtils {
try {
SSLFactory updatedSslFactory =
createSSLFactory(keyStoreType, keyStorePath,
keyStorePassword, trustStoreType, trustStorePath,
- trustStorePassword, sslContextProtocol,
secureRandom, false, isInsecure);
+ trustStorePassword, sslContextProtocol,
secureRandom, false, insecureModeSupplier.get());
SSLFactoryUtils.reload(baseSslFactory, updatedSslFactory);
LOGGER.info("Successfully renewed SSLFactory {} (built
from key store {} and truststore {}) on file"
+ " {} changes", baseSslFactory, keyStorePath,
trustStorePath, changedFile);
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java
b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java
index 8ccf5c0e51..f9c462bd93 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/utils/tls/TlsUtils.java
@@ -233,7 +233,8 @@ public final class TlsUtils {
if (isKeyOrTrustStorePathNullOrHasFileScheme(keyStorePath)
&& isKeyOrTrustStorePathNullOrHasFileScheme(trustStorePath)) {
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(sslFactory,
keyStoreType, keyStorePath,
- keyStorePassword, trustStoreType, trustStorePath,
trustStorePassword, "SSL", secureRandom, false);
+ keyStorePassword, trustStoreType, trustStorePath,
trustStorePassword, "SSL", secureRandom,
+ PinotInsecureMode::isPinotInInsecureMode);
}
// HttpsURLConnection
HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory.getSslSocketFactory());
@@ -300,7 +301,9 @@ public final class TlsUtils {
* @param tlsConfig TLS config
*/
public static SslContext buildClientContext(TlsConfig tlsConfig) {
- SSLFactory sslFactory =
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+ SSLFactory sslFactory =
+
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+ tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
SslContextBuilder sslContextBuilder =
SslContextBuilder.forClient().sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider()));
sslFactory.getKeyManagerFactory().ifPresent(sslContextBuilder::keyManager);
@@ -321,7 +324,9 @@ public final class TlsUtils {
if (tlsConfig.getKeyStorePath() == null) {
throw new IllegalArgumentException("Must provide key store path for
secured server");
}
- SSLFactory sslFactory =
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+ SSLFactory sslFactory =
+
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+ tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
SslContextBuilder sslContextBuilder =
SslContextBuilder.forServer(sslFactory.getKeyManagerFactory().get())
.sslProvider(SslProvider.valueOf(tlsConfig.getSslProvider()));
sslFactory.getTrustManagerFactory().ifPresent(sslContextBuilder::trustManager);
diff --git
a/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
b/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
index 2ae9a12839..ab118b9abd 100644
---
a/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
+++
b/pinot-common/src/test/java/org/apache/pinot/common/utils/tls/TlsUtilsTest.java
@@ -51,15 +51,15 @@ import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import nl.altindag.ssl.SSLFactory;
+import nl.altindag.ssl.trustmanager.HotSwappableX509ExtendedTrustManager;
+import nl.altindag.ssl.trustmanager.UnsafeX509ExtendedTrustManager;
import org.apache.commons.io.FileUtils;
import org.apache.pinot.common.config.TlsConfig;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.*;
/**
@@ -86,7 +86,7 @@ public class TlsUtilsTest {
private static final String TLS_KEYSTORE_FILE_PATH = DEFAULT_TEST_TLS_DIR +
"/" + TLS_KEYSTORE_FILE;
private static final String TLS_TRUSTSTORE_FILE_PATH = DEFAULT_TEST_TLS_DIR
+ "/" + TLS_TRUSTSTORE_FILE;
- @BeforeClass
+ @BeforeMethod
public void setUp()
throws IOException, URISyntaxException {
copyResourceFilesToTempFolder(
@@ -114,7 +114,7 @@ public class TlsUtilsTest {
}
}
- @AfterClass
+ @AfterMethod
public void tearDown() {
FileUtils.deleteQuietly(new File(DEFAULT_TEST_TLS_DIR));
}
@@ -188,29 +188,12 @@ public class TlsUtilsTest {
() -> {
try {
RenewableTlsUtils.reloadSslFactoryWhenFileStoreChanges(sslFactory,
KEYSTORE_TYPE, TLS_KEYSTORE_FILE_PATH,
- PASSWORD, TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD,
"TLS", secureRandom, false);
+ PASSWORD, TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD,
"TLS", secureRandom, () -> false);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
-
- WatchService watchService = FileSystems.getDefault().newWatchService();
- Map<WatchKey, Set<Path>> watchKeyPathMap = new HashMap<>();
- RenewableTlsUtils.registerFile(watchService, watchKeyPathMap,
TLS_KEYSTORE_FILE_PATH);
- RenewableTlsUtils.registerFile(watchService, watchKeyPathMap,
TLS_TRUSTSTORE_FILE_PATH);
-
- // wait for the new thread to start
- Thread.sleep(100);
-
- // update tls files
- copyResourceFilesToTempFolder(
- ImmutableMap.of(TLS_KEYSTORE_UPDATED_FILE, TLS_KEYSTORE_FILE,
TLS_TRUSTSTORE_UPDATED_FILE,
- TLS_TRUSTSTORE_FILE));
-
- // wait for the file change event to be detected
- watchService.take();
- // it will take some time for the thread to be notified and reload the ssl
factory
- Thread.sleep(500);
+ updateTlsFilesAndWaitForSslFactoryToBeRenewed();
executorService.shutdown();
// after tls file update, the returned values should be the same, since
the wrapper is the same
@@ -241,7 +224,8 @@ public class TlsUtilsTest {
tlsConfig.setTrustStorePassword(PASSWORD);
RuntimeException e = null;
try {
-
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(swappableSslFactory,
tlsConfig);
+ RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+ swappableSslFactory, tlsConfig, () -> false);
} catch (RuntimeException ex) {
e = ex;
}
@@ -253,7 +237,8 @@ public class TlsUtilsTest {
tlsConfig.setTrustStorePath("ftp://" + TLS_TRUSTSTORE_FILE_PATH);
e = null;
try {
-
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(swappableSslFactory,
tlsConfig);
+ RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+ swappableSslFactory, tlsConfig, () -> false);
} catch (RuntimeException ex) {
e = ex;
}
@@ -266,7 +251,8 @@ public class TlsUtilsTest {
e = null;
tlsConfig.setTrustStorePath(TLS_TRUSTSTORE_FILE_PATH);
try {
-
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(nonSwappableSslFactory,
tlsConfig);
+ RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+ nonSwappableSslFactory, tlsConfig, () -> false);
} catch (RuntimeException ex) {
e = ex;
}
@@ -276,11 +262,105 @@ public class TlsUtilsTest {
tlsConfig.setKeyStorePath(null);
e = null;
try {
-
RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(nonSwappableSslFactory,
tlsConfig);
+ RenewableTlsUtils.enableAutoRenewalFromFileStoreForSSLFactory(
+ nonSwappableSslFactory, tlsConfig, () -> false);
} catch (RuntimeException ex) {
e = ex;
}
assertEquals(e.getMessage(),
"java.lang.IllegalArgumentException: trust manager of the existing
SSLFactory must be swappable");
}
+
+ @Test
+ public void createSslFactoryInInsecureMode() {
+ SecureRandom secureRandom = new SecureRandom();
+ SSLFactory sslFactory = RenewableTlsUtils.createSSLFactory(KEYSTORE_TYPE,
TLS_KEYSTORE_FILE_PATH, PASSWORD,
+ TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD, "TLS",
secureRandom, false, true);
+
+ X509ExtendedTrustManager x509ExtendedTrustManager =
sslFactory.getTrustManager().get();
+ assertTrue(x509ExtendedTrustManager instanceof
UnsafeX509ExtendedTrustManager);
+ assertEquals(x509ExtendedTrustManager.getAcceptedIssuers().length, 0);
+
+ sslFactory = RenewableTlsUtils.createSSLFactory(KEYSTORE_TYPE,
TLS_KEYSTORE_FILE_PATH, PASSWORD,
+ TRUSTSTORE_TYPE, TLS_TRUSTSTORE_FILE_PATH, PASSWORD, "TLS",
secureRandom, true, true);
+ ensurSslFactoryUseUnsafeTrustManager(sslFactory);
+ }
+
+ @Test
+ public void
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStoresWithPinotSecureMode()
+ throws IOException, URISyntaxException, InterruptedException {
+ TlsConfig tlsConfig = createTlsConfig();
+ SSLFactory sslFactory =
+
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig,
() -> false);
+ ensurSslFactoryUseNormalTrustManager(sslFactory);
+
+ updateTlsFilesAndWaitForSslFactoryToBeRenewed();
+
+ ensurSslFactoryUseNormalTrustManager(sslFactory);
+ }
+
+ @Test
+ public void
createSSLFactoryAndEnableAutoRenewalWhenUsingFileStoresWithPinotInsecureMode()
+ throws IOException, URISyntaxException, InterruptedException {
+ TlsConfig tlsConfig = createTlsConfig();
+ SSLFactory sslFactory =
+
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig,
() -> true);
+ ensurSslFactoryUseUnsafeTrustManager(sslFactory);
+
+ updateTlsFilesAndWaitForSslFactoryToBeRenewed();
+
+ // after tls file update, the ssl factory should still use
UnsafeX509ExtendedTrustManager
+ ensurSslFactoryUseUnsafeTrustManager(sslFactory);
+ }
+
+ private void ensurSslFactoryUseNormalTrustManager(SSLFactory sslFactory) {
+ X509ExtendedTrustManager x509ExtendedTrustManager =
sslFactory.getTrustManager().get();
+ assertTrue(x509ExtendedTrustManager instanceof
HotSwappableX509ExtendedTrustManager);
+ HotSwappableX509ExtendedTrustManager hotSwappableX509ExtendedTrustManager
+ = (HotSwappableX509ExtendedTrustManager) x509ExtendedTrustManager;
+ assertFalse(hotSwappableX509ExtendedTrustManager.getInnerTrustManager()
instanceof UnsafeX509ExtendedTrustManager);
+ assertEquals(x509ExtendedTrustManager.getAcceptedIssuers().length, 1);
+ }
+
+ private void ensurSslFactoryUseUnsafeTrustManager(SSLFactory sslFactory) {
+ X509ExtendedTrustManager x509ExtendedTrustManager =
sslFactory.getTrustManager().get();
+ assertTrue(x509ExtendedTrustManager instanceof
HotSwappableX509ExtendedTrustManager);
+ HotSwappableX509ExtendedTrustManager hotSwappableX509ExtendedTrustManager
+ = (HotSwappableX509ExtendedTrustManager) x509ExtendedTrustManager;
+ assertTrue(hotSwappableX509ExtendedTrustManager.getInnerTrustManager()
instanceof UnsafeX509ExtendedTrustManager);
+ assertEquals(x509ExtendedTrustManager.getAcceptedIssuers().length, 0);
+ }
+
+ private TlsConfig createTlsConfig() {
+ TlsConfig tlsConfig = new TlsConfig();
+ tlsConfig.setKeyStoreType(KEYSTORE_TYPE);
+ tlsConfig.setKeyStorePath(TLS_KEYSTORE_FILE_PATH);
+ tlsConfig.setKeyStorePassword(PASSWORD);
+ tlsConfig.setTrustStoreType(TRUSTSTORE_TYPE);
+ tlsConfig.setTrustStorePath(TLS_TRUSTSTORE_FILE_PATH);
+ tlsConfig.setTrustStorePassword(PASSWORD);
+ tlsConfig.setInsecure(false);
+ return tlsConfig;
+ }
+
+ private void updateTlsFilesAndWaitForSslFactoryToBeRenewed()
+ throws IOException, URISyntaxException, InterruptedException {
+ WatchService watchService = FileSystems.getDefault().newWatchService();
+ Map<WatchKey, Set<Path>> watchKeyPathMap = new HashMap<>();
+ RenewableTlsUtils.registerFile(watchService, watchKeyPathMap,
TLS_KEYSTORE_FILE_PATH);
+ RenewableTlsUtils.registerFile(watchService, watchKeyPathMap,
TLS_TRUSTSTORE_FILE_PATH);
+
+ // wait for the new thread to start
+ Thread.sleep(100);
+
+ // update tls files
+ copyResourceFilesToTempFolder(
+ ImmutableMap.of(TLS_KEYSTORE_UPDATED_FILE, TLS_KEYSTORE_FILE,
TLS_TRUSTSTORE_UPDATED_FILE,
+ TLS_TRUSTSTORE_FILE));
+
+ // wait for the file change event to be detected
+ watchService.take();
+ // it will take some time for the thread to be notified and reload the ssl
factory
+ Thread.sleep(500);
+ }
}
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
index 9d535ab02a..0f071d0895 100644
---
a/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/BaseControllerStarter.java
@@ -78,6 +78,7 @@ import
org.apache.pinot.common.utils.helix.LeadControllerUtils;
import org.apache.pinot.common.utils.log.DummyLogFileServer;
import org.apache.pinot.common.utils.log.LocalLogFileServer;
import org.apache.pinot.common.utils.log.LogFileServer;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
import org.apache.pinot.common.utils.tls.TlsUtils;
import org.apache.pinot.common.version.PinotVersion;
import org.apache.pinot.controller.api.ControllerAdminApiApplication;
@@ -200,6 +201,10 @@ public abstract class BaseControllerStarter implements
ServiceStartable {
_helixClusterName = _config.getHelixClusterName();
ServiceStartableUtils.applyClusterConfig(_config, _helixZkURL,
_helixClusterName, ServiceRole.CONTROLLER);
+ PinotInsecureMode.setPinotInInsecureMode(
+
Boolean.valueOf(_config.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+ CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
setupHelixSystemProperties();
HelixHelper.setMinNumCharsInISToTurnOnCompression(_config.getMinNumCharsInISToTurnOnCompression());
_listenerConfigs = ListenerConfigUtil.buildControllerConfigs(_config);
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 24f952f8c9..bd75b098ac 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
@@ -42,6 +42,7 @@ import org.apache.pinot.common.metrics.ServerMetrics;
import org.apache.pinot.common.proto.PinotQueryServerGrpc;
import org.apache.pinot.common.proto.Server.ServerRequest;
import org.apache.pinot.common.proto.Server.ServerResponse;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
import org.apache.pinot.common.utils.tls.RenewableTlsUtils;
import org.apache.pinot.core.operator.blocks.InstanceResponseBlock;
import org.apache.pinot.core.operator.streaming.StreamingResponseUtils;
@@ -98,7 +99,9 @@ public class GrpcQueryServer extends
PinotQueryServerGrpc.PinotQueryServerImplBa
}
SslContext sslContext =
SERVER_SSL_CONTEXTS_CACHE.computeIfAbsent(tlsConfig.hashCode(),
tlsConfigHashCode -> {
try {
- SSLFactory sslFactory =
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+ SSLFactory sslFactory =
+
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+ tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
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 e617b0d8a6..9a5969c238 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
@@ -38,6 +38,7 @@ import nl.altindag.ssl.SSLFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.pinot.common.config.TlsConfig;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
import org.apache.pinot.common.utils.tls.RenewableTlsUtils;
import org.apache.pinot.common.utils.tls.TlsUtils;
import org.apache.pinot.core.transport.HttpServerThreadPoolConfig;
@@ -264,7 +265,9 @@ public final class ListenerConfigUtil {
}
private static SSLEngineConfigurator buildSSLEngineConfigurator(TlsConfig
tlsConfig) {
- SSLFactory sslFactory =
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(tlsConfig);
+ SSLFactory sslFactory =
+
RenewableTlsUtils.createSSLFactoryAndEnableAutoRenewalWhenUsingFileStores(
+ tlsConfig, PinotInsecureMode::isPinotInInsecureMode);
return new
SSLEngineConfigurator(sslFactory.getSslContext()).setClientMode(false)
.setNeedClientAuth(tlsConfig.isClientAuthEnabled()).setEnabledProtocols(new
String[]{"TLSv1.2"});
}
diff --git
a/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java
b/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java
index b82730288b..cc4e17219c 100644
--- a/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java
+++ b/pinot-minion/src/main/java/org/apache/pinot/minion/BaseMinionStarter.java
@@ -47,6 +47,7 @@ import org.apache.pinot.common.utils.ServiceStartableUtils;
import org.apache.pinot.common.utils.ServiceStatus;
import org.apache.pinot.common.utils.fetcher.SegmentFetcherFactory;
import org.apache.pinot.common.utils.helix.HelixHelper;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
import org.apache.pinot.common.utils.tls.TlsUtils;
import org.apache.pinot.common.version.PinotVersion;
import org.apache.pinot.core.transport.ListenerConfig;
@@ -99,6 +100,10 @@ public abstract class BaseMinionStarter implements
ServiceStartable {
String helixClusterName = _config.getHelixClusterName();
ServiceStartableUtils.applyClusterConfig(_config, zkAddress,
helixClusterName, ServiceRole.MINION);
+ PinotInsecureMode.setPinotInInsecureMode(
+
Boolean.valueOf(_config.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+ CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
setupHelixSystemProperties();
_hostname = _config.getHostName();
_port = _config.getPort();
diff --git
a/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
b/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
index c30e4286aa..f16b326591 100644
---
a/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
+++
b/pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
@@ -61,6 +61,7 @@ import org.apache.pinot.common.utils.ServiceStatus.Status;
import org.apache.pinot.common.utils.config.TagNameUtils;
import org.apache.pinot.common.utils.fetcher.SegmentFetcherFactory;
import org.apache.pinot.common.utils.helix.HelixHelper;
+import org.apache.pinot.common.utils.tls.PinotInsecureMode;
import org.apache.pinot.common.utils.tls.TlsUtils;
import org.apache.pinot.common.version.PinotVersion;
import org.apache.pinot.core.common.datatable.DataTableBuilderFactory;
@@ -152,6 +153,10 @@ public abstract class BaseServerStarter implements
ServiceStartable {
_helixClusterName =
_serverConf.getProperty(CommonConstants.Helix.CONFIG_OF_CLUSTER_NAME);
ServiceStartableUtils.applyClusterConfig(_serverConf, _zkAddress,
_helixClusterName, ServiceRole.SERVER);
+ PinotInsecureMode.setPinotInInsecureMode(
+
Boolean.valueOf(_serverConf.getProperty(CommonConstants.CONFIG_OF_PINOT_INSECURE_MODE,
+ CommonConstants.DEFAULT_PINOT_INSECURE_MODE)));
+
setupHelixSystemProperties();
_listenerConfigs = ListenerConfigUtil.buildServerAdminConfigs(_serverConf);
_hostname = _serverConf.getProperty(Helix.KEY_OF_SERVER_NETTY_HOST,
diff --git
a/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java
b/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java
index ba8d5213b5..f0565c402b 100644
--- a/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java
+++ b/pinot-spi/src/main/java/org/apache/pinot/spi/utils/CommonConstants.java
@@ -54,6 +54,9 @@ public class CommonConstants {
public static final String CONFIG_OF_SWAGGER_RESOURCES_PATH =
"META-INF/resources/webjars/swagger-ui/5.1.0/";
public static final String CONFIG_OF_TIMEZONE = "pinot.timezone";
+ public static final String CONFIG_OF_PINOT_INSECURE_MODE =
"pinot.insecure.mode";
+ public static final String DEFAULT_PINOT_INSECURE_MODE = "false";
+
/**
* The state of the consumer for a given segment
*/
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]