如何在 Java 中禁用 Elasticsearch RestClient v6.7.0 的 SSL 验证

Sah*_*hil 4 java elasticsearch

我正在尝试连接到 ssh 隧道后面的 elasticsearch 实例。elasticsearch 实例的域*.ap-south-1.es.amazonaws.com在隧道本地时,我通过localhost:9201.

这是我用来连接到elasticsearch的代码

RestHighLevelClient(RestClient.builder(HttpHost("localhost", 9201, "https")))
Run Code Online (Sandbox Code Playgroud)

我收到以下错误

javax.net.ssl.SSLPeerUnverifiedException: Host name 'localhost' does not match the certificate subject provided by the peer (CN=*.ap-south-1.es.amazonaws.com)
Run Code Online (Sandbox Code Playgroud)

我在使用 PHP-Elasticsearch 时遇到了这个错误,我使用

$esClient->setSSLVerification(false);
Run Code Online (Sandbox Code Playgroud)

我希望为 Java RestClient 找到类似的方法。

Anu*_*ree 7

我希望这能给出一个完整的答案。

希望这对您有帮助,我遇到了同样的问题,这就是我解决的方法。

    @Bean
        public RestHighLevelClient createSimpleElasticClient() throws Exception {
            try {
                SSLContextBuilder sslBuilder = SSLContexts.custom()
                        .loadTrustMaterial(null, (x509Certificates, s) -> true);
                        final SSLContext sslContext = sslBuilder.build();
                RestHighLevelClient client = new RestHighLevelClient(RestClient
                        .builder(new HttpHost(hostNameOrLoadbalancerURL, 443, "https")) 
//port number is given as 443 since its https schema
                        .setHttpClientConfigCallback(new HttpClientConfigCallback() {
                            @Override
                            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                                return httpClientBuilder
                                         .setSSLContext(sslContext)
                                         .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
                            }
                        })
                        .setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
                            @Override
                            public RequestConfig.Builder customizeRequestConfig(
                                    RequestConfig.Builder requestConfigBuilder) {
                                return requestConfigBuilder.setConnectTimeout(5000)
                                        .setSocketTimeout(120000);
                            }
                        }));
                System.out.println("elasticsearch client created");
                return client;
            } catch (Exception e) {
                System.out.println(e);
                throw new Exception("Could not create an elasticsearch client!!");
            }
        }
Run Code Online (Sandbox Code Playgroud)


AMA*_*AMA 5

由于证书中的主机名不是 localhost,您将遇到此问题,因此要解决此问题,您需要禁用 SSL 主机名验证,通过执行以下操作,您将始终返回 true,这将跳过验证。

RestClientBuilder restClientBuilder =  RestClient.builder(HttpHost);
restClientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder ->
   httpAsyncClientBuilder.setSSLHostnameVerifier((s, sslSession) -> true));
new RestHighLevelClient(restClientBuilder);
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是比较明显的。无论 SSL 会话行为如何,“setSSLHostnameVerifier()”都将返回“true”。 (2认同)

Hri*_*nda 4

为此,您必须禁用一项使用您提供的名称验证主机名的设置。这是 apache 中 HTTPClient 的错误,您必须虚拟化在 setSSLHostnameVerifier 方法中验证的主机名,如下所示。

虽然这段代码是用 Kotlin 编写的,但可以轻松编写 java 替代品

val builder = RestClient.builder(host).setHttpClientConfigCallback { httpAsyncClientBuilder ->
            httpAsyncClientBuilder.setSSLHostnameVerifier { _, _ -> true }
        }
Run Code Online (Sandbox Code Playgroud)

这将始终覆盖您用于验证主机名是否为 true 的设置。

这里是Java代码参考。

RestClientBuilder builder =  RestClient.builder(host);
builder.setHttpClientConfigCallback(httpAsyncClientBuilder ->
   httpAsyncClientBuilder.setSSLHostnameVerifier((host, sslSession) -> true));
new RestHighLevelClient(builder);
Run Code Online (Sandbox Code Playgroud)