无法连接到Elasticsearch服务器:无法找到到请求目标的有效证书路径[重复]

v1uwarro  于 2023-08-03  发布在  ElasticSearch
关注(0)|答案(1)|浏览(194)

此问题在此处已有答案

"PKIX path building failed" and "unable to find valid certification path to requested target"(58回答)
上个月关门了。
这篇文章是编辑并提交审查20天前.
我正在尝试连接运行在GCP VM环境中的Elasticsearch远程服务器(受SSH保护)。我有运行Elasticsearch的GCP VM示例生成的http_ca.crt证书。

  • 我显示了证书的路径,然后Java无法读取文件,之后我将证书添加到keystore。仍然得到错误:
Failed to connect to Elasticsearch server. Exception: PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

字符串

  • 源代码如下:
public class ElasticsearchSSHconnection {

  private static TrustManager[] trustManager;

  public static void main(String[] args) throws Exception {
      String host = "HOST-IP";
      int port = 9200;
      String username = "USERNAME";
      String password = "PASSWORD";
      String caCertificatePath = "C:\\Users\\user\\Downloads\\http_ca\\http_ca.crt";

      SSLContext sslContext = createSSLContextWithCA(caCertificatePath);

      BasicCredentialsProvider credsProv = new BasicCredentialsProvider();
      credsProv.setCredentials(
              AuthScope.ANY, new UsernamePasswordCredentials(username, password)
      );

      RestClientBuilder restClientBuilder = RestClient
              .builder(new HttpHost(host, port, "https"))
              .setHttpClientConfigCallback(httpClientBuilder -> {
                  httpClientBuilder.setSSLContext(sslContext)
                          .setDefaultCredentialsProvider(credsProv);

                  // Disable hostname verification
                  httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);

                  return httpClientBuilder;
              });

      RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);

      try {
          client.ping(RequestOptions.DEFAULT);
          System.out.println("Connection to Elasticsearch server is SUCCESSFUL.");
      } catch (IOException e) {
          System.out.println("Failed to connect to Elasticsearch server. Exception: " + e.getMessage());
      } finally {
          client.close();
      }
  }

  private static SSLContext createSSLContextWithCA(String caCertificatePath) throws Exception {

      KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());

      FileInputStream truststoreInputStream = new FileInputStream("C:\\Windows\\System32\\truststore.jks");
      trustStore.load(truststoreInputStream, "PASSWORD".toCharArray());

      TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
      trustManagerFactory.init(trustStore);

      SSLContext sslContext = SSLContext.getInstance("TLS");
      sslContext.init(null, trustManager, null);

      return sslContext;
}
}

tquggr8v

tquggr8v1#

我自己张贴的答案,我发现的解决方案似乎是工作!

  • 基本上,问题始于Elasticsearch服务器生成的http_ca.crt证书文件。实际上Java运行时无法读取,因为它不受信任。
  • 为了解决这个问题,我使用以下命令将Elasticsearch服务器的SSL证书添加到Java使用的truststore中:
keytool -import -alias http_ca -file C:\Users\User\Downloads\http_ca.crt -keystore truststore.jks

字符串

  • 下一个问题与Java API有关,我使用了RestHighLevelClient。我同时使用http_ca.crttruststore.jks。在没有意识到这一点的情况下,我已经将SSL证书文件移动到了Java truststore。然后我对Java客户端做了一些修改,一切都很好:
public class ElasticsearchConnectionCheckHTTPS {

  public static void main(String[] args) {
      String host = "HOST-IP-ADDRESS";
      int port = PORT;
      String username = "USERNAME";
      String password = "PASSWORD";
      String truststorePath = "C:\\Users\\User\\Downloads\\truststore.jks";
      String truststorePassword = "TRUSTSTORE-PASSWORD";

      try {
          KeyStore truststore = KeyStore.getInstance("JKS");
          truststore.load(new FileInputStream(truststorePath), truststorePassword.toCharArray());

          TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
          trustManagerFactory.init(truststore);

          SSLContext sslContext = SSLContext.getInstance("TLS");
          sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

          CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
          credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

          RestHighLevelClient client = new RestHighLevelClient(
                  RestClient.builder(new HttpHost(host, port, "https"))
                                  .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
                                  .setDefaultCredentialsProvider(credentialsProvider)
                                  .setSSLContext(sslContext)
                                  .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)));

          MainResponse response = client.info(RequestOptions.DEFAULT);
          String clusterName = response.getClusterName().toString();
          String clusterVersion = response.getVersion().toString();
          System.out.println("Connected to Elasticsearch cluster: " + clusterName + " (Version: " + clusterVersion + ")");

          client.close();
      } catch (Exception e) {
          System.out.println("Failed to connect to Elasticsearch server. Exception: " + e.getMessage());
      }
  }
}

  • 将演示运行作为图像文件发布:

x1c 0d1x的数据

相关问题