You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by pe...@apache.org on 2022/05/05 07:07:12 UTC
[pulsar] branch branch-2.9 updated (278531f2f92 -> a118ab953ed)
This is an automated email from the ASF dual-hosted git repository.
penghui pushed a change to branch branch-2.9
in repository https://gitbox.apache.org/repos/asf/pulsar.git
from 278531f2f92 [Broker/Client] Close connection if a ping or pong message cannot be sent (#15382)
new f2bb45b7de8 Use tlsCertRefreshCheckDurationSec instead of 0 for refresh value (#15075)
new c509e4b7982 Add KeyStore support in WebSocket, Function Worker HTTPS Servers (#15084)
new a118ab953ed [improve][broker-web&websocket&proxy&function-worker] Full-support set ssl provider, ciphers and protocols (#13740)
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
conf/broker.conf | 5 +
conf/functions_worker.yml | 40 +++++
conf/proxy.conf | 32 ++++
conf/standalone.conf | 3 +
conf/websocket.conf | 35 ++++
docker/pulsar/scripts/gen-yml-from-env.py | 4 +-
.../apache/pulsar/broker/ServiceConfiguration.java | 23 ++-
.../org/apache/pulsar/jetty}/package-info.java | 2 +-
.../pulsar/jetty/tls/JettySslContextFactory.java | 116 +++++++++++++
.../org/apache/pulsar/jetty/tls}/package-info.java | 2 +-
.../jetty/tls/JettySslContextFactoryTest.java | 174 +++++++++++++++++++
.../JettySslContextFactoryWithKeyStoreTest.java | 193 +++++++++++++++++++++
.../src/test/resources/ssl/jetty_client_key.jks | Bin
.../src/test/resources/ssl/jetty_client_trust.jks | Bin
.../src/test/resources/ssl/jetty_server_key.jks | Bin
.../src/test/resources/ssl/jetty_server_trust.jks | Bin
.../src/test/resources/ssl/my-ca/ca.pem | 0
.../src/test/resources/ssl/my-ca/client-ca.pem | 0
.../src/test/resources/ssl/my-ca/client-key.pem | 0
.../src/test/resources/ssl/my-ca/server-ca.pem | 0
.../src/test/resources/ssl/my-ca/server-key.pem | 0
.../org/apache/pulsar/broker/PulsarService.java | 2 +
.../org/apache/pulsar/broker/web/WebService.java | 16 +-
.../proxy/ProxyPublishConsumeTlsTest.java | 2 +-
pulsar-common/pom.xml | 5 -
.../common/util/DefaultSslContextBuilder.java | 23 ++-
.../apache/pulsar/common/util/SecurityUtility.java | 74 +++-----
.../util/keystoretls/KeyStoreSSLContext.java | 57 +-----
.../SslContextFactoryWithAutoRefresh.java | 66 -------
.../pulsar/functions/worker/WorkerConfig.java | 75 +++++++-
.../worker/WorkerApiV2ResourceConfigTest.java | 18 +-
.../functions/worker/PulsarWorkerService.java | 10 +-
.../pulsar/functions/worker/rest/WorkerServer.java | 39 ++++-
.../pulsar/proxy/server/AdminProxyHandler.java | 14 +-
.../pulsar/proxy/server/ProxyConfiguration.java | 21 +++
.../org/apache/pulsar/proxy/server/WebServer.java | 15 +-
.../pulsar/websocket/service/ProxyServer.java | 40 +++--
.../service/WebSocketProxyConfiguration.java | 63 ++++++-
38 files changed, 934 insertions(+), 235 deletions(-)
copy {pulsar-broker/src/main/java/org/apache/pulsar => pulsar-broker-common/src/main/java/org/apache/pulsar/jetty}/package-info.java (96%)
create mode 100644 pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls/JettySslContextFactory.java
copy {pulsar-broker/src/main/java/org/apache/pulsar => pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls}/package-info.java (95%)
create mode 100644 pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryTest.java
create mode 100644 pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryWithKeyStoreTest.java
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/jetty_client_key.jks (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/jetty_client_trust.jks (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/jetty_server_key.jks (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/jetty_server_trust.jks (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/my-ca/ca.pem (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/my-ca/client-ca.pem (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/my-ca/client-key.pem (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/my-ca/server-ca.pem (100%)
copy {pulsar-common => pulsar-broker-common}/src/test/resources/ssl/my-ca/server-key.pem (100%)
delete mode 100644 pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/SslContextFactoryWithAutoRefresh.java
[pulsar] 02/03: Add KeyStore support in WebSocket, Function Worker HTTPS Servers (#15084)
Posted by pe...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
penghui pushed a commit to branch branch-2.9
in repository https://gitbox.apache.org/repos/asf/pulsar.git
commit c509e4b7982d1401c221346d86fff7beae54fa7d
Author: Michael Marshall <mm...@apache.org>
AuthorDate: Wed Apr 20 22:25:17 2022 -0500
Add KeyStore support in WebSocket, Function Worker HTTPS Servers (#15084)
* Add KeyStore support in WebSocket, Function Worker HTTPS Servers
* Avoid leaking worker config password
* Fix checkstyle
* Replace broker with appropriate text in annotations
* Update python script for new configs
Co-authored-by: Lari Hotari <lh...@apache.org>
We support configuring KeyStores for the broker and the proxy, but not the WebSocket or the Function Worker. By adding this support, users are able to provide KeyStores of type PCKS12 or JKS, which adds flexibility. Further, these KeyStores simplify support for additional algorithms because we rely on the TLS provider to load the KeyStore instead of loading keys ourselves.
* Add `KeyStoreSSLContext`s to the function worker server
* Add `KeyStoreSSLContext`s to the web socket server
* Add configurations to the function worker, the web socket, and the proxy configuration files to simply configuration
* Rely on `toString`, not `ObjectMapper`, when converting the `WorkerConfig` to a string so that we don't log the KeyStore password. (Add a test to verify this logic. Note that we don't want the `ObjectMapper` to ignore the field because we use mappers when converting configuration classes.)
I manually verified that this change works in a minikube cluster. The underlying method named `KeyStoreSSLContext#createSslContextFactory` is already used and tested, so I don't believe we need additional testing on that component.
This change adds a new way to configure TLS in the WebSocket and Function Worker HTTPS Servers. As such, it adds new configuration. This configuration is named in the same way that the broker and proxy configuration is named, so it is consistent.
I've documented the new configuration in the appropriate configuration files.
(cherry picked from commit a4103960a4eb7803af6fabd9fe54a3137f82aff0)
---
conf/broker.conf | 2 +
conf/functions_worker.yml | 40 ++++++++++++
conf/proxy.conf | 27 ++++++++
conf/websocket.conf | 37 +++++++++++
docker/pulsar/scripts/gen-yml-from-env.py | 4 +-
.../apache/pulsar/broker/ServiceConfiguration.java | 2 +-
.../pulsar/functions/worker/WorkerConfig.java | 75 +++++++++++++++++++++-
.../worker/WorkerApiV2ResourceConfigTest.java | 18 +++++-
.../functions/worker/PulsarWorkerService.java | 10 +--
.../pulsar/functions/worker/rest/WorkerServer.java | 33 ++++++++--
.../pulsar/websocket/service/ProxyServer.java | 35 +++++++---
.../service/WebSocketProxyConfiguration.java | 65 +++++++++++++++++--
12 files changed, 314 insertions(+), 34 deletions(-)
diff --git a/conf/broker.conf b/conf/broker.conf
index 849121f9fe8..cfd1e9ef5f9 100644
--- a/conf/broker.conf
+++ b/conf/broker.conf
@@ -600,6 +600,8 @@ tlsRequireTrustedClientCertOnConnect=false
tlsProvider=
### --- KeyStore TLS config variables --- ###
+## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
+
# Enable TLS with KeyStore type configuration in broker.
tlsEnabledWithKeyStore=false
diff --git a/conf/functions_worker.yml b/conf/functions_worker.yml
index b235d600756..06204dfdcfb 100644
--- a/conf/functions_worker.yml
+++ b/conf/functions_worker.yml
@@ -301,6 +301,46 @@ tlsAllowInsecureConnection: false
tlsEnableHostnameVerification: false
# Tls cert refresh duration in seconds (set 0 to check on every new connection)
tlsCertRefreshCheckDurationSec: 300
+# Whether client certificates are required for TLS. Connections are rejected if the client
+# certificate isn't trusted.
+tlsRequireTrustedClientCertOnConnect: false
+
+### --- KeyStore TLS config variables --- ###
+## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
+
+# TLS Provider for KeyStore type
+tlsProvider:
+
+# Enable TLS with KeyStore type configuration in function worker.
+tlsEnabledWithKeyStore: false
+
+# TLS KeyStore type configuration in function worker: JKS, PKCS12
+tlsKeyStoreType: JKS
+
+# TLS KeyStore path in function worker
+tlsKeyStore:
+
+# TLS KeyStore password for function worker
+tlsKeyStorePassword:
+
+# TLS TrustStore type configuration in function worker: JKS, PKCS12
+tlsTrustStoreType: JKS
+
+# TLS TrustStore path in function worker
+tlsTrustStore:
+
+# TLS TrustStore password in function worker, default value is empty password
+tlsTrustStorePassword:
+
+# Specify the tls protocols the function worker's web service will use to negotiate during TLS handshake
+# (a comma-separated list of protocol names).
+# Examples:- [TLSv1.3, TLSv1.2]
+webServiceTlsProtocols:
+
+# Specify the tls cipher the function worker will use to negotiate during TLS Handshake
+# (a comma-separated list of ciphers).
+# Examples:- [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+webServiceTlsCiphers:
########################
# State Management
diff --git a/conf/proxy.conf b/conf/proxy.conf
index fbb009878e3..fbdcad2b2b3 100644
--- a/conf/proxy.conf
+++ b/conf/proxy.conf
@@ -68,6 +68,33 @@ webServicePort=8080
# Port to use to server HTTPS request
webServicePortTls=
+### --- KeyStore TLS config variables --- ###
+## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
+
+# TLS Provider for KeyStore type
+tlsProvider=
+
+# Enable TLS with KeyStore type configuration in proxy.
+tlsEnabledWithKeyStore=false
+
+# TLS KeyStore type configuration in proxy: JKS, PKCS12
+tlsKeyStoreType=JKS
+
+# TLS KeyStore path in proxy
+tlsKeyStore=
+
+# TLS KeyStore password for proxy
+tlsKeyStorePassword=
+
+# TLS TrustStore type configuration in proxy: JKS, PKCS12
+tlsTrustStoreType=JKS
+
+# TLS TrustStore path in proxy
+tlsTrustStore=
+
+# TLS TrustStore password in proxy, default value is empty password
+tlsTrustStorePassword=
+
# Path for the file used to determine the rotation status for the proxy instance when responding
# to service discovery health checks
statusFilePath=
diff --git a/conf/websocket.conf b/conf/websocket.conf
index 814e58753ef..c2a138e7b38 100644
--- a/conf/websocket.conf
+++ b/conf/websocket.conf
@@ -119,6 +119,43 @@ tlsRequireTrustedClientCertOnConnect=false
# Tls cert refresh duration in seconds (set 0 to check on every new connection)
tlsCertRefreshCheckDurationSec=300
+### --- KeyStore TLS config variables --- ###
+## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
+
+# TLS Provider for KeyStore type
+tlsProvider=
+
+# Enable TLS with KeyStore type configuration in WebSocket.
+tlsEnabledWithKeyStore=false
+
+# TLS KeyStore type configuration in WebSocket: JKS, PKCS12
+tlsKeyStoreType=JKS
+
+# TLS KeyStore path in WebSocket
+tlsKeyStore=
+
+# TLS KeyStore password for WebSocket
+tlsKeyStorePassword=
+
+# TLS TrustStore type configuration in WebSocket: JKS, PKCS12
+tlsTrustStoreType=JKS
+
+# TLS TrustStore path in WebSocket
+tlsTrustStore=
+
+# TLS TrustStore password in WebSocket, default value is empty password
+tlsTrustStorePassword=
+
+# Specify the tls protocols the proxy's web service will use to negotiate during TLS handshake
+# (a comma-separated list of protocol names).
+# Examples:- [TLSv1.3, TLSv1.2]
+webServiceTlsProtocols=
+
+# Specify the tls cipher the proxy will use to negotiate during TLS Handshake
+# (a comma-separated list of ciphers).
+# Examples:- [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
+webServiceTlsCiphers=
+
### --- Deprecated config variables --- ###
# Deprecated. Use configurationStoreServers
diff --git a/docker/pulsar/scripts/gen-yml-from-env.py b/docker/pulsar/scripts/gen-yml-from-env.py
index 8aee68b5282..779341d1269 100755
--- a/docker/pulsar/scripts/gen-yml-from-env.py
+++ b/docker/pulsar/scripts/gen-yml-from-env.py
@@ -47,7 +47,9 @@ SET_KEYS = [
'proxyRoles',
'schemaRegistryCompatibilityCheckers',
'brokerClientTlsCiphers',
- 'brokerClientTlsProtocols'
+ 'brokerClientTlsProtocols',
+ 'webServiceTlsCiphers',
+ 'webServiceTlsProtocols',
]
PF_ENV_PREFIX = 'PF_'
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
index dc310d5056f..250d7d41ffa 100644
--- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
@@ -2245,7 +2245,7 @@ public class ServiceConfiguration implements PulsarConfiguration {
@FieldContext(
category = CATEGORY_KEYSTORE_TLS,
- doc = "TLS Provider for Specify the SSL provider for the broker service: \n"
+ doc = "Specify the TLS provider for the broker service: \n"
+ "When using TLS authentication with CACert, the valid value is either OPENSSL or JDK.\n"
+ "When using TLS authentication with KeyStore, available values can be SunJSSE, Conscrypt and etc."
)
diff --git a/pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/worker/WorkerConfig.java b/pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/worker/WorkerConfig.java
index eb40ae3c272..e51e5dfb742 100644
--- a/pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/worker/WorkerConfig.java
+++ b/pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/worker/WorkerConfig.java
@@ -36,9 +36,11 @@ import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-
+import java.util.TreeSet;
import lombok.AccessLevel;
import lombok.Getter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider;
import org.apache.pulsar.common.configuration.Category;
@@ -47,7 +49,6 @@ import org.apache.pulsar.common.configuration.PulsarConfiguration;
import org.apache.pulsar.common.functions.Resources;
import lombok.Data;
-import lombok.experimental.Accessors;
import org.apache.pulsar.common.nar.NarClassLoader;
import org.apache.pulsar.functions.auth.KubernetesSecretsTokenAuthProvider;
import org.apache.pulsar.functions.instance.state.BKStateStoreProviderImpl;
@@ -76,6 +77,8 @@ public class WorkerConfig implements Serializable, PulsarConfiguration {
@Category
private static final String CATEGORY_SECURITY = "Common Security Settings (applied for both worker and client)";
@Category
+ private static final String CATEGORY_KEYSTORE_TLS = "KeyStoreTLS";
+ @Category
private static final String CATEGORY_WORKER_SECURITY = "Worker Security Settings";
@Category
private static final String CATEGORY_CLIENT_SECURITY = "Security settings for clients talking to brokers";
@@ -381,6 +384,74 @@ public class WorkerConfig implements Serializable, PulsarConfiguration {
doc = "Tls cert refresh duration in seconds (set 0 to check on every new connection)"
)
private long tlsCertRefreshCheckDurationSec = 300;
+
+ /**** --- KeyStore TLS config variables. --- ****/
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "Enable TLS with KeyStore type configuration in function worker"
+ )
+ private boolean tlsEnabledWithKeyStore = false;
+
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "Specify the TLS provider for the function worker service: \n"
+ + "When using TLS authentication with CACert, the valid value is either OPENSSL or JDK.\n"
+ + "When using TLS authentication with KeyStore, available values can be SunJSSE, Conscrypt and etc."
+ )
+ private String tlsProvider = null;
+
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "TLS KeyStore type configuration in function worker: JKS, PKCS12"
+ )
+ private String tlsKeyStoreType = "JKS";
+
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "TLS KeyStore path in function worker"
+ )
+ private String tlsKeyStore = null;
+
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "TLS KeyStore password for function worker"
+ )
+ @ToString.Exclude
+ private String tlsKeyStorePassword = null;
+
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "TLS TrustStore type configuration in function worker: JKS, PKCS12"
+ )
+ private String tlsTrustStoreType = "JKS";
+
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "TLS TrustStore path in function worker"
+ )
+ private String tlsTrustStore = null;
+
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "TLS TrustStore password for function worker, null means empty password."
+ )
+ @ToString.Exclude
+ private String tlsTrustStorePassword = null;
+
+ @FieldContext(
+ category = CATEGORY_WORKER_SECURITY,
+ doc = "Specify the tls protocols the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLSv1.3, TLSv1.2]"
+ )
+ private Set<String> webServiceTlsProtocols = new TreeSet<>();
+
+ @FieldContext(
+ category = CATEGORY_WORKER_SECURITY,
+ doc = "Specify the tls cipher the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]"
+ )
+ private Set<String> webServiceTlsCiphers = new TreeSet<>();
+
@FieldContext(
category = CATEGORY_WORKER_SECURITY,
doc = "Enforce authentication"
diff --git a/pulsar-functions/runtime/src/test/java/org/apache/pulsar/functions/worker/WorkerApiV2ResourceConfigTest.java b/pulsar-functions/runtime/src/test/java/org/apache/pulsar/functions/worker/WorkerApiV2ResourceConfigTest.java
index 6cfaea9e242..bf45dd958c8 100644
--- a/pulsar-functions/runtime/src/test/java/org/apache/pulsar/functions/worker/WorkerApiV2ResourceConfigTest.java
+++ b/pulsar-functions/runtime/src/test/java/org/apache/pulsar/functions/worker/WorkerApiV2ResourceConfigTest.java
@@ -25,10 +25,11 @@ import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.net.URL;
+import java.util.Locale;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.pulsar.functions.auth.KubernetesSecretsTokenAuthProvider;
import org.apache.pulsar.functions.runtime.kubernetes.KubernetesRuntimeFactory;
-import org.apache.pulsar.functions.worker.WorkerConfig;
import org.testng.annotations.Test;
/**
@@ -121,4 +122,19 @@ public class WorkerApiV2ResourceConfigTest {
assertTrue(newK8SWc.isFunctionInstanceResourceChangeInLockStep());
}
+
+ @Test
+ public void testPasswordsNotLeakedOnToString() throws Exception {
+ URL yamlUrl = getClass().getClassLoader().getResource("test_worker_config.yml");
+ WorkerConfig wc = WorkerConfig.load(yamlUrl.toURI().getPath());
+ assertFalse(wc.toString().toLowerCase(Locale.ROOT).contains("password"), "Stringified config must not contain password");
+ }
+
+ @Test
+ public void testPasswordsPresentOnObjectMapping() throws Exception {
+ URL yamlUrl = getClass().getClassLoader().getResource("test_worker_config.yml");
+ WorkerConfig wc = WorkerConfig.load(yamlUrl.toURI().getPath());
+ assertTrue((new ObjectMapper().writeValueAsString(wc)).toLowerCase(Locale.ROOT).contains("password"),
+ "ObjectMapper output must include passwords for proper serialization");
+ }
}
diff --git a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/PulsarWorkerService.java b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/PulsarWorkerService.java
index 0f5c402fbce..ef92e85853b 100644
--- a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/PulsarWorkerService.java
+++ b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/PulsarWorkerService.java
@@ -19,9 +19,6 @@
package org.apache.pulsar.functions.worker;
import static org.apache.pulsar.common.policies.data.PoliciesUtil.getBundles;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import io.netty.util.concurrent.DefaultThreadFactory;
@@ -399,12 +396,7 @@ public class PulsarWorkerService implements WorkerService {
workerStatsManager.startupTimeStart();
log.info("/** Starting worker id={} **/", workerConfig.getWorkerId());
-
- try {
- log.info("Worker Configs: {}", new ObjectMapper().writeValueAsString(workerConfig));
- } catch (JsonProcessingException e) {
- log.warn("Failed to print worker configs with error {}", e.getMessage(), e);
- }
+ log.info("Worker Configs: {}", workerConfig);
try {
DistributedLogConfiguration dlogConf = WorkerUtils.getDlogConf(workerConfig);
diff --git a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java
index e5310844424..9747f4b3da4 100644
--- a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java
+++ b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java
@@ -26,6 +26,7 @@ import org.apache.pulsar.broker.web.RateLimitingFilter;
import org.apache.pulsar.broker.web.JettyRequestLogFactory;
import org.apache.pulsar.broker.web.WebExecutorThreadPool;
import org.apache.pulsar.common.util.SecurityUtility;
+import org.apache.pulsar.common.util.keystoretls.KeyStoreSSLContext;
import org.apache.pulsar.functions.worker.WorkerConfig;
import org.apache.pulsar.functions.worker.WorkerService;
import org.apache.pulsar.functions.worker.rest.api.v2.WorkerApiV2Resource;
@@ -122,13 +123,31 @@ public class WorkerServer {
if (this.workerConfig.getTlsEnabled()) {
try {
- SslContextFactory sslCtxFactory = SecurityUtility.createSslContextFactory(
- this.workerConfig.isTlsAllowInsecureConnection(), this.workerConfig.getTlsTrustCertsFilePath(),
- this.workerConfig.getTlsCertificateFilePath(), this.workerConfig.getTlsKeyFilePath(),
- this.workerConfig.isTlsRequireTrustedClientCertOnConnect(),
- true,
- this.workerConfig.getTlsCertRefreshCheckDurationSec());
- httpsConnector = new ServerConnector(server, 1, 1, sslCtxFactory);
+ SslContextFactory sslCtxFactory;
+ if (workerConfig.isTlsEnabledWithKeyStore()) {
+ sslCtxFactory = KeyStoreSSLContext.createSslContextFactory(
+ workerConfig.getTlsProvider(),
+ workerConfig.getTlsKeyStoreType(),
+ workerConfig.getTlsKeyStore(),
+ workerConfig.getTlsKeyStorePassword(),
+ workerConfig.isTlsAllowInsecureConnection(),
+ workerConfig.getTlsTrustStoreType(),
+ workerConfig.getTlsTrustStore(),
+ workerConfig.getTlsTrustStorePassword(),
+ workerConfig.isTlsRequireTrustedClientCertOnConnect(),
+ workerConfig.getTlsCertRefreshCheckDurationSec()
+ );
+ } else {
+ sslCtxFactory = SecurityUtility.createSslContextFactory(
+ workerConfig.isTlsAllowInsecureConnection(),
+ workerConfig.getTlsTrustCertsFilePath(),
+ workerConfig.getTlsCertificateFilePath(),
+ workerConfig.getTlsKeyFilePath(),
+ workerConfig.isTlsRequireTrustedClientCertOnConnect(),
+ true,
+ workerConfig.getTlsCertRefreshCheckDurationSec());
+ }
+ httpsConnector = new ServerConnector(server, sslCtxFactory);
httpsConnector.setPort(this.workerConfig.getWorkerPortTls());
connectors.add(httpsConnector);
} catch (Exception e) {
diff --git a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java
index 3179bb452a9..9cfed156c3f 100644
--- a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java
+++ b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java
@@ -37,6 +37,7 @@ import org.apache.pulsar.broker.web.JettyRequestLogFactory;
import org.apache.pulsar.broker.web.WebExecutorThreadPool;
import org.apache.pulsar.client.api.PulsarClientException;
import org.apache.pulsar.common.util.SecurityUtility;
+import org.apache.pulsar.common.util.keystoretls.KeyStoreSSLContext;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -76,15 +77,31 @@ public class ProxyServer {
// TLS enabled connector
if (config.getWebServicePortTls().isPresent()) {
try {
- SslContextFactory sslCtxFactory = SecurityUtility.createSslContextFactory(
- config.isTlsAllowInsecureConnection(),
- config.getTlsTrustCertsFilePath(),
- config.getTlsCertificateFilePath(),
- config.getTlsKeyFilePath(),
- config.isTlsRequireTrustedClientCertOnConnect(),
- true,
- config.getTlsCertRefreshCheckDurationSec());
- connectorTls = new ServerConnector(server, -1, -1, sslCtxFactory);
+ SslContextFactory sslCtxFactory;
+ if (config.isTlsEnabledWithKeyStore()) {
+ sslCtxFactory = KeyStoreSSLContext.createSslContextFactory(
+ config.getTlsProvider(),
+ config.getTlsKeyStoreType(),
+ config.getTlsKeyStore(),
+ config.getTlsKeyStorePassword(),
+ config.isTlsAllowInsecureConnection(),
+ config.getTlsTrustStoreType(),
+ config.getTlsTrustStore(),
+ config.getTlsTrustStorePassword(),
+ config.isTlsRequireTrustedClientCertOnConnect(),
+ config.getTlsCertRefreshCheckDurationSec()
+ );
+ } else {
+ sslCtxFactory = SecurityUtility.createSslContextFactory(
+ config.isTlsAllowInsecureConnection(),
+ config.getTlsTrustCertsFilePath(),
+ config.getTlsCertificateFilePath(),
+ config.getTlsKeyFilePath(),
+ config.isTlsRequireTrustedClientCertOnConnect(),
+ true,
+ config.getTlsCertRefreshCheckDurationSec());
+ }
+ connectorTls = new ServerConnector(server, sslCtxFactory);
connectorTls.setPort(config.getWebServicePortTls().get());
connectors.add(connectorTls);
} catch (Exception e) {
diff --git a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java
index d37d14208fd..2cd8eb23f7f 100644
--- a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java
+++ b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java
@@ -21,16 +21,16 @@ package org.apache.pulsar.websocket.service;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
-
+import java.util.TreeSet;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
import org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider;
import org.apache.pulsar.common.configuration.FieldContext;
import org.apache.pulsar.common.configuration.PulsarConfiguration;
import com.google.common.collect.Sets;
-import lombok.Getter;
-import lombok.Setter;
-
@Getter
@Setter
public class WebSocketProxyConfiguration implements PulsarConfiguration {
@@ -160,6 +160,63 @@ public class WebSocketProxyConfiguration implements PulsarConfiguration {
@FieldContext(doc = "TLS cert refresh duration (in seconds). 0 means checking every new connection.")
private long tlsCertRefreshCheckDurationSec = 300;
+ /**** --- KeyStore TLS config variables. --- ****/
+ @FieldContext(
+ doc = "Enable TLS with KeyStore type configuration for WebSocket"
+ )
+ private boolean tlsEnabledWithKeyStore = false;
+
+ @FieldContext(
+ doc = "Specify the TLS provider for the WebSocket service: \n"
+ + "When using TLS authentication with CACert, the valid value is either OPENSSL or JDK.\n"
+ + "When using TLS authentication with KeyStore, available values can be SunJSSE, Conscrypt and etc."
+ )
+ private String tlsProvider = null;
+
+ @FieldContext(
+ doc = "TLS KeyStore type configuration in WebSocket: JKS, PKCS12"
+ )
+ private String tlsKeyStoreType = "JKS";
+
+ @FieldContext(
+ doc = "TLS KeyStore path in WebSocket"
+ )
+ private String tlsKeyStore = null;
+
+ @FieldContext(
+ doc = "TLS KeyStore password for WebSocket"
+ )
+ @ToString.Exclude
+ private String tlsKeyStorePassword = null;
+
+ @FieldContext(
+ doc = "TLS TrustStore type configuration in WebSocket: JKS, PKCS12"
+ )
+ private String tlsTrustStoreType = "JKS";
+
+ @FieldContext(
+ doc = "TLS TrustStore path in WebSocket"
+ )
+ private String tlsTrustStore = null;
+
+ @FieldContext(
+ doc = "TLS TrustStore password for WebSocket, null means empty password."
+ )
+ @ToString.Exclude
+ private String tlsTrustStorePassword = null;
+
+ @FieldContext(
+ doc = "Specify the tls protocols the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLSv1.3, TLSv1.2]"
+ )
+ private Set<String> webServiceTlsProtocols = new TreeSet<>();
+
+ @FieldContext(
+ doc = "Specify the tls cipher the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]"
+ )
+ private Set<String> webServiceTlsCiphers = new TreeSet<>();
+
@FieldContext(doc = "Key-value properties. Types are all String")
private Properties properties = new Properties();
}
[pulsar] 03/03: [improve][broker-web&websocket&proxy&function-worker] Full-support set ssl provider, ciphers and protocols (#13740)
Posted by pe...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
penghui pushed a commit to branch branch-2.9
in repository https://gitbox.apache.org/repos/asf/pulsar.git
commit a118ab953ede75d6ecfdf32aff95595f270486a1
Author: Zixuan Liu <no...@gmail.com>
AuthorDate: Sun May 1 12:35:46 2022 +0800
[improve][broker-web&websocket&proxy&function-worker] Full-support set ssl provider, ciphers and protocols (#13740)
Fixes #13734
Pulsar doesn't set ssl provider, ciphers and protocols to the web, websocket and proxy service when `tlsEnabledWithKeyStore=false`
- Add `org.apache.pulsar.jetty.tls` package in pulsar-broker-common for Jetty TLS support
- Add a new `webServiceTlsProvider=Conscrypt` to broker and proxy config
- Update `Conscrypt` as the `tlsProvider` value in websocket config
In the old version, we implicitly use the `Conscrypt` provider, now we need to set it explicitly.
(cherry picked from commit bf15e83a3f19b698c1492071792045e47824675c)
---
conf/broker.conf | 3 +
conf/functions_worker.yml | 6 +-
conf/proxy.conf | 9 +-
conf/standalone.conf | 3 +
conf/websocket.conf | 8 +-
.../apache/pulsar/broker/ServiceConfiguration.java | 21 +++
.../java/org/apache/pulsar/jetty/package-info.java | 19 ++
.../pulsar/jetty/tls/JettySslContextFactory.java | 116 +++++++++++++
.../org/apache/pulsar/jetty/tls/package-info.java | 19 ++
.../jetty/tls/JettySslContextFactoryTest.java | 174 +++++++++++++++++++
.../JettySslContextFactoryWithKeyStoreTest.java | 193 +++++++++++++++++++++
.../src/test/resources/ssl/jetty_client_key.jks | Bin 0 -> 2679 bytes
.../src/test/resources/ssl/jetty_client_trust.jks | Bin 0 -> 1207 bytes
.../src/test/resources/ssl/jetty_server_key.jks | Bin 0 -> 2679 bytes
.../src/test/resources/ssl/jetty_server_trust.jks | Bin 0 -> 1207 bytes
.../src/test/resources/ssl/my-ca/ca.pem | 18 ++
.../src/test/resources/ssl/my-ca/client-ca.pem | 19 ++
.../src/test/resources/ssl/my-ca/client-key.pem | 28 +++
.../src/test/resources/ssl/my-ca/server-ca.pem | 19 ++
.../src/test/resources/ssl/my-ca/server-key.pem | 28 +++
.../org/apache/pulsar/broker/PulsarService.java | 2 +
.../org/apache/pulsar/broker/web/WebService.java | 16 +-
.../proxy/ProxyPublishConsumeTlsTest.java | 2 +-
pulsar-common/pom.xml | 5 -
.../common/util/DefaultSslContextBuilder.java | 23 ++-
.../apache/pulsar/common/util/SecurityUtility.java | 74 +++-----
.../util/keystoretls/KeyStoreSSLContext.java | 57 +-----
.../SslContextFactoryWithAutoRefresh.java | 66 -------
.../pulsar/functions/worker/rest/WorkerServer.java | 16 +-
.../pulsar/proxy/server/AdminProxyHandler.java | 14 +-
.../pulsar/proxy/server/ProxyConfiguration.java | 21 +++
.../org/apache/pulsar/proxy/server/WebServer.java | 15 +-
.../pulsar/websocket/service/ProxyServer.java | 13 +-
.../service/WebSocketProxyConfiguration.java | 6 +-
34 files changed, 791 insertions(+), 222 deletions(-)
diff --git a/conf/broker.conf b/conf/broker.conf
index cfd1e9ef5f9..b67afa89c0b 100644
--- a/conf/broker.conf
+++ b/conf/broker.conf
@@ -599,6 +599,9 @@ tlsRequireTrustedClientCertOnConnect=false
# When using TLS authentication with KeyStore, available values can be SunJSSE, Conscrypt and etc.
tlsProvider=
+# Specify the TLS provider for the web service: SunJSSE, Conscrypt and etc.
+webServiceTlsProvider=Conscrypt
+
### --- KeyStore TLS config variables --- ###
## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
diff --git a/conf/functions_worker.yml b/conf/functions_worker.yml
index 06204dfdcfb..0b228d26a58 100644
--- a/conf/functions_worker.yml
+++ b/conf/functions_worker.yml
@@ -305,11 +305,11 @@ tlsCertRefreshCheckDurationSec: 300
# certificate isn't trusted.
tlsRequireTrustedClientCertOnConnect: false
-### --- KeyStore TLS config variables --- ###
+### --- TLS config variables --- ###
## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
-# TLS Provider for KeyStore type
-tlsProvider:
+# Specify the TLS provider for the web service: SunJSSE, Conscrypt and etc.
+tlsProvider: Conscrypt
# Enable TLS with KeyStore type configuration in function worker.
tlsEnabledWithKeyStore: false
diff --git a/conf/proxy.conf b/conf/proxy.conf
index fbdcad2b2b3..4f98663afc1 100644
--- a/conf/proxy.conf
+++ b/conf/proxy.conf
@@ -68,12 +68,17 @@ webServicePort=8080
# Port to use to server HTTPS request
webServicePortTls=
-### --- KeyStore TLS config variables --- ###
+### --- TLS config variables --- ###
## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
-# TLS Provider for KeyStore type
+# Specify the TLS provider for the broker service:
+# When using TLS authentication with CACert, the valid value is either OPENSSL or JDK.
+# When using TLS authentication with KeyStore, available values can be SunJSSE, Conscrypt and etc.
tlsProvider=
+# Specify the TLS provider for the web service, available values can be SunJSSE, Conscrypt and etc.
+webServiceTlsProvider=Conscrypt
+
# Enable TLS with KeyStore type configuration in proxy.
tlsEnabledWithKeyStore=false
diff --git a/conf/standalone.conf b/conf/standalone.conf
index 16312125a02..01030d049d4 100644
--- a/conf/standalone.conf
+++ b/conf/standalone.conf
@@ -362,6 +362,9 @@ tlsRequireTrustedClientCertOnConnect=false
# When using TLS authentication with KeyStore, available values can be SunJSSE, Conscrypt and etc.
tlsProvider=
+# Specify the TLS provider for the web service: SunJSSE, Conscrypt and etc.
+webServiceTlsProvider=Conscrypt
+
### --- KeyStore TLS config variables --- ###
# Enable TLS with KeyStore type configuration in broker.
tlsEnabledWithKeyStore=false
diff --git a/conf/websocket.conf b/conf/websocket.conf
index c2a138e7b38..535fade4ea6 100644
--- a/conf/websocket.conf
+++ b/conf/websocket.conf
@@ -96,6 +96,7 @@ brokerClientTrustCertsFilePath=
anonymousUserRole=
### --- TLS --- ###
+## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
# Deprecated - use webServicePortTls and brokerClientTlsEnabled instead
tlsEnabled=false
@@ -119,11 +120,8 @@ tlsRequireTrustedClientCertOnConnect=false
# Tls cert refresh duration in seconds (set 0 to check on every new connection)
tlsCertRefreshCheckDurationSec=300
-### --- KeyStore TLS config variables --- ###
-## Note that some of the above TLS configs also apply to the KeyStore TLS configuration.
-
-# TLS Provider for KeyStore type
-tlsProvider=
+# Specify the TLS provider for the WebSocket: SunJSSE, Conscrypt and etc.
+tlsProvider=Conscrypt
# Enable TLS with KeyStore type configuration in WebSocket.
tlsEnabledWithKeyStore=false
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
index 250d7d41ffa..53709718545 100644
--- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
+import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import lombok.Setter;
@@ -144,6 +145,26 @@ public class ServiceConfiguration implements PulsarConfiguration {
)
private Optional<Integer> webServicePortTls = Optional.empty();
+ @FieldContext(
+ category = CATEGORY_SERVER,
+ doc = "Specify the TLS provider for the web service: SunJSSE, Conscrypt and etc."
+ )
+ private String webServiceTlsProvider = "Conscrypt";
+
+ @FieldContext(
+ category = CATEGORY_TLS,
+ doc = "Specify the tls protocols the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLSv1.3, TLSv1.2]"
+ )
+ private Set<String> webServiceTlsProtocols = new TreeSet<>();
+
+ @FieldContext(
+ category = CATEGORY_TLS,
+ doc = "Specify the tls cipher the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]"
+ )
+ private Set<String> webServiceTlsCiphers = new TreeSet<>();
+
@FieldContext(
category = CATEGORY_SERVER,
doc = "Hostname or IP address the service binds on"
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/package-info.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/package-info.java
new file mode 100644
index 00000000000..f01bd9198f5
--- /dev/null
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/package-info.java
@@ -0,0 +1,19 @@
+/**
+ * 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.pulsar.jetty;
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls/JettySslContextFactory.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls/JettySslContextFactory.java
new file mode 100644
index 00000000000..514fa4a0725
--- /dev/null
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls/JettySslContextFactory.java
@@ -0,0 +1,116 @@
+/**
+ * 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.pulsar.jetty.tls;
+
+import java.util.Set;
+import javax.net.ssl.SSLContext;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.pulsar.common.util.DefaultSslContextBuilder;
+import org.apache.pulsar.common.util.SecurityUtility;
+import org.apache.pulsar.common.util.SslContextAutoRefreshBuilder;
+import org.apache.pulsar.common.util.keystoretls.NetSslContextBuilder;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+
+@Slf4j
+public class JettySslContextFactory {
+ static {
+ // DO NOT EDIT - Load Conscrypt provider
+ if (SecurityUtility.CONSCRYPT_PROVIDER != null) {
+ }
+ }
+
+ public static SslContextFactory.Server createServerSslContextWithKeystore(String sslProviderString,
+ String keyStoreTypeString,
+ String keyStore,
+ String keyStorePassword,
+ boolean allowInsecureConnection,
+ String trustStoreTypeString,
+ String trustStore,
+ String trustStorePassword,
+ boolean requireTrustedClientCertOnConnect,
+ Set<String> ciphers,
+ Set<String> protocols,
+ long certRefreshInSec) {
+ NetSslContextBuilder sslCtxRefresher = new NetSslContextBuilder(
+ sslProviderString,
+ keyStoreTypeString,
+ keyStore,
+ keyStorePassword,
+ allowInsecureConnection,
+ trustStoreTypeString,
+ trustStore,
+ trustStorePassword,
+ requireTrustedClientCertOnConnect,
+ certRefreshInSec);
+
+ return new JettySslContextFactory.Server(sslProviderString, sslCtxRefresher,
+ requireTrustedClientCertOnConnect, ciphers, protocols);
+ }
+
+ public static SslContextFactory createServerSslContext(String sslProviderString, boolean tlsAllowInsecureConnection,
+ String tlsTrustCertsFilePath,
+ String tlsCertificateFilePath,
+ String tlsKeyFilePath,
+ boolean tlsRequireTrustedClientCertOnConnect,
+ Set<String> ciphers,
+ Set<String> protocols,
+ long certRefreshInSec) {
+ DefaultSslContextBuilder sslCtxRefresher =
+ new DefaultSslContextBuilder(tlsAllowInsecureConnection, tlsTrustCertsFilePath, tlsCertificateFilePath,
+ tlsKeyFilePath, tlsRequireTrustedClientCertOnConnect, certRefreshInSec, sslProviderString);
+
+ return new JettySslContextFactory.Server(sslProviderString, sslCtxRefresher,
+ tlsRequireTrustedClientCertOnConnect, ciphers, protocols);
+ }
+
+ private static class Server extends SslContextFactory.Server {
+ private final SslContextAutoRefreshBuilder<SSLContext> sslCtxRefresher;
+
+ public Server(String sslProviderString, SslContextAutoRefreshBuilder<SSLContext> sslCtxRefresher,
+ boolean requireTrustedClientCertOnConnect, Set<String> ciphers, Set<String> protocols) {
+ super();
+ this.sslCtxRefresher = sslCtxRefresher;
+
+ if (ciphers != null && ciphers.size() > 0) {
+ this.setIncludeCipherSuites(ciphers.toArray(new String[0]));
+ }
+
+ if (protocols != null && protocols.size() > 0) {
+ this.setIncludeProtocols(protocols.toArray(new String[0]));
+ }
+
+ if (sslProviderString != null && !sslProviderString.equals("")) {
+ setProvider(sslProviderString);
+ }
+
+ if (requireTrustedClientCertOnConnect) {
+ this.setNeedClientAuth(true);
+ this.setTrustAll(false);
+ } else {
+ this.setWantClientAuth(true);
+ this.setTrustAll(true);
+ }
+ }
+
+ @Override
+ public SSLContext getSslContext() {
+ return sslCtxRefresher.get();
+ }
+ }
+}
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls/package-info.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls/package-info.java
new file mode 100644
index 00000000000..8978699ff79
--- /dev/null
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/jetty/tls/package-info.java
@@ -0,0 +1,19 @@
+/**
+ * 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.pulsar.jetty.tls;
diff --git a/pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryTest.java b/pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryTest.java
new file mode 100644
index 00000000000..c1816674880
--- /dev/null
+++ b/pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryTest.java
@@ -0,0 +1,174 @@
+/**
+ * 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.pulsar.jetty.tls;
+
+import com.google.common.io.Resources;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.pulsar.common.util.SecurityUtility;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.testng.annotations.Test;
+
+@Slf4j
+public class JettySslContextFactoryTest {
+
+ @Test
+ public void testJettyTlsServerTls() throws Exception {
+ Server server = new Server();
+ List<ServerConnector> connectors = new ArrayList<>();
+ SslContextFactory factory = JettySslContextFactory.createServerSslContext(
+ null,
+ false,
+ Resources.getResource("ssl/my-ca/ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/server-ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/server-key.pem").getPath(),
+ true,
+ null,
+ null,
+ 600);
+
+ ServerConnector connector = new ServerConnector(server, factory);
+ connector.setPort(0);
+ connectors.add(connector);
+ server.setConnectors(connectors.toArray(new ServerConnector[0]));
+ server.start();
+ // client connect
+ HttpClientBuilder httpClientBuilder = HttpClients.custom();
+ RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+ registryBuilder.register("https",
+ new SSLConnectionSocketFactory(getClientSslContext(), new NoopHostnameVerifier()));
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registryBuilder.build());
+ httpClientBuilder.setConnectionManager(cm);
+ CloseableHttpClient httpClient = httpClientBuilder.build();
+ HttpGet httpGet = new HttpGet("https://localhost:" + connector.getLocalPort());
+ httpClient.execute(httpGet);
+ httpClient.close();
+ server.stop();
+ }
+
+ @Test(expectedExceptions = SSLHandshakeException.class)
+ public void testJettyTlsServerInvalidTlsProtocol() throws Exception {
+ Server server = new Server();
+ List<ServerConnector> connectors = new ArrayList<>();
+ SslContextFactory factory = JettySslContextFactory.createServerSslContext(
+ null,
+ false,
+ Resources.getResource("ssl/my-ca/ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/server-ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/server-key.pem").getPath(),
+ true,
+ null,
+ new HashSet<String>() {
+ {
+ this.add("TLSv1.3");
+ }
+ },
+ 600);
+ factory.setHostnameVerifier((s, sslSession) -> true);
+ ServerConnector connector = new ServerConnector(server, factory);
+ connector.setPort(0);
+ connectors.add(connector);
+ server.setConnectors(connectors.toArray(new ServerConnector[0]));
+ server.start();
+ // client connect
+ HttpClientBuilder httpClientBuilder = HttpClients.custom();
+ RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+ registryBuilder.register("https", new SSLConnectionSocketFactory(getClientSslContext(),
+ new String[]{"TLSv1.2"}, null, new NoopHostnameVerifier()));
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registryBuilder.build());
+ httpClientBuilder.setConnectionManager(cm);
+ CloseableHttpClient httpClient = httpClientBuilder.build();
+ HttpGet httpGet = new HttpGet("https://localhost:" + connector.getLocalPort());
+ httpClient.execute(httpGet);
+ httpClient.close();
+ server.stop();
+ }
+
+ @Test(expectedExceptions = SSLHandshakeException.class)
+ public void testJettyTlsServerInvalidCipher() throws Exception {
+ Server server = new Server();
+ List<ServerConnector> connectors = new ArrayList<>();
+ SslContextFactory factory = JettySslContextFactory.createServerSslContext(
+ null,
+ false,
+ Resources.getResource("ssl/my-ca/ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/server-ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/server-key.pem").getPath(),
+ true,
+ new HashSet<String>() {
+ {
+ this.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+ }
+ },
+ new HashSet<String>() {
+ {
+ this.add("TLSv1.2");
+ }
+ },
+ 600);
+
+ factory.setHostnameVerifier((s, sslSession) -> true);
+ ServerConnector connector = new ServerConnector(server, factory);
+ connector.setPort(0);
+ connectors.add(connector);
+ server.setConnectors(connectors.toArray(new ServerConnector[0]));
+ server.start();
+ // client connect
+ HttpClientBuilder httpClientBuilder = HttpClients.custom();
+ RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+ registryBuilder.register("https", new SSLConnectionSocketFactory(getClientSslContext(),
+ new String[]{"TLSv1.2"}, new String[]{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"},
+ new NoopHostnameVerifier()));
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registryBuilder.build());
+ httpClientBuilder.setConnectionManager(cm);
+ CloseableHttpClient httpClient = httpClientBuilder.build();
+ HttpGet httpGet = new HttpGet("https://localhost:" + connector.getLocalPort());
+ httpClient.execute(httpGet);
+ httpClient.close();
+ server.stop();
+ }
+
+ private static SSLContext getClientSslContext() throws GeneralSecurityException, IOException {
+ return SecurityUtility.createSslContext(
+ false,
+ Resources.getResource("ssl/my-ca/ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/client-ca.pem").getPath(),
+ Resources.getResource("ssl/my-ca/client-key.pem").getPath(),
+ null
+ );
+ }
+}
diff --git a/pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryWithKeyStoreTest.java b/pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryWithKeyStoreTest.java
new file mode 100644
index 00000000000..292bd123fdf
--- /dev/null
+++ b/pulsar-broker-common/src/test/java/org/apache/pulsar/jetty/tls/JettySslContextFactoryWithKeyStoreTest.java
@@ -0,0 +1,193 @@
+/**
+ * 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.pulsar.jetty.tls;
+
+import com.google.common.io.Resources;
+import java.io.FileInputStream;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.TrustManagerFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.testng.annotations.Test;
+
+@Slf4j
+public class JettySslContextFactoryWithKeyStoreTest {
+
+ @Test
+ public void testJettyTlsServerTls() throws Exception {
+ Server server = new Server();
+ List<ServerConnector> connectors = new ArrayList<>();
+ SslContextFactory.Server factory = JettySslContextFactory.createServerSslContextWithKeystore(null,
+ "JKS", Resources.getResource("ssl/jetty_server_key.jks").getPath(),
+ "jetty_server_pwd", false, "JKS",
+ Resources.getResource("ssl/jetty_server_trust.jks").getPath(),
+ "jetty_server_pwd", true, null,
+ null, 600);
+ factory.setHostnameVerifier((s, sslSession) -> true);
+ ServerConnector connector = new ServerConnector(server, factory);
+ connector.setPort(0);
+ connectors.add(connector);
+ server.setConnectors(connectors.toArray(new ServerConnector[0]));
+ server.start();
+ // client connect
+ HttpClientBuilder httpClientBuilder = HttpClients.custom();
+ RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+ registryBuilder.register("https",
+ new SSLConnectionSocketFactory(getClientSslContext(), new NoopHostnameVerifier()));
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registryBuilder.build());
+ httpClientBuilder.setConnectionManager(cm);
+ CloseableHttpClient httpClient = httpClientBuilder.build();
+ HttpGet httpGet = new HttpGet("https://localhost:" + connector.getLocalPort());
+ httpClient.execute(httpGet);
+ httpClient.close();
+ server.stop();
+ }
+
+ @Test(expectedExceptions = SSLHandshakeException.class)
+ public void testJettyTlsServerInvalidTlsProtocol() throws Exception {
+ Configurator.setRootLevel(Level.INFO);
+ Server server = new Server();
+ List<ServerConnector> connectors = new ArrayList<>();
+ SslContextFactory.Server factory = JettySslContextFactory.createServerSslContextWithKeystore(null,
+ "JKS", Resources.getResource("ssl/jetty_server_key.jks").getPath(),
+ "jetty_server_pwd", false, "JKS",
+ Resources.getResource("ssl/jetty_server_trust.jks").getPath(),
+ "jetty_server_pwd", true, null,
+ new HashSet<String>() {
+ {
+ this.add("TLSv1.3");
+ }
+ }, 600);
+ factory.setHostnameVerifier((s, sslSession) -> true);
+ ServerConnector connector = new ServerConnector(server, factory);
+ connector.setPort(0);
+ connectors.add(connector);
+ server.setConnectors(connectors.toArray(new ServerConnector[0]));
+ server.start();
+ // client connect
+ HttpClientBuilder httpClientBuilder = HttpClients.custom();
+ RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+ registryBuilder.register("https", new SSLConnectionSocketFactory(getClientSslContext(),
+ new String[]{"TLSv1.2"}, null, new NoopHostnameVerifier()));
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registryBuilder.build());
+ httpClientBuilder.setConnectionManager(cm);
+ CloseableHttpClient httpClient = httpClientBuilder.build();
+ HttpGet httpGet = new HttpGet("https://localhost:" + connector.getLocalPort());
+ httpClient.execute(httpGet);
+ httpClient.close();
+ server.stop();
+ }
+
+ @Test(expectedExceptions = SSLHandshakeException.class)
+ public void testJettyTlsServerInvalidCipher() throws Exception {
+ Server server = new Server();
+ List<ServerConnector> connectors = new ArrayList<>();
+ SslContextFactory.Server factory = JettySslContextFactory.createServerSslContextWithKeystore(null,
+ "JKS", Resources.getResource("ssl/jetty_server_key.jks").getPath(),
+ "jetty_server_pwd", false, "JKS",
+ Resources.getResource("ssl/jetty_server_trust.jks").getPath(),
+ "jetty_server_pwd", true, new HashSet<String>() {
+ {
+ this.add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
+ }
+ },
+ new HashSet<String>() {
+ {
+ this.add("TLSv1.2");
+ }
+ }, 600);
+ factory.setHostnameVerifier((s, sslSession) -> true);
+ ServerConnector connector = new ServerConnector(server, factory);
+ connector.setPort(0);
+ connectors.add(connector);
+ server.setConnectors(connectors.toArray(new ServerConnector[0]));
+ server.start();
+ // client connect
+ HttpClientBuilder httpClientBuilder = HttpClients.custom();
+ RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+ registryBuilder.register("https", new SSLConnectionSocketFactory(getClientSslContext(),
+ new String[]{"TLSv1.2"}, new String[]{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"},
+ new NoopHostnameVerifier()));
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registryBuilder.build());
+ httpClientBuilder.setConnectionManager(cm);
+ CloseableHttpClient httpClient = httpClientBuilder.build();
+ HttpGet httpGet = new HttpGet("https://localhost:" + connector.getLocalPort());
+ httpClient.execute(httpGet);
+ httpClient.close();
+ server.stop();
+ }
+
+ private static SSLContext getClientSslContext() {
+ return getSslContext(Resources.getResource("ssl/jetty_client_key.jks").getPath(),
+ "jetty_client_pwd",
+ Resources.getResource("ssl/jetty_client_trust.jks").getPath(),
+ "jetty_client_pwd");
+ }
+
+ private static SSLContext getSslContext(String keyStorePath, String keyStorePassword,
+ String trustStorePath, String trustStorePassword) {
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ // key store
+ KeyManagerFactory keyManagerFactory =
+ KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ KeyStore keyStore = KeyStore.getInstance("JKS");
+ try (FileInputStream inputStream = new FileInputStream(keyStorePath)) {
+ keyStore.load(inputStream, keyStorePassword.toCharArray());
+ }
+ keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
+ KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
+ // trust store
+ TrustManagerFactory trustManagerFactory =
+ TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ KeyStore trustStore = KeyStore.getInstance("JKS");
+ try (FileInputStream inputStream = new FileInputStream(trustStorePath)) {
+ trustStore.load(inputStream, trustStorePassword.toCharArray());
+ }
+ trustManagerFactory.init(trustStore);
+ sslContext.init(keyManagers, trustManagerFactory.getTrustManagers(), new SecureRandom());
+ return sslContext;
+ } catch (Exception e) {
+ log.error("load ssl context error ", e);
+ return null;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/pulsar-broker-common/src/test/resources/ssl/jetty_client_key.jks b/pulsar-broker-common/src/test/resources/ssl/jetty_client_key.jks
new file mode 100644
index 00000000000..2b8ea64347d
Binary files /dev/null and b/pulsar-broker-common/src/test/resources/ssl/jetty_client_key.jks differ
diff --git a/pulsar-broker-common/src/test/resources/ssl/jetty_client_trust.jks b/pulsar-broker-common/src/test/resources/ssl/jetty_client_trust.jks
new file mode 100644
index 00000000000..166a2e00fb3
Binary files /dev/null and b/pulsar-broker-common/src/test/resources/ssl/jetty_client_trust.jks differ
diff --git a/pulsar-broker-common/src/test/resources/ssl/jetty_server_key.jks b/pulsar-broker-common/src/test/resources/ssl/jetty_server_key.jks
new file mode 100644
index 00000000000..b6189b75c8a
Binary files /dev/null and b/pulsar-broker-common/src/test/resources/ssl/jetty_server_key.jks differ
diff --git a/pulsar-broker-common/src/test/resources/ssl/jetty_server_trust.jks b/pulsar-broker-common/src/test/resources/ssl/jetty_server_trust.jks
new file mode 100644
index 00000000000..b09cc030a71
Binary files /dev/null and b/pulsar-broker-common/src/test/resources/ssl/jetty_server_trust.jks differ
diff --git a/pulsar-broker-common/src/test/resources/ssl/my-ca/ca.pem b/pulsar-broker-common/src/test/resources/ssl/my-ca/ca.pem
new file mode 100644
index 00000000000..3d5a80e2347
--- /dev/null
+++ b/pulsar-broker-common/src/test/resources/ssl/my-ca/ca.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC9DCCAdygAwIBAgIUNbNkV2+K2Hf4Q1V5gdAENZQiLokwDQYJKoZIhvcNAQEL
+BQAwETEPMA0GA1UEAxMGUHVsc2FyMCAXDTIyMDExNDA0MjgwMFoYDzIxMjIwMTE2
+MDQyODAwWjARMQ8wDQYDVQQDEwZQdWxzYXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDBR2K5EKVziLqdsz78efEW4lOwKiJ32e97uxn1Z6oKgkgImpVP
+Z9aoJB4EwSnDg+6FV2YULdWPm7C6W33tDmWRaU/Hlo/cOejnK8UmiMu/EyDpE2Wj
+n0RimGmwOkBi2IWIcIzWMmPDZ9kZc65OUeEmwZedKRy62PQyfCeNU4OOHQn3PXjI
+NbXJZD5TvBmn4SJn2RP9EgmIPaBAh/Mng045ZeHHLhwMKC8EOyHc2aB7AL6brymR
+xzsiYWdcJn4mqqMvT82mVvhkgAMOcR4CXYF8eYnsG6ZbDHb13CawcvLVREJZk7AB
+XZi9Rd5xczxHILM8rdkIZfunaG1X5hbih5wJAgMBAAGjQjBAMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTCC1lYG+62cUPjNk9q4jCm
+Ps65njANBgkqhkiG9w0BAQsFAAOCAQEAKV2Lpu5cH5EsG53EWsYxEKvuQZ0LTxCE
+wCDf/NxJaQbzfv0tsbZatMge0vcZ/5r8tZZoOC+pGTwk6MaRbEFH8PmvlH1LIQvu
+Y34/YQZOy8wBTWwaIfFMnYWc0iAFoFt2Lzuq+GOI+svTFp729Ae8r7UxY/f9Lioc
+ttdGr7vA6PpcIMoEIPjVp+m41uL9IDfX8eOxg4gVlwtqpbHdTzMrOz0YY+3qH/WK
+6Qffw4pwitzAEj2zCn2lvGC5cbpd13SAaqtB3xL/Aet0SS2r3g9qDo1RruQhXUng
+06U/Hqtn5K1fNQv3pivi3Jg5z1DfJWHkH37luAoIlOZHRmPK6rhp/g==
+-----END CERTIFICATE-----
diff --git a/pulsar-broker-common/src/test/resources/ssl/my-ca/client-ca.pem b/pulsar-broker-common/src/test/resources/ssl/my-ca/client-ca.pem
new file mode 100644
index 00000000000..adcae3393ad
--- /dev/null
+++ b/pulsar-broker-common/src/test/resources/ssl/my-ca/client-ca.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHDCCAgSgAwIBAgIUJJpmKX3DnbUwJ7tUhCt8MTiwz0owDQYJKoZIhvcNAQEL
+BQAwETEPMA0GA1UEAxMGUHVsc2FyMCAXDTIyMDExNDA0MjgwMFoYDzIxMjExMjIx
+MDQyODAwWjARMQ8wDQYDVQQDEwZQdWxzYXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDZN+CNZ1i1WaXulbwSASOfXErWXhGV9DHqavPp3DohgQdundfS
+648T/X80uWQlyxu4L4j0oc97jtzc1AyZFXj5nocVsveEO9aDjnYCc5NdBNJLQHgl
+IO59fEpTd55NO24g9a8/sxgn0ADCenMlngk1Ou+2QJBONw7W12/WUSUg6ICe+b+x
+qPzgApue16oGw9HxhPwa3oEvVZrEnFIWLjsSWtezhgFHMCH9/ngk0KlRyes/EZCz
+ZgkO5mgii2fmNDg+yuWUfw7Q0x6BJskGIrxisJiJBRR1+DIvJqgqxJsNmeeEQrZK
+YHBukj5RWDFOpOHgqFbPsv45sVKoLrGFrMnNAgMBAAGjajBoMA4GA1UdDwEB/wQE
+AwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQW
+BBSwkx93xjYP4I+dcFF3xS9NLesmFjAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJ
+KoZIhvcNAQELBQADggEBAAK3ZF63w46pT76QIOeSM3ocUm6izvW/IrxLUESfgRC4
+gg0/5VfPiHHUe6orn15KuPXHe7xCUFqc2oFn5aIU1B/6iOPeNItvMJidU0a3UAiw
+hFK9MSFgESNBiEnu1dE5tPcIIxTyCFQ/8loeY3dsdcNVoguH/2J9v/XcMMga46A1
+wudaaa1nb+ZYnXkRuyObKVJQN7EqC+4edinMOTPBbF9wtRMAMBRHXXENXb9zFthi
+Dbdn4YvadYsNHxh5ar+hQn/HSPMuCUPY/uUqxtBagb6aS0YnSoUscSLs1Jizg5NX
+d+QV8X/5E6W4xWnptUZwVxOemkdnr6A8MH1eQKKFZTM=
+-----END CERTIFICATE-----
diff --git a/pulsar-broker-common/src/test/resources/ssl/my-ca/client-key.pem b/pulsar-broker-common/src/test/resources/ssl/my-ca/client-key.pem
new file mode 100644
index 00000000000..5b08b151c80
--- /dev/null
+++ b/pulsar-broker-common/src/test/resources/ssl/my-ca/client-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDZN+CNZ1i1WaXu
+lbwSASOfXErWXhGV9DHqavPp3DohgQdundfS648T/X80uWQlyxu4L4j0oc97jtzc
+1AyZFXj5nocVsveEO9aDjnYCc5NdBNJLQHglIO59fEpTd55NO24g9a8/sxgn0ADC
+enMlngk1Ou+2QJBONw7W12/WUSUg6ICe+b+xqPzgApue16oGw9HxhPwa3oEvVZrE
+nFIWLjsSWtezhgFHMCH9/ngk0KlRyes/EZCzZgkO5mgii2fmNDg+yuWUfw7Q0x6B
+JskGIrxisJiJBRR1+DIvJqgqxJsNmeeEQrZKYHBukj5RWDFOpOHgqFbPsv45sVKo
+LrGFrMnNAgMBAAECggEATeVZ45uiFja16J9NuG8sJSPluoY1bD8L/3KnUcAmIImy
+7powIXVT8+k+StwI6/ywThbN2FyGmVqcHZz1f5hRr8KH0uJBHOyQetEFxM9Jk1v9
+Rfsymq36mImP5erJnAyp66vvUrqY+P4Ap71duam4x5wBBqyUk1fvPGA5vPOQiwHs
+TN9JHizGobY25fpigWKIMamyE7HWXEUzVdOo83ZiNx53ths+WcF/kqto2v5LtyfJ
+HgoPocfZI8tRz9tfgc8zOkvyjsvgdd6rLhd0r2oExnyQBJdktGFpQZMGambU328u
+NqcdJscjP/HWAHRzuSdOvCMOEn8E5GIjcWEnQqOmSQKBgQDcpb655/UdcVxrv2Ou
+8juucDJMpf6i/UcmlXVXx+3zGSuQZcCC2fupe3JcxPdK7bo65YlC3OoRihggh2sS
+cnFMNHMfyoE3G/doXIr3QyL9UAQt4yb+7Nz7jRXYcg4Ytv+FVS6BSzIDEK17v+es
+GuWDM3JwtigtzYS4tRh7lgmuBwKBgQD8BXp7yIyVv657B8OJJSoeGataziFPhZux
+WKoS3gq24169ZWXwLc+nwrdgvBNrRaHuX+cYh93RF9+2WZrRcRL41XqN938adasY
+zPsfOJa9IOgUzQtGUMSe1/WqvHfcvqZCqYq4u/LSdf+I67woP4tCqqn4E928aIZb
+6PjLH+dUiwKBgH1ntn7y1t1lEKIspPtJsaHzIqNttMvuKAJF7+t0Nkl0hM4NBt1Y
+BzDMeLNBP0vW0YGn89uMs3xEgHH8hV52rO4i4UuwTMCFpJgsAM+H2NsgHz/1WrSI
+6xANn9zk9h4V5CRjxYq2sjYLxI4RBBtNLiTjmKd24F8n78cLJl8XZ2kBAoGAGoHF
+ATH1v2ZaxqvpYApdpK7UfAeEL2YBGyUVNkjOXbAKbec1Uo6u8ZkkSnNdo4G+Z2EE
+4Gqh5PUa3YYNJ4w6D5v8eOQYJUNNDJ26p+z+xcOpRU7PqcSi+YYDW8LY5InU2NwW
+MBnsj0BD8TXCI4WTcx6aI/KK9t8TiqU1Tb/8R8MCgYANVinOLz2enB+Qzu4o88W/
+witKHI3D9+z/uWjp0Q4rwmr3OL4FD9vZWvL4qwbDgpfLirJ4e3UVfN1/FoytAKlk
+Kykf8oDWciCIdxStt/yUpgQv78IL3vM5d9B8Qb7KCRtJ0BIXGJ7Gle3xJeuduZLe
++F+hwI3Dpv5HPqa9o6ttJw==
+-----END PRIVATE KEY-----
diff --git a/pulsar-broker-common/src/test/resources/ssl/my-ca/server-ca.pem b/pulsar-broker-common/src/test/resources/ssl/my-ca/server-ca.pem
new file mode 100644
index 00000000000..df5f69298e2
--- /dev/null
+++ b/pulsar-broker-common/src/test/resources/ssl/my-ca/server-ca.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHDCCAgSgAwIBAgIUVQHD0/oi9Ca50HA7DFLYOO2wEzYwDQYJKoZIhvcNAQEL
+BQAwETEPMA0GA1UEAxMGUHVsc2FyMCAXDTIyMDExNDA0MjgwMFoYDzIxMjExMjIx
+MDQyODAwWjARMQ8wDQYDVQQDEwZQdWxzYXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDBcqDkMhjLd9ik//UQijqbajQP5t6dvVZNn9gODQrS9oB/URur
+NzCcPWYPJZfEJlTkV8mlmgq4dBjwghpy5ALOGiERk55JPIN4cy01hQ6j7YSPFvMv
+BjqZvm5dpGDNTr7GY7THegMM1wpk9EaUOm7tBOHtf6ZnANjSMcQM74RCSBt0Koqw
+06CKVDCbgJ5NNE1LgwYeVQAwtQAhY8rqqQKJvCorFbq7OiisFBnz5pRBT6N4kMo1
+9LZo3Oe2F2w9eH9vacQ0NjSOCNXqal9Xl/Pwy9JgKKppwZ/3nCgRc+yfjrnkRz0f
+b+llb2NpR5Ge+tNMakqelE8bDSw/5BPjRPftAgMBAAGjajBoMA4GA1UdDwEB/wQE
+AwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQW
+BBRXws5mmLbW+xOLflUyUZ0I0uN96zAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJ
+KoZIhvcNAQELBQADggEBAKMklpYJIkp4icz9Ea5wWQiRXWb94lGdyCA833VHeGB2
+fKvNXj1d6lEiy26pOjhDmycroKelj70WqOsqVgi4xh4Y9sj6pwb8Q423Tu3qNO1k
+qaScTar2DANSigNzqlSbLshPWQ2ZyDwkvZPuqPgHzOXekzbUGwxgCiySaQkl2mCS
+mBaG3XnESwiMIKkLphEv0MAvTVaImbSRWYEQ4OECwcHXxx+14wK8NLcdDIHcSzki
+8Eq24CxDOeL5QxciGMi5tylsdCpT+D/BXTKiu46yoRjXUsTLYL53yUZZIqQ3A4CV
+enZ/vHhP0Ev9RcRigFTqrBm7EC3b2AUpvqgRMnPwQZo=
+-----END CERTIFICATE-----
diff --git a/pulsar-broker-common/src/test/resources/ssl/my-ca/server-key.pem b/pulsar-broker-common/src/test/resources/ssl/my-ca/server-key.pem
new file mode 100644
index 00000000000..a3f3a36b73c
--- /dev/null
+++ b/pulsar-broker-common/src/test/resources/ssl/my-ca/server-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDBcqDkMhjLd9ik
+//UQijqbajQP5t6dvVZNn9gODQrS9oB/URurNzCcPWYPJZfEJlTkV8mlmgq4dBjw
+ghpy5ALOGiERk55JPIN4cy01hQ6j7YSPFvMvBjqZvm5dpGDNTr7GY7THegMM1wpk
+9EaUOm7tBOHtf6ZnANjSMcQM74RCSBt0Koqw06CKVDCbgJ5NNE1LgwYeVQAwtQAh
+Y8rqqQKJvCorFbq7OiisFBnz5pRBT6N4kMo19LZo3Oe2F2w9eH9vacQ0NjSOCNXq
+al9Xl/Pwy9JgKKppwZ/3nCgRc+yfjrnkRz0fb+llb2NpR5Ge+tNMakqelE8bDSw/
+5BPjRPftAgMBAAECggEBAJm2JsgMUo1ihn/dbnIdFCKoCgRUs7FtYCVADOJlVKN7
+AXGpFi4/JV4Qn4cLnQNcXfovE2iF9VzJy4NYLgH60YvJUVtxC8Yv0lukUVkEiDST
+p9A3MTa9YVUG7xVzZwPcPVTQpzYV6lSKjpTXUTm5EKk/RvJ7itKv5plmt9x7eYFb
+/JwqXo1Z6C4gfIFR85LWmrCsNUK5T9oooLz88D6+ZH3+fWlr75RDff2kqdLshMTs
+N0Ov7NXcRFeruFs/IPrgTxjBMeNa2LFdYVPeeQ41L4uOI49uVBAmSn1be+THvDoj
+Do+6wTEF/h6/VLoOaIFZZdHlqd4is+xcEg8gwVkCn2ECgYEAxqVvGKc9qaqEVwBx
+U5Ru9OFx0NqEBvkYZRbCg1REcMFd3lqFTHvHiF3pmCp0XgLJKYuy42618IJXhj6D
+Y15/p9jX0025MpnH/AdwpO6x5pv6gb/JOMnHOnq8sI3R+V6TVsv1WZj0sOj94mF0
++Od++bQkUnSlfE4X7v+cJfo/Q8UCgYEA+Uz1yOyI9Dv1dEdBMdBA8MTriYU0uJCV
+dVKzL/uC9XyguVBWu1HX0MvEKyjPRycvLB7TuQqAFLgCtC8EEuPGBpWtyXOm9Jxw
+ToCfUZFuBQeMuf4vZcFgJjiEKTdKBxrvjkhyIhPR6JAy0WUr8Ry+ZtqvmG5NOEz5
+ptm1tznYngkCgYEAlckeyV8p/uqF2biKu3QcamgoU0zB6yQfAfK0fySmasNTzZtC
+EhbvsOLnhgbVMiI1ny8ol5fedtlBuAchOWeDKIQ40as0r3QHuQG/LY6S9Im+zeFY
+kIqNwInWB+cYYkmvHe6zNXlBYLh+4BmOgzTDqPPtw4MTWXTlVSDGlFhrJeUCgYBX
+7rlS4Xt9ChkNpoRsWZROWGbr3rw1zWmqND1X01Lh28+lDZ1J/RguYXET+BUEd+G/
+oi/zuKxsomrxuxOoxgZ3FBx0TgK5jORgDCYl0zIHPB57DBkTvx123cBf+Ux3LR0K
+BqubMXp8mUATc6gIJ6dRCBmfnmhGT4BPRcM+mXy6YQKBgGEGH37VABus+Oi3g1bk
+qEAaUI1asRLJIfbY2ImxEroLIQAbTFuIQUsZTKpT7jJZubjYvy1Fev0LU/n7Kv2w
+7ym41z70ro5uxwUBfJjnF3RtgncNcftn4b3siNzvBfKEBuhegMeS5YAbBIwABUpR
+4mVpm9BLOiX4yENIT6JdUQFc
+-----END PRIVATE KEY-----
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java
index 60cd75501d0..a777ced4f95 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java
@@ -1383,6 +1383,8 @@ public class PulsarService implements AutoCloseable, ShutdownService {
conf.getBrokerClientAuthenticationParameters());
if (conf.isBrokerClientTlsEnabled()) {
+ builder.tlsCiphers(config.getBrokerClientTlsCiphers())
+ .tlsProtocols(config.getBrokerClientTlsProtocols());
if (conf.isBrokerClientTlsEnabledWithKeyStore()) {
builder.useKeyStoreTls(true)
.tlsTrustStoreType(conf.getBrokerClientTlsTrustStoreType())
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
index e5e2ab1d218..e80a5160cb5 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/WebService.java
@@ -30,8 +30,7 @@ import javax.servlet.DispatcherType;
import org.apache.pulsar.broker.PulsarServerException;
import org.apache.pulsar.broker.PulsarService;
import org.apache.pulsar.broker.ServiceConfiguration;
-import org.apache.pulsar.common.util.SecurityUtility;
-import org.apache.pulsar.common.util.keystoretls.KeyStoreSSLContext;
+import org.apache.pulsar.jetty.tls.JettySslContextFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -99,8 +98,8 @@ public class WebService implements AutoCloseable {
SslContextFactory sslCtxFactory;
ServiceConfiguration config = pulsar.getConfiguration();
if (config.isTlsEnabledWithKeyStore()) {
- sslCtxFactory = KeyStoreSSLContext.createSslContextFactory(
- config.getTlsProvider(),
+ sslCtxFactory = JettySslContextFactory.createServerSslContextWithKeystore(
+ config.getWebServiceTlsProvider(),
config.getTlsKeyStoreType(),
config.getTlsKeyStore(),
config.getTlsKeyStorePassword(),
@@ -109,15 +108,20 @@ public class WebService implements AutoCloseable {
config.getTlsTrustStore(),
config.getTlsTrustStorePassword(),
config.isTlsRequireTrustedClientCertOnConnect(),
+ config.getWebServiceTlsCiphers(),
+ config.getWebServiceTlsProtocols(),
config.getTlsCertRefreshCheckDurationSec()
);
} else {
- sslCtxFactory = SecurityUtility.createSslContextFactory(
+ sslCtxFactory = JettySslContextFactory.createServerSslContext(
+ config.getWebServiceTlsProvider(),
config.isTlsAllowInsecureConnection(),
config.getTlsTrustCertsFilePath(),
config.getTlsCertificateFilePath(),
config.getTlsKeyFilePath(),
- config.isTlsRequireTrustedClientCertOnConnect(), true,
+ config.isTlsRequireTrustedClientCertOnConnect(),
+ config.getWebServiceTlsCiphers(),
+ config.getWebServiceTlsProtocols(),
config.getTlsCertRefreshCheckDurationSec());
}
httpsConnector = new PulsarServerConnector(server, 1, 1, sslCtxFactory);
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/websocket/proxy/ProxyPublishConsumeTlsTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/websocket/proxy/ProxyPublishConsumeTlsTest.java
index 4c82615aa7f..b780fde760e 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/websocket/proxy/ProxyPublishConsumeTlsTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/websocket/proxy/ProxyPublishConsumeTlsTest.java
@@ -106,7 +106,7 @@ public class ProxyPublishConsumeTlsTest extends TlsProducerConsumerBase {
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setSslContext(SecurityUtility
- .createSslContext(false, SecurityUtility.loadCertificatesFromPemFile(TLS_TRUST_CERT_FILE_PATH)));
+ .createSslContext(false, SecurityUtility.loadCertificatesFromPemFile(TLS_TRUST_CERT_FILE_PATH), null));
WebSocketClient consumeClient = new WebSocketClient(sslContextFactory);
SimpleConsumerSocket consumeSocket = new SimpleConsumerSocket();
diff --git a/pulsar-common/pom.xml b/pulsar-common/pom.xml
index e8b5c595790..fd715f87e00 100644
--- a/pulsar-common/pom.xml
+++ b/pulsar-common/pom.xml
@@ -136,11 +136,6 @@
<artifactId>netty-codec-haproxy</artifactId>
</dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
- </dependency>
-
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/DefaultSslContextBuilder.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/DefaultSslContextBuilder.java
index b1e8a14ff95..2e67b02f90b 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/DefaultSslContextBuilder.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/common/util/DefaultSslContextBuilder.java
@@ -18,11 +18,8 @@
*/
package org.apache.pulsar.common.util;
-import java.io.FileNotFoundException;
-import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
@SuppressWarnings("checkstyle:JavadocType")
public class DefaultSslContextBuilder extends SslContextAutoRefreshBuilder<SSLContext> {
@@ -31,23 +28,37 @@ public class DefaultSslContextBuilder extends SslContextAutoRefreshBuilder<SSLCo
protected final boolean tlsAllowInsecureConnection;
protected final FileModifiedTimeUpdater tlsTrustCertsFilePath, tlsCertificateFilePath, tlsKeyFilePath;
protected final boolean tlsRequireTrustedClientCertOnConnect;
+ private final String providerName;
public DefaultSslContextBuilder(boolean allowInsecure, String trustCertsFilePath, String certificateFilePath,
- String keyFilePath, boolean requireTrustedClientCertOnConnect, long certRefreshInSec)
- throws SSLException, FileNotFoundException, GeneralSecurityException, IOException {
+ String keyFilePath, boolean requireTrustedClientCertOnConnect,
+ long certRefreshInSec) {
super(certRefreshInSec);
this.tlsAllowInsecureConnection = allowInsecure;
this.tlsTrustCertsFilePath = new FileModifiedTimeUpdater(trustCertsFilePath);
this.tlsCertificateFilePath = new FileModifiedTimeUpdater(certificateFilePath);
this.tlsKeyFilePath = new FileModifiedTimeUpdater(keyFilePath);
this.tlsRequireTrustedClientCertOnConnect = requireTrustedClientCertOnConnect;
+ this.providerName = null;
+ }
+
+ public DefaultSslContextBuilder(boolean allowInsecure, String trustCertsFilePath, String certificateFilePath,
+ String keyFilePath, boolean requireTrustedClientCertOnConnect,
+ long certRefreshInSec, String providerName) {
+ super(certRefreshInSec);
+ this.tlsAllowInsecureConnection = allowInsecure;
+ this.tlsTrustCertsFilePath = new FileModifiedTimeUpdater(trustCertsFilePath);
+ this.tlsCertificateFilePath = new FileModifiedTimeUpdater(certificateFilePath);
+ this.tlsKeyFilePath = new FileModifiedTimeUpdater(keyFilePath);
+ this.tlsRequireTrustedClientCertOnConnect = requireTrustedClientCertOnConnect;
+ this.providerName = providerName;
}
@Override
public synchronized SSLContext update() throws GeneralSecurityException {
this.sslContext = SecurityUtility.createSslContext(tlsAllowInsecureConnection,
tlsTrustCertsFilePath.getFileName(), tlsCertificateFilePath.getFileName(),
- tlsKeyFilePath.getFileName());
+ tlsKeyFilePath.getFileName(), this.providerName);
return this.sslContext;
}
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
index 4fe3a3756a1..6b715bbf6dc 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
@@ -65,7 +65,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.pulsar.common.classification.InterfaceAudience;
import org.apache.pulsar.common.classification.InterfaceStability;
import org.apache.pulsar.common.tls.TlsHostnameVerifier;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
/**
* Helper class for the security domain.
@@ -197,9 +196,10 @@ public class SecurityUtility {
return provider;
}
- public static SSLContext createSslContext(boolean allowInsecureConnection, Certificate[] trustCertificates)
+ public static SSLContext createSslContext(boolean allowInsecureConnection, Certificate[] trustCertificates,
+ String providerName)
throws GeneralSecurityException {
- return createSslContext(allowInsecureConnection, trustCertificates, (Certificate[]) null, (PrivateKey) null);
+ return createSslContext(allowInsecureConnection, trustCertificates, null, null, providerName);
}
public static SslContext createNettySslContextForClient(SslProvider sslProvider, boolean allowInsecureConnection,
@@ -212,11 +212,11 @@ public class SecurityUtility {
}
public static SSLContext createSslContext(boolean allowInsecureConnection, String trustCertsFilePath,
- String certFilePath, String keyFilePath) throws GeneralSecurityException {
+ String certFilePath, String keyFilePath, String providerName) throws GeneralSecurityException {
X509Certificate[] trustCertificates = loadCertificatesFromPemFile(trustCertsFilePath);
X509Certificate[] certificates = loadCertificatesFromPemFile(certFilePath);
PrivateKey privateKey = loadPrivateKeyFromPemFile(keyFilePath);
- return createSslContext(allowInsecureConnection, trustCertificates, certificates, privateKey);
+ return createSslContext(allowInsecureConnection, trustCertificates, certificates, privateKey, providerName);
}
/**
@@ -324,18 +324,25 @@ public class SecurityUtility {
}
public static SSLContext createSslContext(boolean allowInsecureConnection, Certificate[] trustCertficates,
- Certificate[] certificates, PrivateKey privateKey) throws GeneralSecurityException {
+ Certificate[] certificates, PrivateKey privateKey)
+ throws GeneralSecurityException {
+ return createSslContext(allowInsecureConnection, trustCertficates, certificates, privateKey, null);
+ }
+
+ public static SSLContext createSslContext(boolean allowInsecureConnection, Certificate[] trustCertficates,
+ Certificate[] certificates, PrivateKey privateKey, String providerName)
+ throws GeneralSecurityException {
KeyStoreHolder ksh = new KeyStoreHolder();
TrustManager[] trustManagers = null;
KeyManager[] keyManagers = null;
+ Provider provider = resolveProvider(providerName);
- trustManagers = setupTrustCerts(ksh, allowInsecureConnection, trustCertficates, CONSCRYPT_PROVIDER);
+ trustManagers = setupTrustCerts(ksh, allowInsecureConnection, trustCertficates, provider);
keyManagers = setupKeyManager(ksh, privateKey, certificates);
- SSLContext sslCtx = CONSCRYPT_PROVIDER != null ? SSLContext.getInstance("TLS", CONSCRYPT_PROVIDER)
+ SSLContext sslCtx = provider != null ? SSLContext.getInstance("TLS", provider)
: SSLContext.getInstance("TLS");
sslCtx.init(keyManagers, trustManagers, new SecureRandom());
- sslCtx.getDefaultSSLParameters();
return sslCtx;
}
@@ -542,51 +549,16 @@ public class SecurityUtility {
}
}
- public static SslContextFactory createSslContextFactory(boolean tlsAllowInsecureConnection,
- String tlsTrustCertsFilePath, String tlsCertificateFilePath, String tlsKeyFilePath,
- boolean tlsRequireTrustedClientCertOnConnect, boolean autoRefresh, long certRefreshInSec)
- throws GeneralSecurityException, SSLException, FileNotFoundException, IOException {
- SslContextFactory sslCtxFactory = null;
- if (autoRefresh) {
- sslCtxFactory = new SslContextFactoryWithAutoRefresh(tlsAllowInsecureConnection, tlsTrustCertsFilePath,
- tlsCertificateFilePath, tlsKeyFilePath, tlsRequireTrustedClientCertOnConnect, certRefreshInSec);
- } else {
- sslCtxFactory = new SslContextFactory();
- SSLContext sslCtx = createSslContext(tlsAllowInsecureConnection, tlsTrustCertsFilePath,
- tlsCertificateFilePath, tlsKeyFilePath);
- sslCtxFactory.setSslContext(sslCtx);
+ public static Provider resolveProvider(String providerName) throws NoSuchAlgorithmException {
+ Provider provider = null;
+ if (!StringUtils.isEmpty(providerName)) {
+ provider = Security.getProvider(providerName);
}
- if (tlsRequireTrustedClientCertOnConnect) {
- sslCtxFactory.setNeedClientAuth(true);
- } else {
- sslCtxFactory.setWantClientAuth(true);
- }
- sslCtxFactory.setTrustAll(true);
- return sslCtxFactory;
- }
- /**
- * {@link SslContextFactory} that auto-refresh SSLContext.
- */
- static class SslContextFactoryWithAutoRefresh extends SslContextFactory {
-
- private final DefaultSslContextBuilder sslCtxRefresher;
-
- public SslContextFactoryWithAutoRefresh(boolean tlsAllowInsecureConnection, String tlsTrustCertsFilePath,
- String tlsCertificateFilePath, String tlsKeyFilePath, boolean tlsRequireTrustedClientCertOnConnect,
- long certRefreshInSec)
- throws SSLException, FileNotFoundException, GeneralSecurityException, IOException {
- super();
- sslCtxRefresher = new DefaultSslContextBuilder(tlsAllowInsecureConnection, tlsTrustCertsFilePath,
- tlsCertificateFilePath, tlsKeyFilePath, tlsRequireTrustedClientCertOnConnect, certRefreshInSec);
- if (CONSCRYPT_PROVIDER != null) {
- setProvider(CONSCRYPT_PROVIDER.getName());
- }
+ if (provider == null) {
+ provider = SSLContext.getDefault().getProvider();
}
- @Override
- public SSLContext getSslContext() {
- return sslCtxRefresher.get();
- }
+ return provider;
}
}
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
index 987a32b216c..7b06a33601b 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/KeyStoreSSLContext.java
@@ -38,7 +38,6 @@ import javax.net.ssl.TrustManagerFactory;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.common.util.SecurityUtility;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
/**
* KeyStoreSSLContext that mainly wrap a SSLContext to provide SSL context for both webservice and netty.
@@ -125,8 +124,10 @@ public class KeyStoreSSLContext {
public SSLContext createSSLContext() throws GeneralSecurityException, IOException {
SSLContext sslContext;
- if (sslProviderString != null) {
- sslContext = SSLContext.getInstance(protocol, sslProviderString);
+
+ Provider provider = SecurityUtility.resolveProvider(sslProviderString);
+ if (provider != null) {
+ sslContext = SSLContext.getInstance(protocol, provider);
} else {
sslContext = SSLContext.getInstance(protocol);
}
@@ -149,8 +150,8 @@ public class KeyStoreSSLContext {
if (this.allowInsecureConnection) {
trustManagerFactory = InsecureTrustManagerFactory.INSTANCE;
} else {
- trustManagerFactory = sslProviderString != null
- ? TrustManagerFactory.getInstance(tmfAlgorithm, sslProviderString)
+ trustManagerFactory = provider != null
+ ? TrustManagerFactory.getInstance(tmfAlgorithm, provider)
: TrustManagerFactory.getInstance(tmfAlgorithm);
KeyStore trustStore = KeyStore.getInstance(trustStoreTypeString);
char[] passwordChars = trustStorePassword.toCharArray();
@@ -333,48 +334,4 @@ public class KeyStoreSSLContext {
return keyStoreSSLContext.createSSLContext();
}
-
- // for web server. autoRefresh is default true.
- public static SslContextFactory createSslContextFactory(String sslProviderString,
- String keyStoreTypeString,
- String keyStore,
- String keyStorePassword,
- boolean allowInsecureConnection,
- String trustStoreTypeString,
- String trustStore,
- String trustStorePassword,
- boolean requireTrustedClientCertOnConnect,
- long certRefreshInSec)
- throws GeneralSecurityException, IOException {
- SslContextFactory sslCtxFactory;
-
- if (sslProviderString == null) {
- Provider provider = SecurityUtility.CONSCRYPT_PROVIDER;
- if (provider != null) {
- sslProviderString = provider.getName();
- }
- }
-
- sslCtxFactory = new SslContextFactoryWithAutoRefresh(
- sslProviderString,
- keyStoreTypeString,
- keyStore,
- keyStorePassword,
- allowInsecureConnection,
- trustStoreTypeString,
- trustStore,
- trustStorePassword,
- requireTrustedClientCertOnConnect,
- certRefreshInSec);
-
- if (requireTrustedClientCertOnConnect) {
- sslCtxFactory.setNeedClientAuth(true);
- } else {
- sslCtxFactory.setWantClientAuth(true);
- }
- sslCtxFactory.setTrustAll(true);
-
- return sslCtxFactory;
- }
-}
-
+}
\ No newline at end of file
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/SslContextFactoryWithAutoRefresh.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/SslContextFactoryWithAutoRefresh.java
deleted file mode 100644
index 0882a3a0cb1..00000000000
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/keystoretls/SslContextFactoryWithAutoRefresh.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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.pulsar.common.util.keystoretls;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-/**
- * SslContextFactoryWithAutoRefresh that create SSLContext for web server, and refresh in time.
- */
-public class SslContextFactoryWithAutoRefresh extends SslContextFactory {
- private final NetSslContextBuilder sslCtxRefresher;
-
- public SslContextFactoryWithAutoRefresh(String sslProviderString,
- String keyStoreTypeString,
- String keyStore,
- String keyStorePassword,
- boolean allowInsecureConnection,
- String trustStoreTypeString,
- String trustStore,
- String trustStorePassword,
- boolean requireTrustedClientCertOnConnect,
- long certRefreshInSec)
- throws SSLException, FileNotFoundException, GeneralSecurityException, IOException {
- super();
- sslCtxRefresher = new NetSslContextBuilder(
- sslProviderString,
- keyStoreTypeString,
- keyStore,
- keyStorePassword,
- allowInsecureConnection,
- trustStoreTypeString,
- trustStore,
- trustStorePassword,
- requireTrustedClientCertOnConnect,
- certRefreshInSec);
- if (sslProviderString != null) {
- setProvider(sslProviderString);
- }
- }
-
- @Override
- public SSLContext getSslContext() {
- return sslCtxRefresher.get();
- }
-}
diff --git a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java
index 9747f4b3da4..831a474a51d 100644
--- a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java
+++ b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/WorkerServer.java
@@ -25,12 +25,11 @@ import org.apache.pulsar.broker.web.AuthenticationFilter;
import org.apache.pulsar.broker.web.RateLimitingFilter;
import org.apache.pulsar.broker.web.JettyRequestLogFactory;
import org.apache.pulsar.broker.web.WebExecutorThreadPool;
-import org.apache.pulsar.common.util.SecurityUtility;
-import org.apache.pulsar.common.util.keystoretls.KeyStoreSSLContext;
import org.apache.pulsar.functions.worker.WorkerConfig;
import org.apache.pulsar.functions.worker.WorkerService;
import org.apache.pulsar.functions.worker.rest.api.v2.WorkerApiV2Resource;
import org.apache.pulsar.functions.worker.rest.api.v2.WorkerStatsApiV2Resource;
+import org.apache.pulsar.jetty.tls.JettySslContextFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -125,7 +124,7 @@ public class WorkerServer {
try {
SslContextFactory sslCtxFactory;
if (workerConfig.isTlsEnabledWithKeyStore()) {
- sslCtxFactory = KeyStoreSSLContext.createSslContextFactory(
+ sslCtxFactory = JettySslContextFactory.createServerSslContextWithKeystore(
workerConfig.getTlsProvider(),
workerConfig.getTlsKeyStoreType(),
workerConfig.getTlsKeyStore(),
@@ -135,17 +134,22 @@ public class WorkerServer {
workerConfig.getTlsTrustStore(),
workerConfig.getTlsTrustStorePassword(),
workerConfig.isTlsRequireTrustedClientCertOnConnect(),
+ workerConfig.getWebServiceTlsCiphers(),
+ workerConfig.getWebServiceTlsProtocols(),
workerConfig.getTlsCertRefreshCheckDurationSec()
);
} else {
- sslCtxFactory = SecurityUtility.createSslContextFactory(
+ sslCtxFactory = JettySslContextFactory.createServerSslContext(
+ workerConfig.getTlsProvider(),
workerConfig.isTlsAllowInsecureConnection(),
workerConfig.getTlsTrustCertsFilePath(),
workerConfig.getTlsCertificateFilePath(),
workerConfig.getTlsKeyFilePath(),
workerConfig.isTlsRequireTrustedClientCertOnConnect(),
- true,
- workerConfig.getTlsCertRefreshCheckDurationSec());
+ workerConfig.getWebServiceTlsCiphers(),
+ workerConfig.getWebServiceTlsProtocols(),
+ workerConfig.getTlsCertRefreshCheckDurationSec()
+ );
}
httpsConnector = new ServerConnector(server, sslCtxFactory);
httpsConnector.setPort(this.workerConfig.getWorkerPortTls());
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
index 853eb0bf0bc..d4eb4774268 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java
@@ -266,15 +266,17 @@ class AdminProxyHandler extends ProxyServlet {
AuthenticationDataProvider authData = auth.getAuthData();
if (authData.hasDataForTls()) {
sslCtx = SecurityUtility.createSslContext(
- config.isTlsAllowInsecureConnection(),
- trustCertificates,
- authData.getTlsCertificates(),
- authData.getTlsPrivateKey()
+ config.isTlsAllowInsecureConnection(),
+ trustCertificates,
+ authData.getTlsCertificates(),
+ authData.getTlsPrivateKey(),
+ config.getBrokerClientSslProvider()
);
} else {
sslCtx = SecurityUtility.createSslContext(
- config.isTlsAllowInsecureConnection(),
- trustCertificates
+ config.isTlsAllowInsecureConnection(),
+ trustCertificates,
+ config.getBrokerClientSslProvider()
);
}
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
index a29158f3902..e440133aa40 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConfiguration.java
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
+import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -214,6 +215,26 @@ public class ProxyConfiguration implements PulsarConfiguration {
)
private Optional<Integer> webServicePortTls = Optional.empty();
+ @FieldContext(
+ category = CATEGORY_KEYSTORE_TLS,
+ doc = "Specify the TLS provider for the web service, available values can be SunJSSE, Conscrypt and etc."
+ )
+ private String webServiceTlsProvider = "Conscrypt";
+
+ @FieldContext(
+ category = CATEGORY_TLS,
+ doc = "Specify the tls protocols the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLSv1.3, TLSv1.2]"
+ )
+ private Set<String> webServiceTlsProtocols = new TreeSet<>();
+
+ @FieldContext(
+ category = CATEGORY_TLS,
+ doc = "Specify the tls cipher the proxy's web service will use to negotiate during TLS Handshake.\n\n"
+ + "Example:- [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]"
+ )
+ private Set<String> webServiceTlsCiphers = new TreeSet<>();
+
@FieldContext(
category = CATEGORY_SERVER,
doc = "The directory where nar Extraction happens"
diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java
index 8a9956ca493..b8004f916fd 100644
--- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java
+++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/WebServer.java
@@ -37,8 +37,7 @@ import org.apache.pulsar.broker.web.JsonMapperProvider;
import org.apache.pulsar.broker.web.RateLimitingFilter;
import org.apache.pulsar.broker.web.JettyRequestLogFactory;
import org.apache.pulsar.broker.web.WebExecutorThreadPool;
-import org.apache.pulsar.common.util.SecurityUtility;
-import org.apache.pulsar.common.util.keystoretls.KeyStoreSSLContext;
+import org.apache.pulsar.jetty.tls.JettySslContextFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
@@ -100,8 +99,8 @@ public class WebServer {
try {
SslContextFactory sslCtxFactory;
if (config.isTlsEnabledWithKeyStore()) {
- sslCtxFactory = KeyStoreSSLContext.createSslContextFactory(
- config.getTlsProvider(),
+ sslCtxFactory = JettySslContextFactory.createServerSslContextWithKeystore(
+ config.getWebServiceTlsProvider(),
config.getTlsKeyStoreType(),
config.getTlsKeyStore(),
config.getTlsKeyStorePassword(),
@@ -110,16 +109,20 @@ public class WebServer {
config.getTlsTrustStore(),
config.getTlsTrustStorePassword(),
config.isTlsRequireTrustedClientCertOnConnect(),
+ config.getWebServiceTlsCiphers(),
+ config.getWebServiceTlsProtocols(),
config.getTlsCertRefreshCheckDurationSec()
);
} else {
- sslCtxFactory = SecurityUtility.createSslContextFactory(
+ sslCtxFactory = JettySslContextFactory.createServerSslContext(
+ config.getWebServiceTlsProvider(),
config.isTlsAllowInsecureConnection(),
config.getTlsTrustCertsFilePath(),
config.getTlsCertificateFilePath(),
config.getTlsKeyFilePath(),
config.isTlsRequireTrustedClientCertOnConnect(),
- true,
+ config.getWebServiceTlsCiphers(),
+ config.getWebServiceTlsProtocols(),
config.getTlsCertRefreshCheckDurationSec());
}
connectorTls = new ServerConnector(server, 1, 1, sslCtxFactory);
diff --git a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java
index 9cfed156c3f..85b7e2626ce 100644
--- a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java
+++ b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/ProxyServer.java
@@ -36,8 +36,7 @@ import org.apache.pulsar.broker.web.JsonMapperProvider;
import org.apache.pulsar.broker.web.JettyRequestLogFactory;
import org.apache.pulsar.broker.web.WebExecutorThreadPool;
import org.apache.pulsar.client.api.PulsarClientException;
-import org.apache.pulsar.common.util.SecurityUtility;
-import org.apache.pulsar.common.util.keystoretls.KeyStoreSSLContext;
+import org.apache.pulsar.jetty.tls.JettySslContextFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -79,7 +78,7 @@ public class ProxyServer {
try {
SslContextFactory sslCtxFactory;
if (config.isTlsEnabledWithKeyStore()) {
- sslCtxFactory = KeyStoreSSLContext.createSslContextFactory(
+ sslCtxFactory = JettySslContextFactory.createServerSslContextWithKeystore(
config.getTlsProvider(),
config.getTlsKeyStoreType(),
config.getTlsKeyStore(),
@@ -89,16 +88,20 @@ public class ProxyServer {
config.getTlsTrustStore(),
config.getTlsTrustStorePassword(),
config.isTlsRequireTrustedClientCertOnConnect(),
+ config.getWebServiceTlsCiphers(),
+ config.getWebServiceTlsProtocols(),
config.getTlsCertRefreshCheckDurationSec()
);
} else {
- sslCtxFactory = SecurityUtility.createSslContextFactory(
+ sslCtxFactory = JettySslContextFactory.createServerSslContext(
+ config.getTlsProvider(),
config.isTlsAllowInsecureConnection(),
config.getTlsTrustCertsFilePath(),
config.getTlsCertificateFilePath(),
config.getTlsKeyFilePath(),
config.isTlsRequireTrustedClientCertOnConnect(),
- true,
+ config.getWebServiceTlsCiphers(),
+ config.getWebServiceTlsProtocols(),
config.getTlsCertRefreshCheckDurationSec());
}
connectorTls = new ServerConnector(server, sslCtxFactory);
diff --git a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java
index 2cd8eb23f7f..deb8ab3e032 100644
--- a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java
+++ b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketProxyConfiguration.java
@@ -167,11 +167,9 @@ public class WebSocketProxyConfiguration implements PulsarConfiguration {
private boolean tlsEnabledWithKeyStore = false;
@FieldContext(
- doc = "Specify the TLS provider for the WebSocket service: \n"
- + "When using TLS authentication with CACert, the valid value is either OPENSSL or JDK.\n"
- + "When using TLS authentication with KeyStore, available values can be SunJSSE, Conscrypt and etc."
+ doc = "Specify the TLS provider for the WebSocket service: SunJSSE, Conscrypt and etc."
)
- private String tlsProvider = null;
+ private String tlsProvider = "Conscrypt";
@FieldContext(
doc = "TLS KeyStore type configuration in WebSocket: JKS, PKCS12"
[pulsar] 01/03: Use tlsCertRefreshCheckDurationSec instead of 0 for refresh value (#15075)
Posted by pe...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
penghui pushed a commit to branch branch-2.9
in repository https://gitbox.apache.org/repos/asf/pulsar.git
commit f2bb45b7de8235732a172148481a06a181c5dfd3
Author: Michael Marshall <mm...@apache.org>
AuthorDate: Fri Apr 8 00:44:15 2022 -0500
Use tlsCertRefreshCheckDurationSec instead of 0 for refresh value (#15075)
(cherry picked from commit e398d7e412c21e47c7e5d48225088f12874ebd29)
---
.../src/main/java/org/apache/pulsar/common/util/SecurityUtility.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
index d5a0c5a5767..4fe3a3756a1 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/common/util/SecurityUtility.java
@@ -549,7 +549,7 @@ public class SecurityUtility {
SslContextFactory sslCtxFactory = null;
if (autoRefresh) {
sslCtxFactory = new SslContextFactoryWithAutoRefresh(tlsAllowInsecureConnection, tlsTrustCertsFilePath,
- tlsCertificateFilePath, tlsKeyFilePath, tlsRequireTrustedClientCertOnConnect, 0);
+ tlsCertificateFilePath, tlsKeyFilePath, tlsRequireTrustedClientCertOnConnect, certRefreshInSec);
} else {
sslCtxFactory = new SslContextFactory();
SSLContext sslCtx = createSslContext(tlsAllowInsecureConnection, tlsTrustCertsFilePath,