4

Am hoping to use localstack to simulate elasticsearch/kinesis/dynamo. Am running into troubles with my elastic code wanting HTTPS endpoints.

Testing via java 11/IntelliJ

In all cases am hitting this error:

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: 
 sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid 
 certification path to requested target

I've tried:

  • Starting localstack with the USE_SSL environment variable set. curl commands (EG "curl -k https://localhost:port") for elastic work but java does not.
  • Using localstack annotations ("@RunWith(LocalstackDockerTestRunner.class)" and passing in "USE_SSL" as a param - no go
  • Telling Java to ignore "bad" certs via System.setProperty(SDKGlobalConfiguration.DISABLE_CERT_CHECKING_SYSTEM_PROPERTY, "true"); - no go
  • Passing cmdline param -Dcom.amazonaws.sdk.disableCertChecking - no go

I feel like what Im looking for is doable.. just can't seem to find the right combination of settings.

acme-j
  • 99
  • 10
  • Have you tried looking into [these answers](https://stackoverflow.com/questions/1219208/is-it-possible-to-get-java-to-ignore-the-trust-store-and-just-accept-whatever)? – nimrodm Sep 24 '19 at 03:56
  • Just did. Nothing different - same error(s). I feel like AWS is ignoring all the "trust everything" messages; – acme-j Sep 24 '19 at 16:05
  • How are you accessing Elasticsearch? Using some ready made library? Using java's original HTTPSURLConnection? Using Apache HTTPClient? Using Java11 new HttpClient? – nimrodm Sep 24 '19 at 17:09
  • Using the RestHighLevelClient - which is injected – acme-j Sep 24 '19 at 22:19
  • 1
    How did you run your java application from cmdline? `java -Dcom.amazonaws.sdk.disableCertChecking -jar my.jar` or `java -jar my.jar -Dcom.amazonaws.sdk.disableCertChecking`? The first version should work. The position where you place this, makes a huge difference. – philnate Sep 25 '19 at 15:56

1 Answers1

0

If you are creating the RestHighLevelClient yourself (or control the creation of this object), you can use the constructor that accepts a RestClientBuilder.

Use RestClient.builder() method to create a RestClientBuilder with a custom SSLContext. The following is from Elasticsearch source code:

        RestClientBuilder builder = RestClient.builder(
            new HttpHost("localhost", 9200, "https"))
            .setHttpClientConfigCallback(new HttpClientConfigCallback() {
                @Override
                public HttpAsyncClientBuilder customizeHttpClient(
                        HttpAsyncClientBuilder httpClientBuilder) {
                    return httpClientBuilder.setSSLContext(sslContext);
                }
            });

In your case you need to create an SSLContext that trusts all hosts:

SSLContext context = SSLContext.getInstance("SSL")
context.init(null, new TrustManager[] {
  new X509TrustManager {
    void checkClientTrusted(X509Certificate[] chain, String authType) {}
    void checkServerTrusted(X509Certificate[] chain, String authType) {}
    void getAcceptedIssuers() { return null; }
  }
}, null);

The above is completely untested but may get you started. Feel free to update this answer with more details if it works for you.

nimrodm
  • 23,081
  • 7
  • 58
  • 59