首页 > 解决方案 > 错误::收到致命警报:handshake_failure:javax.net.ssl.SSLHandshakeException,使用 java REST 客户端连接到弹性搜索时

问题描述

  1. java版本:1.8
  2. 弹性版本:7.10
  3. Ubuntu:18.04LTS

我正在尝试使用java连接到elasticsearch,我们已经使用xpack security设置了elastic中的安全性,并且elastic受密码保护并且工作正常但是当我尝试使用java建立安全的弹性连接时出现问题。

注意:Elasticsearch 和 java 都在不同的 linux 机器上。

我在 elasticsearch.yml 中添加了这些参数

cluster.name: la-test-elastic-2
network.host: 0.0.0.0
http.port: 9200
xpack.security.enable: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate 
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12 
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12

还为您的 Elasticsearch 集群创建了证书颁发机构。使用

bin/elasticsearch-certutil ca

并为集群中的每个节点生成证书和私钥。

使用 elasticsearch-certutil cert 命令:

bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

使用 REST 客户端的 java 代码

String keyStorePass = "";       
Path trustStorePath = Paths.get("lib/elastic-certificates.p12");
KeyStore truststore = KeyStore.getInstance("pkcs12");
try (InputStream is = Files.newInputStream(trustStorePath)) {
    truststore.load(is, keyStorePass.toCharArray());
}
SSLContextBuilder sslBuilder = SSLContexts.custom().loadTrustMaterial(truststore, null);
final SSLContext sslContext = sslBuilder.build();       
final CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "elastic"));
// 3. Changes for add multiple IP address
String[] hosts = elasticHost.split(",");
HttpHost[] httpHosts = Arrays.stream(hosts)
        .map(host -> new HttpHost(host.trim(), elasticPort, "https"))
        .collect(Collectors.toList())
        .toArray(new HttpHost[hosts.length]);
// 4. Build the low-level client
RestClientBuilder builder = RestClient.builder(httpHosts)
        .setHttpClientConfigCallback(new HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(
                    HttpAsyncClientBuilder httpClientBuilder) {

                        // set Basic credentials
                        httpClientBuilder.setDefaultCredentialsProvider(credsProvider);
                        // set SSL context
                        return httpClientBuilder.setSSLContext(sslContext);
                    }
        });  
// 5. Build the high-level client
client = new RestHighLevelClient(builder);
//try to search existing index
SearchRequest searchRequest = new SearchRequest("idx");
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println("searchResponse : " + searchResponse.toString());

我找到了上面的代码,但我的问题是我在 2 行代码中提到的路径,即:

Path trustStorePath = Paths.get("lib/elastic-certificates.p12");  // I try giving /etc/elasticsearch/elastic-certificates.p12 but getting no such file exception error

我的第二个疑问是:

KeyStore truststore = KeyStore.getInstance("pkcs12"); 

我应该在这里给出哪个文件

如果我在上面运行,那么我会收到这个错误:

Error: :Received fatal alert: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:860)
        at org.elasticsearch.client.RestClient.performRequest(RestClient.java:275)
        at org.elasticsearch.client.RestClient.performRequest(RestClient.java:262)
        at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1632)
        at org.elasticsearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1602)
        at org.elasticsearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1572)
        at org.elasticsearch.client.RestHighLevelClient.search(RestHighLevelClient.java:1088)
        at testsecureelastic.TestSecureElasticConnection.getElasticConnectionOther(TestSecureElasticConnection.java:164)
        at testsecureelastic.TestSecureElasticConnection.main(TestSecureElasticConnection.java:279)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:311)
        at sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
        at sun.security.ssl.TransportContext.dispatch(TransportContext.java:185)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:149)
        at sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:575)
        at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:531)
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:398)
        at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:377)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:626)
        at org.apache.http.nio.reactor.ssl.SSLIOSession.doUnwrap(SSLIOSession.java:271)
        at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:316)
        at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:509)
        at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:120)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
        at java.lang.Thread.run(Thread.java:748)

标签: javaelasticsearchsslrest-client

解决方案


推荐阅读