ElasticSearch 8.x 使用 High Level Client 以 HTTPS 方式链接,SSL 证书、主机名验证器 各是什么,如何忽略

ElasticSearch

1、ElasticSearch学习随笔之基础介绍

2、ElasticSearch学习随笔之简单操作

3、ElasticSearch学习随笔之java api 操作

4、ElasticSearch学习随笔之SpringBoot Starter 操作

5、ElasticSearch学习随笔之嵌套操作

6、ElasticSearch学习随笔之分词算法

7、ElasticSearch学习随笔之高级检索

8、ELK技术栈介绍

9、Logstash部署与使用

10、ElasticSearch 7.x 版本使用 BulkProcessor 实现批量添加数据

11、ElasticSearch 8.x 弃用了 High Level REST Client,移除了 Java Transport Client,推荐使用 Elasticsearch Java API

12、ElasticSearch 8.x 使用 snapshot(快照)进行数据迁移

13、ElasticSearch 8.x 版本如何使用 SearchRequestBuilder 检索

14、ElasticSearch 8.x 使用 High Level Client 以 HTTPS 方式链接,SSL 证书、主机名验证器 各是什么,如何忽略

ElasticSearch,创始人 Shay Banon(谢巴农)

本文主要讲解ElasticSearch 高级搜索实战,来满足复杂的业务场景,还是用 Kibana 来操作。


文章目录


前言

在平时测试环境中,我们可以通过 IP 地址 或者 域名【http://***】来简单粗暴的连接 ElasticSearch 服务,比较内网测试没必要考虑别的,连接上能进行索引的操作即可;不过到了生产环境,安全问题成了 头号杀手 ,毕竟数据无价嚒,不过目前很多企业应用都会部署到云端,应用ElasticSearch 服务之前其实也是属于内网连接,并不会暴漏链接到外面,再加上云服务自身的安全和防火前的保护,所以安全基本上不用考虑了。

可以公司是有规范的,无论是 DB 数据库还是缓存,还是像 ElasticSearch 这种搜索引擎必须要有 用户名和密码 这层安全校验的,这是安全最基本的,所以应对不同的环境 或许 就需要不同的连接方式了。

一:pom 依赖

对于 ElasticSearch 客户端的版本,不需要太高,稳定很重要,对于有些莫名其妙的问题,换一个 版本的 客户端有可能就好了,亲身经历

java 复制代码
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.15.2</version>
</dependency>

二:开放式连接方式

三:用户名密码验证方式

这种方式在其他博客中已经提到好几次了,放到这里只为有需要的 码友 们拷贝代码。

java 复制代码
private static RestHighLevelClient createClient(){
    String hostname = "192.168.0.67";
    int port = 9200;
    String esUsername = "your es username";
    String esPassword = "your es password";
    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esUsername, esPassword));
    RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(hostname, port))
            .setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
    return new RestHighLevelClient(restClientBuilder);
}

四:忽略 SSL证书 和 主机名验证

生产环境的 ElasticSearch 有时可能是通过域名来访问的,并且是 https 开头的,那就需要 SSL/TLS 认证了,但是我们并不需要,那只能忽略了。

4.1 忽略 SSL 认证

按上面说的,ElasticSearch 访问地址是 https://***,而只配置了 用户名密码,那用客户端链接则 可能 会报如下错误:

bash 复制代码
javax.net.ssl.SSLHandshakeException:PKIX path building failed:sun.security.provider.certpath.SunCertPathBuilderException:unable to find valid certification path to requested target
at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:783)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:218)
at org.elasticsearch.client.RestClient.performRequest(RestClient.java:205)
at org.elasticsearch.client.RestHighLevelclient.internalPerformRequest(RestHighLevelclient.java:1454)
at org.elasticsearch.client.RestHighLevelclient.performRequest(RestHighLevelclient.java:1424)

此时我们需要忽略 SSL 认证,然忽略 SSL 的写法也有好几种。

注意: 以下三种方式选择其中一种就可以,那种适合就用那种。

方式一

首先获取 TLS 的 SSLContext 实例,再进行初始化,初始化的时候什么都不做。

