diff --git a/src/main/java/org/elasticsearch/shield/transport/netty/NettySecuredTransport.java b/src/main/java/org/elasticsearch/shield/transport/netty/NettySecuredTransport.java index 2d7bafb1c5f..ebbd33b99c2 100644 --- a/src/main/java/org/elasticsearch/shield/transport/netty/NettySecuredTransport.java +++ b/src/main/java/org/elasticsearch/shield/transport/netty/NettySecuredTransport.java @@ -66,7 +66,8 @@ public class NettySecuredTransport extends NettyTransport { @Override public ChannelPipeline getPipeline() throws Exception { ChannelPipeline pipeline = super.getPipeline(); - if (ssl) { + boolean profileSsl = profileSettings.getAsBoolean("shield.ssl", ssl); + if (profileSsl) { SSLEngine serverEngine; if (profileSettings.get("shield.truststore.path") != null) { serverEngine = sslService.createSSLEngine(profileSettings.getByPrefix("shield.")); diff --git a/src/test/java/org/elasticsearch/shield/transport/netty/NettySecuredTransportTests.java b/src/test/java/org/elasticsearch/shield/transport/netty/NettySecuredTransportTests.java new file mode 100644 index 00000000000..070fc7eb787 --- /dev/null +++ b/src/test/java/org/elasticsearch/shield/transport/netty/NettySecuredTransportTests.java @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.shield.transport.netty; + +import org.elasticsearch.Version; +import org.elasticsearch.common.netty.OpenChannelsHandler; +import org.elasticsearch.common.netty.channel.ChannelPipelineFactory; +import org.elasticsearch.common.netty.handler.ssl.SslHandler; +import org.elasticsearch.common.network.NetworkService; +import org.elasticsearch.common.settings.ImmutableSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.shield.ssl.SSLService; +import org.elasticsearch.test.ElasticsearchTestCase; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.netty.NettyTransport; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; +import static org.mockito.Mockito.mock; +import static org.hamcrest.Matchers.*; + +public class NettySecuredTransportTests extends ElasticsearchTestCase { + + private SSLService sslService; + + @Before + public void createSSLService() throws Exception { + Path testnodeStore = Paths.get(getClass().getResource("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode.jks").toURI()); + sslService = new SSLService(settingsBuilder() + .put("shield.ssl.keystore.path", testnodeStore) + .put("shield.ssl.keystore.password", "testnode") + .build()); + } + + @Test + public void testThatSSLCanBeDisabledByProfile() throws Exception { + Settings settings = ImmutableSettings.builder().put("shield.transport.ssl", true).build(); + NettySecuredTransport transport = new NettySecuredTransport(settings, mock(ThreadPool.class), mock(NetworkService.class), mock(BigArrays.class), Version.CURRENT, null, sslService); + setOpenChannelsHandlerToMock(transport); + ChannelPipelineFactory factory = transport.configureServerChannelPipelineFactory("client", ImmutableSettings.builder().put("shield.ssl", false).build()); + assertThat(factory.getPipeline().get(SslHandler.class), nullValue()); + } + + @Test + public void testThatSSLCanBeEnabledByProfile() throws Exception { + Settings settings = ImmutableSettings.builder().put("shield.transport.ssl", false).build(); + NettySecuredTransport transport = new NettySecuredTransport(settings, mock(ThreadPool.class), mock(NetworkService.class), mock(BigArrays.class), Version.CURRENT, null, sslService); + setOpenChannelsHandlerToMock(transport); + ChannelPipelineFactory factory = transport.configureServerChannelPipelineFactory("client", ImmutableSettings.builder().put("shield.ssl", true).build()); + assertThat(factory.getPipeline().get(SslHandler.class), notNullValue()); + } + + @Test + public void testThatProfileTakesDefaultSSLSetting() throws Exception { + Settings settings = ImmutableSettings.builder().put("shield.transport.ssl", true).build(); + NettySecuredTransport transport = new NettySecuredTransport(settings, mock(ThreadPool.class), mock(NetworkService.class), mock(BigArrays.class), Version.CURRENT, null, sslService); + setOpenChannelsHandlerToMock(transport); + ChannelPipelineFactory factory = transport.configureServerChannelPipelineFactory("client", ImmutableSettings.EMPTY); + assertThat(factory.getPipeline().get(SslHandler.class), notNullValue()); + } + + /* + * We don't really need to start Netty for these tests, but we can't create a pipeline + * with a null handler. So we set it to a mock for this test using reflection. + */ + private void setOpenChannelsHandlerToMock(NettyTransport transport) throws Exception { + Field serverOpenChannels = NettyTransport.class.getDeclaredField("serverOpenChannels"); + serverOpenChannels.setAccessible(true); + serverOpenChannels.set(transport, mock(OpenChannelsHandler.class)); + } +} diff --git a/src/test/java/org/elasticsearch/shield/transport/ssl/SslMultiPortTests.java b/src/test/java/org/elasticsearch/shield/transport/ssl/SslMultiPortTests.java index a7b62f633ec..8ef4b8093ed 100644 --- a/src/test/java/org/elasticsearch/shield/transport/ssl/SslMultiPortTests.java +++ b/src/test/java/org/elasticsearch/shield/transport/ssl/SslMultiPortTests.java @@ -23,21 +23,26 @@ import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilde import static org.elasticsearch.shield.transport.support.TransportProfileUtil.getProfilePort; import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope; import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope; +import static org.elasticsearch.test.ShieldSettingsSource.DEFAULT_USER_NAME; +import static org.elasticsearch.test.ShieldSettingsSource.DEFAULT_PASSWORD; import static org.hamcrest.CoreMatchers.is; @ClusterScope(scope = Scope.SUITE) public class SslMultiPortTests extends ShieldIntegrationTest { private static int randomClientPort; + private static int randomNonSslPort; @BeforeClass public static void getRandomPort() { randomClientPort = randomIntBetween(49000, 65500); // ephemeral port + randomNonSslPort = randomIntBetween(49000, 65500); } @Override protected Settings nodeSettings(int nodeOrdinal) { String randomClientPortRange = randomClientPort + "-" + (randomClientPort+100); + String randomNonSslPortRange = randomNonSslPort + "-" + (randomNonSslPort+100); File store; try { @@ -54,6 +59,9 @@ public class SslMultiPortTests extends ShieldIntegrationTest { .put("transport.profiles.client.bind_host", "localhost") // make sure this is "localhost", no matter if ipv4 or ipv6, but be consistent .put("transport.profiles.client.shield.truststore.path", store.getAbsolutePath()) // settings for client truststore .put("transport.profiles.client.shield.truststore.password", "testnode-client-profile") + .put("transport.profiles.no_ssl.port", randomNonSslPortRange) + .put("transport.profiles.no_ssl.bind_host", "localhost") + .put("transport.profiles.no_ssl.shield.ssl", "false") .build(); } @@ -102,4 +110,24 @@ public class SslMultiPortTests extends ShieldIntegrationTest { transportClient.admin().cluster().prepareHealth().get(); } } + + @Test + public void testThatTransportClientCanConnectToNoSslProfile() throws Exception { + Settings settings = ImmutableSettings.builder() + .put("shield.user", DEFAULT_USER_NAME + ":" + DEFAULT_PASSWORD) + .put("cluster.name", internalCluster().getClusterName()) + .build(); + try (TransportClient transportClient = new TransportClient(settings, false)) { + transportClient.addTransportAddress(new InetSocketTransportAddress("localhost", getProfilePort("no_ssl", internalCluster()))); + assertGreenClusterState(transportClient); + } + } + + @Test(expected = NoNodeAvailableException.class) + public void testThatStandardTransportClientCannotConnectToNoSslProfile() throws Exception { + try (TransportClient transportClient = createTransportClient(ImmutableSettings.EMPTY)) { + transportClient.addTransportAddress(new InetSocketTransportAddress("localhost", getProfilePort("no_ssl", internalCluster()))); + assertGreenClusterState(transportClient); + } + } }