forked from opensearch-project/security
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TLS related tests. (opensearch-project#2156)
This PR introduced negative test cases related to TLS. Almost all integration tests use TLS so this feature is already pretty well tested. Signed-off-by: Lukasz Soszynski <[email protected]> Signed-off-by: Lukasz Soszynski <[email protected]> Signed-off-by: Stephen Crawford <[email protected]>
- Loading branch information
1 parent
222f63d
commit 3dd6441
Showing
12 changed files
with
320 additions
and
52 deletions.
There are no files selected for viewing
69 changes: 69 additions & 0 deletions
69
src/integrationTest/java/org/opensearch/security/SslOnlyTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
* | ||
*/ | ||
package org.opensearch.security; | ||
|
||
import java.util.Map; | ||
|
||
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; | ||
import org.junit.ClassRule; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
||
import org.opensearch.security.support.ConfigConstants; | ||
import org.opensearch.test.framework.cluster.ClusterManager; | ||
import org.opensearch.test.framework.cluster.LocalCluster; | ||
import org.opensearch.test.framework.cluster.TestRestClient; | ||
import org.opensearch.test.framework.cluster.TestRestClient.HttpResponse; | ||
|
||
import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; | ||
|
||
/** | ||
* Test related to SSL-only mode of security plugin. In this mode, the security plugin is responsible only for TLS/SSL encryption. | ||
* Therefore, the plugin does not perform authentication and authorization. Moreover, the REST resources (e.g. /_plugins/_security/whoami, | ||
* /_plugins/_security/authinfo, etc.) provided by the plugin are not available. | ||
*/ | ||
@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) | ||
@ThreadLeakScope(ThreadLeakScope.Scope.NONE) | ||
public class SslOnlyTests { | ||
|
||
|
||
@ClassRule | ||
public static LocalCluster cluster = new LocalCluster.Builder() | ||
.clusterManager(ClusterManager.THREE_CLUSTER_MANAGERS).anonymousAuth(false) | ||
.loadConfigurationIntoIndex(false) | ||
.nodeSettings(Map.of(ConfigConstants.SECURITY_SSL_ONLY, true)) | ||
.sslOnly(true) | ||
.authc(AUTHC_HTTPBASIC_INTERNAL).build(); | ||
|
||
@Test | ||
public void shouldNotLoadSecurityPluginResources() { | ||
try(TestRestClient client = cluster.getRestClient()) { | ||
|
||
HttpResponse response = client.getAuthInfo(); | ||
|
||
// in SSL only mode the security plugin does not register a handler for resource /_plugins/_security/whoami. Therefore error | ||
// response is returned. | ||
response.assertStatusCode(400); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldGetIndicesWithoutAuthentication() { | ||
try(TestRestClient client = cluster.getRestClient()) { | ||
|
||
// request does not contains credential | ||
HttpResponse response = client.get("/_cat/indices"); | ||
|
||
// successful response is returned because the security plugin in SSL only mode | ||
// does not perform authentication and authorization | ||
response.assertStatusCode(200); | ||
} | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
src/integrationTest/java/org/opensearch/security/TlsTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
* | ||
*/ | ||
package org.opensearch.security; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import javax.net.ssl.SSLHandshakeException; | ||
|
||
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; | ||
import org.apache.hc.client5.http.classic.methods.HttpGet; | ||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; | ||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; | ||
import org.apache.hc.client5.http.impl.classic.HttpClients; | ||
import org.apache.hc.core5.http.NoHttpResponseException; | ||
import org.apache.hc.core5.http.message.BasicHeader; | ||
import org.junit.ClassRule; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
||
import org.opensearch.test.framework.TestSecurityConfig.User; | ||
import org.opensearch.test.framework.cluster.ClusterManager; | ||
import org.opensearch.test.framework.cluster.LocalCluster; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.equalTo; | ||
import static org.hamcrest.Matchers.instanceOf; | ||
import static org.opensearch.security.ssl.util.SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_CIPHERS; | ||
import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; | ||
import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; | ||
import static org.opensearch.test.framework.matcher.ExceptionMatcherAssert.assertThatThrownBy; | ||
|
||
@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) | ||
@ThreadLeakScope(ThreadLeakScope.Scope.NONE) | ||
public class TlsTests { | ||
|
||
private static final User USER_ADMIN = new User("admin").roles(ALL_ACCESS); | ||
|
||
public static final String SUPPORTED_CIPHER_SUIT = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; | ||
public static final String NOT_SUPPORTED_CIPHER_SUITE = "TLS_RSA_WITH_AES_128_CBC_SHA"; | ||
public static final String AUTH_INFO_ENDPOINT = "/_opendistro/_security/authinfo?pretty"; | ||
|
||
@ClassRule | ||
public static LocalCluster cluster = new LocalCluster.Builder() | ||
.clusterManager(ClusterManager.THREE_CLUSTER_MANAGERS).anonymousAuth(false) | ||
.nodeSettings(Map.of(SECURITY_SSL_HTTP_ENABLED_CIPHERS, List.of(SUPPORTED_CIPHER_SUIT))) | ||
.authc(AUTHC_HTTPBASIC_INTERNAL).users(USER_ADMIN).build(); | ||
|
||
@Test | ||
public void shouldCreateAuditOnIncomingNonTlsConnection() throws IOException { | ||
try(CloseableHttpClient httpClient = HttpClients.createDefault()) { | ||
HttpGet request = new HttpGet("http://localhost:" + cluster.getHttpPort()); | ||
|
||
assertThatThrownBy(() -> httpClient.execute(request), instanceOf(NoHttpResponseException.class)); | ||
} | ||
//TODO check if audit is created, audit_category = SSL_EXCEPTION | ||
} | ||
|
||
@Test | ||
public void shouldSupportClientCipherSuite_positive() throws IOException { | ||
try(CloseableHttpClient client = cluster.getClosableHttpClient(new String[] { SUPPORTED_CIPHER_SUIT })) { | ||
HttpGet httpGet = new HttpGet("https://localhost:" + cluster.getHttpPort() + AUTH_INFO_ENDPOINT); | ||
BasicHeader header = cluster.getBasicAuthHeader(USER_ADMIN.getName(), USER_ADMIN.getPassword()); | ||
httpGet.addHeader(header); | ||
|
||
try(CloseableHttpResponse response = client.execute(httpGet)) { | ||
|
||
int responseStatusCode = response.getCode(); | ||
assertThat(responseStatusCode, equalTo(200)); | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldSupportClientCipherSuite_negative() throws IOException { | ||
try(CloseableHttpClient client = cluster.getClosableHttpClient(new String[]{ NOT_SUPPORTED_CIPHER_SUITE })) { | ||
HttpGet httpGet = new HttpGet("https://localhost:" + cluster.getHttpPort() + AUTH_INFO_ENDPOINT); | ||
|
||
assertThatThrownBy(() -> client.execute(httpGet), instanceOf(SSLHandshakeException.class)); | ||
} | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
...ntegrationTest/java/org/opensearch/test/framework/cluster/CloseableHttpClientFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
* | ||
*/ | ||
package org.opensearch.test.framework.cluster; | ||
|
||
import java.util.Objects; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import javax.net.ssl.SSLContext; | ||
|
||
import org.apache.hc.client5.http.config.RequestConfig; | ||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; | ||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; | ||
import org.apache.hc.client5.http.impl.classic.HttpClients; | ||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; | ||
import org.apache.hc.client5.http.io.HttpClientConnectionManager; | ||
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; | ||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; | ||
import org.apache.hc.core5.http.io.SocketConfig; | ||
|
||
class CloseableHttpClientFactory { | ||
|
||
private final SSLContext sslContext; | ||
|
||
private final RequestConfig requestConfig; | ||
|
||
private final String[] supportedCipherSuit; | ||
|
||
public CloseableHttpClientFactory(SSLContext sslContext, RequestConfig requestConfig, String[] supportedCipherSuit) { | ||
this.sslContext = Objects.requireNonNull(sslContext, "SSL context is required."); | ||
this.requestConfig = requestConfig; | ||
this.supportedCipherSuit = supportedCipherSuit; | ||
} | ||
|
||
public CloseableHttpClient getHTTPClient() { | ||
|
||
final HttpClientBuilder hcb = HttpClients.custom(); | ||
|
||
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(this.sslContext, null, supportedCipherSuit, | ||
NoopHostnameVerifier.INSTANCE); | ||
|
||
final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() | ||
.setSSLSocketFactory(sslsf) | ||
.setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(60, TimeUnit.SECONDS).build()) | ||
.build(); | ||
hcb.setConnectionManager(cm); | ||
|
||
if (requestConfig != null) { | ||
hcb.setDefaultRequestConfig(requestConfig); | ||
} | ||
|
||
return hcb.build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.