Elasticsearch:在 Java 客户端中使用 truststore 来创建 HTTPS 连接
在我之前的文章 “ Elasticsearch:使用 Elasticsearch Java client 8.0 来连接带有 HTTPS 的集群” 里,我使用了两种方法,一直是使用 token 的方式,另外一种是使用 PEM 证书来进行连接的。在实际的使用中,有时我们的证书是以 PCKS12 格式的 truststore 格式的,那么我们该如何建立这种 HTTPS 的连接呢?
如果你还没有安装好自己的 Elasticsearch 集群,你可以参考我之前的文章 “ 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch” 来进行安装。
在接下来的示例中,我将使用 Elasticsearch 8.4.1 来进行展示。为了大家更好地理解我下面的代码,我把代码放到 github 上。你可以通过如下的命令来进行下载:
git clone https://github.com/liu-xiao-guo/elasticsearchjava-search8-https
例子
如上所示,Java 客户端和 Server 直接的验证图。针对我们的 Java 应用,我们需要在客户端创建一个 truststore 来建立联系。我们可以在 Elasticsearch 的安装目录下使用如下的命令来创建一个 truststore:
keytool -import -file http_ca.crt -keystore truststore.p12 -storepass password -noprompt -storetype pkcs12
1. $ pwd
2. /Users/liuxg/elastic/elasticsearch-8.4.1/config/certs
3. $ keytool -import -file http_ca.crt -keystore truststore.p12 -storepass password -noprompt -storetype pkcs12
4. Certificate was added to keystore
5. $ ls
6. http.p12 http_ca.crt transport.p12 truststore.p12
如上所示,它在当前的目录下创建一个叫做 truststore.p12 的文件。它的密码是 password。我们可以使用如下的命令来查看这个 truststore 的内容:
keytool -keystore truststore.p12 -list
1. $ keytool -keystore truststore.p12 -list
2. Enter keystore password:
3. Keystore type: PKCS12
4. Keystore provider: SUN
6. Your keystore contains 1 entry
8. mykey, Sep 26, 2022, trustedCertEntry,
9. Certificate fingerprint (SHA-256): F7:7C:44:13:CC:C6:A0:34:AC:97:67:F1:2B:9F:82:40:BF:30:1C:E9:56:CE:0D:96:10:9A:78:63:C4:A3:34:63
接下来,我们在 ElasticsearchJava.java 文件中添加如下的一个方法:
ElasticsearchJava.java
`1. private static synchronized void makeConnection_truststore() throws CertificateException, IOException, NoSuchAlgorithmException,
2. KeyStoreException, KeyManagementException {
3. final CredentialsProvider credentialsProvider =
4. new BasicCredentialsProvider();
5. credentialsProvider.setCredentials(AuthScope.ANY,
6. new UsernamePasswordCredentials("elastic", "Qu9UByppvqRRyI0LkoI+"));
8. String storePath = "/Users/liuxg/elastic/elasticsearch-8.4.1/config/certs/truststore.p12";
9. // String keyStorePass = "dI8wbt8VTkigRjxvOrvP9w";
10. String keyStorePass = "password";
11. Path trustStorePath = Paths.get(storePath);
12. KeyStore truststore = KeyStore.getInstance("pkcs12");
13. try (InputStream is = Files.newInputStream(trustStorePath)) {
14. truststore.load(is, keyStorePass.toCharArray());
15. }
16. SSLContextBuilder sslBuilder = SSLContexts.custom()
17. .loadTrustMaterial(truststore, null);
18. final SSLContext sslContext = sslBuilder.build();
19. RestClientBuilder builder = RestClient.builder(
20. new HttpHost("localhost", 9200, "https"))
21. .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
22. @Override
23. public HttpAsyncClientBuilder customizeHttpClient(
24. HttpAsyncClientBuilder httpClientBuilder) {
25. return httpClientBuilder.setSSLContext(sslContext)
26. .setDefaultCredentialsProvider(credentialsProvider);
27. }
28. });
29. RestClient restClient = builder.build();
31. // Create the transport with a Jackson mapper
32. ElasticsearchTransport transport = new RestClientTransport(
33. restClient, new JacksonJsonpMapper());
35. client = new ElasticsearchClient(transport);
36. asyncClient = new ElasticsearchAsyncClient(transport);
37. }`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
在上面,我们需要注意的是:
- 你可以使用除 elastic 之外的其它用户账号及其密码来进行连接
- 你需要修改 storePath 的路径,根据自己的安装及生成的 truststore 的文件路径
- 你需要修改相应的 keyStorePass,根据自己的配置
我们使用如下的代码进行相应的连接并创建一个叫做 products 的索引:
`1. try {
2. makeConnection_truststore();
3. } catch (CertificateException e) {
4. e.printStackTrace();
5. } catch (NoSuchAlgorithmException e) {
6. e.printStackTrace();
7. } catch (KeyStoreException e) {
8. e.printStackTrace();
9. } catch (KeyManagementException e) {
10. e.printStackTrace();
11. }
13. // Index data to an index products
14. Product product = new Product("abc", "Bag", 42);
16. IndexRequest<Object> indexRequest = new IndexRequest.Builder<>()
17. .index("products")
18. .id("abc")
19. .document(product)
20. .build();
22. client.index(indexRequest);`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
我们运行上面的代码,并在 Kibana 中进行查看:
GET products/_search
`
1. {
2. "took": 0,
3. "timed_out": false,
4. "_shards": {
5. "total": 1,
6. "successful": 1,
7. "skipped": 0,
8. "failed": 0
9. },
10. "hits": {
11. "total": {
12. "value": 1,
13. "relation": "eq"
14. },
15. "max_score": 1,
16. "hits": [
17. {
18. "_index": "products",
19. "_id": "abc",
20. "_score": 1,
21. "_source": {
22. "id": "abc",
23. "name": "Bag",
24. "price": 42
25. }
26. }
27. ]
28. }
29. }
`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
它表明,我们已经成功地创建了 products 索引。它说明了我们的连接是成功的。
参考:
【1】 Encrypted communication | Elasticsearch Java API Client [8.4] | Elastic