mirror of
https://github.com/apache/druid.git
synced 2025-02-20 00:47:40 +00:00
add more tls configs to enable/disable specific cipher suites and protocols (#4902)
* add more tls configs to enable/disable specific cipher suites and protocols * fix doc, allow empty list
This commit is contained in:
parent
797b54d283
commit
7cc18226cd
@ -30,8 +30,17 @@ values for the below mentioned configs among others provided by Java implementat
|
|||||||
|`druid.server.https.keyStoreType`|The type of the key store.|none|yes|
|
|`druid.server.https.keyStoreType`|The type of the key store.|none|yes|
|
||||||
|`druid.server.https.certAlias`|Alias of TLS/SSL certificate for the connector.|none|yes|
|
|`druid.server.https.certAlias`|Alias of TLS/SSL certificate for the connector.|none|yes|
|
||||||
|`druid.server.https.keyStorePassword`|The [Password Provider](../operations/password-provider.html) or String password for the Key Store.|none|yes|
|
|`druid.server.https.keyStorePassword`|The [Password Provider](../operations/password-provider.html) or String password for the Key Store.|none|yes|
|
||||||
|
|
||||||
|
Following table contains non-mandatory advanced configuration options, use caution.
|
||||||
|
|
||||||
|
|Property|Description|Default|Required|
|
||||||
|
|--------|-----------|-------|--------|
|
||||||
|`druid.server.https.keyManagerFactoryAlgorithm`|Algorithm to use for creating KeyManager, more details [here](https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#KeyManager).|`javax.net.ssl.KeyManagerFactory.getDefaultAlgorithm()`|no|
|
|`druid.server.https.keyManagerFactoryAlgorithm`|Algorithm to use for creating KeyManager, more details [here](https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#KeyManager).|`javax.net.ssl.KeyManagerFactory.getDefaultAlgorithm()`|no|
|
||||||
|`druid.server.https.keyManagerPassword`|The [Password Provider](../operations/password-provider.html) or String password for the Key Manager.|none|no|
|
|`druid.server.https.keyManagerPassword`|The [Password Provider](../operations/password-provider.html) or String password for the Key Manager.|none|no|
|
||||||
|
|`druid.server.https.includeCipherSuites`|List of cipher suite names to include. You can either use the exact cipher suite name or a regular expression.|Jetty's default include cipher list|no|
|
||||||
|
|`druid.server.https.excludeCipherSuites`|List of cipher suite names to exclude. You can either use the exact cipher suite name or a regular expression.|Jetty's default exclude cipher list|no|
|
||||||
|
|`druid.server.https.includeProtocols`|List of exact protocols names to include.|Jetty's default include protocol list|no|
|
||||||
|
|`druid.server.https.excludeProtocols`|List of exact protocols names to exclude.|Jetty's default exclude protocol list|no|
|
||||||
|
|
||||||
# Druid's internal communication over TLS
|
# Druid's internal communication over TLS
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ package io.druid.server.initialization;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import io.druid.metadata.PasswordProvider;
|
import io.druid.metadata.PasswordProvider;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class TLSServerConfig
|
public class TLSServerConfig
|
||||||
{
|
{
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@ -32,15 +34,27 @@ public class TLSServerConfig
|
|||||||
@JsonProperty
|
@JsonProperty
|
||||||
private String certAlias;
|
private String certAlias;
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
private String keyManagerFactoryAlgorithm;
|
|
||||||
|
|
||||||
@JsonProperty("keyStorePassword")
|
@JsonProperty("keyStorePassword")
|
||||||
private PasswordProvider keyStorePasswordProvider;
|
private PasswordProvider keyStorePasswordProvider;
|
||||||
|
|
||||||
@JsonProperty("keyManagerPassword")
|
@JsonProperty("keyManagerPassword")
|
||||||
private PasswordProvider keyManagerPasswordProvider;
|
private PasswordProvider keyManagerPasswordProvider;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private String keyManagerFactoryAlgorithm;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private List<String> includeCipherSuites;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private List<String> excludeCipherSuites;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private List<String> includeProtocols;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private List<String> excludeProtocols;
|
||||||
|
|
||||||
public String getKeyStorePath()
|
public String getKeyStorePath()
|
||||||
{
|
{
|
||||||
return keyStorePath;
|
return keyStorePath;
|
||||||
@ -71,6 +85,26 @@ public class TLSServerConfig
|
|||||||
return keyManagerFactoryAlgorithm;
|
return keyManagerFactoryAlgorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getIncludeCipherSuites()
|
||||||
|
{
|
||||||
|
return includeCipherSuites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getExcludeCipherSuites()
|
||||||
|
{
|
||||||
|
return excludeCipherSuites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getIncludeProtocols()
|
||||||
|
{
|
||||||
|
return includeProtocols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getExcludeProtocols()
|
||||||
|
{
|
||||||
|
return excludeProtocols;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
@ -79,6 +113,10 @@ public class TLSServerConfig
|
|||||||
", keyStoreType='" + keyStoreType + '\'' +
|
", keyStoreType='" + keyStoreType + '\'' +
|
||||||
", certAlias='" + certAlias + '\'' +
|
", certAlias='" + certAlias + '\'' +
|
||||||
", keyManagerFactoryAlgorithm='" + keyManagerFactoryAlgorithm + '\'' +
|
", keyManagerFactoryAlgorithm='" + keyManagerFactoryAlgorithm + '\'' +
|
||||||
|
", includeCipherSuites=" + includeCipherSuites +
|
||||||
|
", excludeCipherSuites=" + excludeCipherSuites +
|
||||||
|
", includeProtocols=" + includeProtocols +
|
||||||
|
", excludeProtocols=" + excludeProtocols +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,13 +120,13 @@ public class ChatHandlerServerModule implements Module
|
|||||||
@RemoteChatHandler TLSServerConfig TLSServerConfig
|
@RemoteChatHandler TLSServerConfig TLSServerConfig
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
final Server server = JettyServerModule.makeJettyServer(
|
return JettyServerModule.makeAndInitializeServer(
|
||||||
|
injector,
|
||||||
|
lifecycle,
|
||||||
node,
|
node,
|
||||||
config,
|
config,
|
||||||
TLSServerConfig,
|
TLSServerConfig,
|
||||||
injector.getExistingBinding(Key.get(SslContextFactory.class))
|
injector.getExistingBinding(Key.get(SslContextFactory.class))
|
||||||
);
|
);
|
||||||
JettyServerModule.initializeServer(injector, lifecycle, server);
|
|
||||||
return server;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ package io.druid.server.initialization.jetty;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
||||||
import com.fasterxml.jackson.jaxrs.smile.JacksonSmileProvider;
|
import com.fasterxml.jackson.jaxrs.smile.JacksonSmileProvider;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import com.google.inject.Binder;
|
import com.google.inject.Binder;
|
||||||
import com.google.inject.Binding;
|
import com.google.inject.Binding;
|
||||||
@ -48,6 +49,7 @@ import io.druid.guice.annotations.JSR311Resource;
|
|||||||
import io.druid.guice.annotations.Json;
|
import io.druid.guice.annotations.Json;
|
||||||
import io.druid.guice.annotations.Self;
|
import io.druid.guice.annotations.Self;
|
||||||
import io.druid.guice.annotations.Smile;
|
import io.druid.guice.annotations.Smile;
|
||||||
|
import io.druid.java.util.common.ISE;
|
||||||
import io.druid.java.util.common.RE;
|
import io.druid.java.util.common.RE;
|
||||||
import io.druid.java.util.common.lifecycle.Lifecycle;
|
import io.druid.java.util.common.lifecycle.Lifecycle;
|
||||||
import io.druid.java.util.common.logger.Logger;
|
import io.druid.java.util.common.logger.Logger;
|
||||||
@ -72,8 +74,10 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
|||||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
||||||
|
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -147,14 +151,14 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
final TLSServerConfig TLSServerConfig
|
final TLSServerConfig TLSServerConfig
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
final Server server = makeJettyServer(
|
return makeAndInitializeServer(
|
||||||
|
injector,
|
||||||
|
lifecycle,
|
||||||
node,
|
node,
|
||||||
config,
|
config,
|
||||||
TLSServerConfig,
|
TLSServerConfig,
|
||||||
injector.getExistingBinding(Key.get(SslContextFactory.class))
|
injector.getExistingBinding(Key.get(SslContextFactory.class))
|
||||||
);
|
);
|
||||||
initializeServer(injector, lifecycle, server);
|
|
||||||
return server;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@ -175,7 +179,9 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Server makeJettyServer(
|
static Server makeAndInitializeServer(
|
||||||
|
Injector injector,
|
||||||
|
Lifecycle lifecycle,
|
||||||
DruidNode node,
|
DruidNode node,
|
||||||
ServerConfig config,
|
ServerConfig config,
|
||||||
TLSServerConfig tlsServerConfig,
|
TLSServerConfig tlsServerConfig,
|
||||||
@ -216,9 +222,10 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
connector.setPort(node.getPlaintextPort());
|
connector.setPort(node.getPlaintextPort());
|
||||||
serverConnectors.add(connector);
|
serverConnectors.add(connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final SslContextFactory sslContextFactory;
|
||||||
if (node.isEnableTlsPort()) {
|
if (node.isEnableTlsPort()) {
|
||||||
log.info("Creating https connector with port [%d]", node.getTlsPort());
|
log.info("Creating https connector with port [%d]", node.getTlsPort());
|
||||||
final SslContextFactory sslContextFactory;
|
|
||||||
if (sslContextFactoryBinding == null) {
|
if (sslContextFactoryBinding == null) {
|
||||||
// Never trust all certificates by default
|
// Never trust all certificates by default
|
||||||
sslContextFactory = new SslContextFactory(false);
|
sslContextFactory = new SslContextFactory(false);
|
||||||
@ -229,8 +236,26 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
sslContextFactory.setKeyManagerFactoryAlgorithm(tlsServerConfig.getKeyManagerFactoryAlgorithm() == null
|
sslContextFactory.setKeyManagerFactoryAlgorithm(tlsServerConfig.getKeyManagerFactoryAlgorithm() == null
|
||||||
? KeyManagerFactory.getDefaultAlgorithm()
|
? KeyManagerFactory.getDefaultAlgorithm()
|
||||||
: tlsServerConfig.getKeyManagerFactoryAlgorithm());
|
: tlsServerConfig.getKeyManagerFactoryAlgorithm());
|
||||||
sslContextFactory.setKeyManagerPassword(tlsServerConfig.getKeyManagerPasswordProvider() == null ? null
|
sslContextFactory.setKeyManagerPassword(tlsServerConfig.getKeyManagerPasswordProvider() == null ?
|
||||||
: tlsServerConfig.getKeyManagerPasswordProvider().getPassword());
|
null : tlsServerConfig.getKeyManagerPasswordProvider().getPassword());
|
||||||
|
if (tlsServerConfig.getIncludeCipherSuites() != null) {
|
||||||
|
sslContextFactory.setIncludeCipherSuites(
|
||||||
|
tlsServerConfig.getIncludeCipherSuites()
|
||||||
|
.toArray(new String[tlsServerConfig.getIncludeCipherSuites().size()]));
|
||||||
|
}
|
||||||
|
if (tlsServerConfig.getExcludeCipherSuites() != null) {
|
||||||
|
sslContextFactory.setExcludeCipherSuites(
|
||||||
|
tlsServerConfig.getExcludeCipherSuites()
|
||||||
|
.toArray(new String[tlsServerConfig.getExcludeCipherSuites().size()]));
|
||||||
|
}
|
||||||
|
if (tlsServerConfig.getIncludeProtocols() != null) {
|
||||||
|
sslContextFactory.setIncludeProtocols(
|
||||||
|
tlsServerConfig.getIncludeProtocols().toArray(new String[tlsServerConfig.getIncludeProtocols().size()]));
|
||||||
|
}
|
||||||
|
if (tlsServerConfig.getExcludeProtocols() != null) {
|
||||||
|
sslContextFactory.setExcludeProtocols(
|
||||||
|
tlsServerConfig.getExcludeProtocols().toArray(new String[tlsServerConfig.getExcludeProtocols().size()]));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sslContextFactory = sslContextFactoryBinding.getProvider().get();
|
sslContextFactory = sslContextFactoryBinding.getProvider().get();
|
||||||
}
|
}
|
||||||
@ -246,6 +271,8 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
);
|
);
|
||||||
connector.setPort(node.getTlsPort());
|
connector.setPort(node.getTlsPort());
|
||||||
serverConnectors.add(connector);
|
serverConnectors.add(connector);
|
||||||
|
} else {
|
||||||
|
sslContextFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ServerConnector[] connectors = new ServerConnector[serverConnectors.size()];
|
final ServerConnector[] connectors = new ServerConnector[serverConnectors.size()];
|
||||||
@ -266,11 +293,7 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
|
|
||||||
server.setConnectors(connectors);
|
server.setConnectors(connectors);
|
||||||
|
|
||||||
return server;
|
// initialize server
|
||||||
}
|
|
||||||
|
|
||||||
static void initializeServer(Injector injector, Lifecycle lifecycle, final Server server)
|
|
||||||
{
|
|
||||||
JettyServerInitializer initializer = injector.getInstance(JettyServerInitializer.class);
|
JettyServerInitializer initializer = injector.getInstance(JettyServerInitializer.class);
|
||||||
try {
|
try {
|
||||||
initializer.initialize(server, injector);
|
initializer.initialize(server, injector);
|
||||||
@ -286,6 +309,27 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
public void start() throws Exception
|
public void start() throws Exception
|
||||||
{
|
{
|
||||||
server.start();
|
server.start();
|
||||||
|
if (node.isEnableTlsPort()) {
|
||||||
|
// Perform validation
|
||||||
|
Preconditions.checkNotNull(sslContextFactory);
|
||||||
|
final SSLEngine sslEngine = sslContextFactory.newSSLEngine();
|
||||||
|
if (sslEngine.getEnabledCipherSuites() == null || sslEngine.getEnabledCipherSuites().length == 0) {
|
||||||
|
throw new ISE(
|
||||||
|
"No supported cipher suites found, supported suites [%s], configured suites include list: [%s] exclude list: [%s]",
|
||||||
|
Arrays.toString(sslEngine.getSupportedCipherSuites()),
|
||||||
|
tlsServerConfig.getIncludeCipherSuites(),
|
||||||
|
tlsServerConfig.getExcludeCipherSuites()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (sslEngine.getEnabledProtocols() == null || sslEngine.getEnabledProtocols().length == 0) {
|
||||||
|
throw new ISE(
|
||||||
|
"No supported protocols found, supported protocols [%s], configured protocols include list: [%s] exclude list: [%s]",
|
||||||
|
Arrays.toString(sslEngine.getSupportedProtocols()),
|
||||||
|
tlsServerConfig.getIncludeProtocols(),
|
||||||
|
tlsServerConfig.getExcludeProtocols()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -300,6 +344,8 @@ public class JettyServerModule extends JerseyServletModule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getMaxJettyAcceptorsSelectorsNum(DruidNode druidNode)
|
private static int getMaxJettyAcceptorsSelectorsNum(DruidNode druidNode)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user