injectable sslcontextfactory for jetty server and key manager factory algorithm (#4769)

* injectable sslcontextfactory for jetty server

key manager factory algorithm

* explicitly set trustAll certificates to false in sslcontextfactory
This commit is contained in:
Parag Jain 2017-09-12 13:45:03 -05:00 committed by Gian Merlino
parent 6f3e52b3db
commit b5e839b3db
4 changed files with 50 additions and 12 deletions

View File

@ -30,6 +30,7 @@ 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.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.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's internal communication over TLS
@ -42,5 +43,5 @@ Since, there are various ways to configure SSLContext, by default, Druid looks f
while creating the HttpClient. This binding can be achieved writing a [Druid extension](../development/extensions.html)
which can provide an instance of SSLContext. Druid comes with a simple extension present [here](../development/extensions-core/simple-client-sslcontext.html)
which should be useful enough for most simple cases, see [this](./including-extensions.html) for how to include extensions.
If this extension does not satisfy the requirement then please follow the extension [implementation] (https://github.com/druid-io/druid/tree/master/extensions-core/simple-client-sslcontext)
If this extension does not satisfy the requirements then please follow the extension [implementation](https://github.com/druid-io/druid/tree/master/extensions-core/simple-client-sslcontext)
to create your own extension.

View File

@ -32,6 +32,9 @@ public class TLSServerConfig
@JsonProperty
private String certAlias;
@JsonProperty
private String keyManagerFactoryAlgorithm;
@JsonProperty("keyStorePassword")
private PasswordProvider keyStorePasswordProvider;
@ -63,6 +66,11 @@ public class TLSServerConfig
return keyManagerPasswordProvider;
}
public String getKeyManagerFactoryAlgorithm()
{
return keyManagerFactoryAlgorithm;
}
@Override
public String toString()
{
@ -70,6 +78,7 @@ public class TLSServerConfig
"keyStorePath='" + keyStorePath + '\'' +
", keyStoreType='" + keyStoreType + '\'' +
", certAlias='" + certAlias + '\'' +
", keyManagerFactoryAlgorithm='" + keyManagerFactoryAlgorithm + '\'' +
'}';
}
}

View File

@ -25,7 +25,6 @@ import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.multibindings.Multibinder;
import io.druid.guice.Jerseys;
import io.druid.guice.JsonConfigProvider;
import io.druid.guice.LazySingleton;
@ -40,6 +39,7 @@ import io.druid.server.initialization.ServerConfig;
import io.druid.server.initialization.TLSServerConfig;
import io.druid.server.metrics.DataSourceTaskIdHolder;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import java.util.Properties;
@ -120,7 +120,12 @@ public class ChatHandlerServerModule implements Module
@RemoteChatHandler TLSServerConfig TLSServerConfig
)
{
final Server server = JettyServerModule.makeJettyServer(node, config, TLSServerConfig);
final Server server = JettyServerModule.makeJettyServer(
node,
config,
TLSServerConfig,
injector.getExistingBinding(Key.get(SslContextFactory.class))
);
JettyServerModule.initializeServer(injector, lifecycle, server);
return server;
}

View File

@ -25,9 +25,11 @@ import com.fasterxml.jackson.jaxrs.smile.JacksonSmileProvider;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Ints;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.ConfigurationException;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provides;
import com.google.inject.ProvisionException;
import com.google.inject.Scopes;
@ -71,6 +73,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import javax.net.ssl.KeyManagerFactory;
import javax.servlet.ServletException;
import java.util.ArrayList;
import java.util.List;
@ -144,7 +147,12 @@ public class JettyServerModule extends JerseyServletModule
final TLSServerConfig TLSServerConfig
)
{
final Server server = makeJettyServer(node, config, TLSServerConfig);
final Server server = makeJettyServer(
node,
config,
TLSServerConfig,
injector.getExistingBinding(Key.get(SslContextFactory.class))
);
initializeServer(injector, lifecycle, server);
return server;
}
@ -167,7 +175,12 @@ public class JettyServerModule extends JerseyServletModule
return provider;
}
static Server makeJettyServer(DruidNode node, ServerConfig config, TLSServerConfig tlsServerConfig)
static Server makeJettyServer(
DruidNode node,
ServerConfig config,
TLSServerConfig tlsServerConfig,
Binding<SslContextFactory> sslContextFactoryBinding
)
{
final QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setMinThreads(config.getNumThreads());
@ -190,13 +203,23 @@ public class JettyServerModule extends JerseyServletModule
}
if (config.isTls()) {
log.info("Creating https connector with port [%d]", node.getTlsPort());
final SslContextFactory sslContextFactory = new SslContextFactory(tlsServerConfig.getKeyStorePath());
sslContextFactory.setKeyStoreType(tlsServerConfig.getKeyStoreType());
sslContextFactory.setKeyStorePassword(tlsServerConfig.getKeyStorePasswordProvider().getPassword());
sslContextFactory.setCertAlias(tlsServerConfig.getCertAlias());
sslContextFactory.setKeyManagerPassword(tlsServerConfig.getKeyManagerPasswordProvider() == null
? null
: tlsServerConfig.getKeyManagerPasswordProvider().getPassword());
final SslContextFactory sslContextFactory;
if (sslContextFactoryBinding == null) {
// Never trust all certificates by default
sslContextFactory = new SslContextFactory(false);
sslContextFactory.setKeyStorePath(tlsServerConfig.getKeyStorePath());
sslContextFactory.setKeyStoreType(tlsServerConfig.getKeyStoreType());
sslContextFactory.setKeyStorePassword(tlsServerConfig.getKeyStorePasswordProvider().getPassword());
sslContextFactory.setCertAlias(tlsServerConfig.getCertAlias());
sslContextFactory.setKeyManagerFactoryAlgorithm(tlsServerConfig.getKeyManagerFactoryAlgorithm() == null
? KeyManagerFactory.getDefaultAlgorithm()
: tlsServerConfig.getKeyManagerFactoryAlgorithm());
sslContextFactory.setKeyManagerPassword(tlsServerConfig.getKeyManagerPasswordProvider() == null ? null
: tlsServerConfig.getKeyManagerPasswordProvider().getPassword());
} else {
sslContextFactory = sslContextFactoryBinding.getProvider().get();
}
final HttpConfiguration httpsConfiguration = new HttpConfiguration();
httpsConfiguration.setSecureScheme("https");
httpsConfiguration.setSecurePort(node.getTlsPort());