java 复制代码
public static RestHighLevelClient createClient(){
    String hostname = "es.test.com";
    int port = 9200;
    String esUsername = "your es username";
    String esPassword = "your es password";
    // 配置用户名和密码
    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esUsername, esPassword));
    RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(hostname, port, "https"));
    clientBuilder.setHttpClientConfigCallback( httpAsyncClientBuilder -> {
                // 配置认证支持
                httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                // 忽略证书配置
                try {
                    SSLContext sslContext = SSLContext.getInstance("TLS");
                    sslContext.init(null, new TrustManager[] {
                                    new X509TrustManager() {
                                        @Override
                                        public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
                                                throws CertificateException {
                                            // 忽略证书错误 信任任何客户端证书
                                        }

                                        @Override
                                        public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
                                                throws CertificateException {
                                            // 忽略证书错误 信任任何客户端证书
                                        }

                                        @Override
                                        public X509Certificate[] getAcceptedIssuers() {
                                            return new X509Certificate[0];
                                        }
                                    }
                            },
                            null);
                    httpAsyncClientBuilder.setSSLContext(sslContext);
                } catch (NoSuchAlgorithmException | KeyManagementException e) {
                    System.out.println("忽略证书错误");
                }
                // 忽略 hostname 校验认证
                httpAsyncClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
                return httpAsyncClientBuilder;
            });
    return new RestHighLevelClient(clientBuilder);
}

方式二

首先创建一个信任策略的 TrustStrategy,再通过策略构建一个 SSLContext 。

java 复制代码
public static RestHighLevelClient createClient(){
    String hostname = "es.test.com";
    int port = 9200;
    String esUsername = "your es username";
    String esPassword = "your es password";
    // 配置用户名和密码
    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esUsername, esPassword));
    RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(hostname, port, "https"));
    clientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {
        httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        try {
            // 创建一个信任所有证书的 TrustStrategy 策略
            TrustStrategy acceptTrustStrategy = (chain, authType) -> true;
            // 使用 SSLContextBuilder 创建 SSLContext
            SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(null, acceptTrustStrategy).build();
            httpAsyncClientBuilder.setSSLContext(sslContext);
        } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
            e.printStackTrace();
        }
        return httpAsyncClientBuilder;
    });
    return new RestHighLevelClient(clientBuilder);
}

方式三

这里需要一个引入一个第三方的 jar 包,封装了我们需要的 SSL 认证实例。

java 复制代码
<dependency>
    <groupId>io.github.hakky54</groupId>
    <artifactId>sslcontext-kickstart</artifactId>
    <version>8.1.4</version>
</dependency>

下面通过第三方 jar 包提供的 SSLFactory 来得到 SSLContext 。

java 复制代码
public static RestHighLevelClient createClient(){
    String hostname = "es.test.com";
    int port = 9200;
    String esUsername = "your es username";
    String esPassword = "your es password";
    // 用户名和密码认证
    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(esUsername, esPassword));
    // 配置策略工厂
    SSLFactory sslFactory = SSLFactory.builder()
            .withUnsafeTrustMaterial()
            .withUnsafeHostnameVerifier()
            .build();
    RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(hostname, port, "https"));
    clientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {
        httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        // 通过策略工厂获取一个 SSLContext
        httpAsyncClientBuilder.setSSLContext(sslFactory.getSslContext());
        return httpAsyncClientBuilder;
    });
    return new RestHighLevelClient(clientBuilder);
}

4.2 忽略 主机名验证

处理 SSL 认证,还有可能包如下错误:

bash 复制代码
java.io.IOException: Host name 'devintes.jibo.cn' does not match the certificate subject provided by the peer (CN=elasticsearch-devint-master)

我们接着忽略,只需要在忽略 SSL 是再忽略 主机名验证就可以了,代码如下:

java 复制代码
httpAsyncClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);

其实再上面的 方式三 中,用 SSLFactory 也是可以忽略的。

相关推荐
牙牙7055 分钟前
Centos7安装Jenkins脚本一键部署
java·servlet·jenkins
paopaokaka_luck12 分钟前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
以后不吃煲仔饭25 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师26 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
The_Ticker31 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
java1234_小锋36 分钟前
Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?
大数据·elasticsearch·jenkins
Elastic 中国社区官方博客37 分钟前
Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
我的运维人生37 分钟前
Elasticsearch实战应用:构建高效搜索与分析平台
大数据·elasticsearch·jenkins·运维开发·技术共享
jwolf237 分钟前
摸一下elasticsearch8的AI能力:语义搜索/vector向量搜索案例
人工智能·搜索引擎
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink