Skip to content

Commit

Permalink
[security] Allow to config web server's cipher and protocols (#13354)
Browse files Browse the repository at this point in the history
  • Loading branch information
shoothzj authored Jan 7, 2022
1 parent 2c2cd14 commit b540523
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 33 deletions.
10 changes: 10 additions & 0 deletions conf/broker.conf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ webServicePort=8080
# Port to use to server HTTPS request - By default TLS is disabled
webServicePortTls=

# Specify the tls protocols the broker'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 broker will use to negotiate during TLS Handshake
# (a comma-separated list of ciphers).
# Examples:- [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
webServiceTlsCiphers=

# Hostname or IP address the service binds on, default is 0.0.0.0.
bindAddress=0.0.0.0

Expand Down
10 changes: 10 additions & 0 deletions conf/proxy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ webServicePort=8080
# Port to use to server HTTPS request
webServicePortTls=

# 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=

# Path for the file used to determine the rotation status for the proxy instance when responding
# to service discovery health checks
statusFilePath=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,20 @@ public class ServiceConfiguration implements PulsarConfiguration {
)
private Optional<Integer> webServicePortTls = Optional.empty();

@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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ public WebService(PulsarService pulsar) throws PulsarServerException {
config.getTlsTrustStore(),
config.getTlsTrustStorePassword(),
config.isTlsRequireTrustedClientCertOnConnect(),
config.getWebServiceTlsCiphers(),
config.getWebServiceTlsProtocols(),
config.getTlsCertRefreshCheckDurationSec()
);
} else {
Expand Down
14 changes: 14 additions & 0 deletions pulsar-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,20 @@
<optional>true</optional>
</dependency>

<!-- test -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>${bouncycastlefips.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,29 @@
*/
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;

import java.util.Set;

/**
* SslContextFactoryWithAutoRefresh that create SSLContext for web server, and refresh in time.
*/
public class SslContextFactoryWithAutoRefresh extends SslContextFactory {
public class JettySslContextFactoryWithAutoRefresh extends SslContextFactory.Server {
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 {
public JettySslContextFactoryWithAutoRefresh(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) {
super();
sslCtxRefresher = new NetSslContextBuilder(
sslProviderString,
Expand All @@ -54,6 +53,12 @@ public SslContextFactoryWithAutoRefresh(String sslProviderString,
trustStorePassword,
requireTrustedClientCertOnConnect,
certRefreshInSec);
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) {
setProvider(sslProviderString);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ public static KeyStoreSSLContext createServerKeyStoreSslContext(String sslProvid
return keyStoreSSLContext;
}

// for web server use case, no need ciphers and protocols
// the web server only use this method to get SSLContext, it won't use this to configure engine
// no need ciphers and protocols
public static SSLContext createServerSslContext(String sslProviderString,
String keyStoreTypeString,
String keyStorePath,
Expand Down Expand Up @@ -339,18 +340,19 @@ public static SSLContext createClientSslContext(String keyStoreTypeString,
}

// 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;
public static SslContextFactory.Server createSslContextFactory(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) {
SslContextFactory.Server sslCtxFactory;

if (sslProviderString == null) {
Provider provider = SecurityUtility.CONSCRYPT_PROVIDER;
Expand All @@ -359,7 +361,7 @@ public static SslContextFactory createSslContextFactory(String sslProviderString
}
}

sslCtxFactory = new SslContextFactoryWithAutoRefresh(
sslCtxFactory = new JettySslContextFactoryWithAutoRefresh(
sslProviderString,
keyStoreTypeString,
keyStore,
Expand All @@ -369,6 +371,8 @@ public static SslContextFactory createSslContextFactory(String sslProviderString
trustStore,
trustStorePassword,
requireTrustedClientCertOnConnect,
ciphers,
protocols,
certRefreshInSec);

if (requireTrustedClientCertOnConnect) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
*/
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.apache.pulsar.common.util.FileModifiedTimeUpdater;
import org.apache.pulsar.common.util.SslContextAutoRefreshBuilder;

Expand Down Expand Up @@ -70,7 +68,7 @@ public NetSslContextBuilder(String sslProviderString,

@Override
public synchronized SSLContext update()
throws SSLException, FileNotFoundException, GeneralSecurityException, IOException {
throws GeneralSecurityException, IOException {
this.sslContext = KeyStoreSSLContext.createServerSslContext(tlsProvider,
tlsKeyStoreType, tlsKeyStore.getFileName(), tlsKeyStorePassword,
tlsAllowInsecureConnection,
Expand Down
Loading

0 comments on commit b540523

Please sign in to comment.