加密通信
编辑加密通信编辑
可以使用 HttpClientConfigCallback
配置使用 TLS 的加密通信。作为参数接收的 org.apache.http.impl.nio.client.HttpAsyncClientBuilder
公开了多种方法来配置加密通信:setSSLContext
、setSSLSessionStrategy
和 setConnectionManager
,按优先级从最低到最高排序。
当访问在 HTTP 层为 TLS 设置的 Elasticsearch 集群时,客户端需要信任 Elasticsearch 使用的证书。以下示例展示了如何设置客户端以信任已签署 Elasticsearch 使用的证书的 CA,前提是该 CA 证书在 PKCS#12 密钥库中可用。
Path trustStorePath = Paths.get("/path/to/truststore.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(); RestClientBuilder builder = RestClient.builder( new HttpHost("localhost", 9200, "https")) .setHttpClientConfigCallback(new HttpClientConfigCallback() { @Override public HttpAsyncClientBuilder customizeHttpClient( HttpAsyncClientBuilder httpClientBuilder) { return httpClientBuilder.setSSLContext(sslContext); } });
以下示例展示了如何设置客户端以信任已签署 Elasticsearch 使用的证书的 CA,前提是该 CA 证书以 PEM 编码文件形式可用。
Path caCertificatePath = Paths.get("/path/to/ca.crt"); CertificateFactory factory = CertificateFactory.getInstance("X.509"); Certificate trustedCa; try (InputStream is = Files.newInputStream(caCertificatePath)) { trustedCa = factory.generateCertificate(is); } KeyStore trustStore = KeyStore.getInstance("pkcs12"); trustStore.load(null, null); trustStore.setCertificateEntry("ca", trustedCa); SSLContextBuilder sslContextBuilder = SSLContexts.custom() .loadTrustMaterial(trustStore, null); final SSLContext sslContext = sslContextBuilder.build(); RestClient.builder( new HttpHost("localhost", 9200, "https")) .setHttpClientConfigCallback(new HttpClientConfigCallback() { @Override public HttpAsyncClientBuilder customizeHttpClient( HttpAsyncClientBuilder httpClientBuilder) { return httpClientBuilder.setSSLContext(sslContext); } });
当 Elasticsearch 配置为要求客户端 TLS 身份验证时(例如,当配置 PKI 域时),客户端需要在 TLS 握手期间提供客户端证书以进行身份验证。以下示例展示了如何设置客户端以使用存储在 PKCS#12 密钥库中的证书和私钥进行 TLS 身份验证。
Path trustStorePath = Paths.get("/path/to/your/truststore.p12"); Path keyStorePath = Paths.get("/path/to/your/keystore.p12"); KeyStore trustStore = KeyStore.getInstance("pkcs12"); KeyStore keyStore = KeyStore.getInstance("pkcs12"); try (InputStream is = Files.newInputStream(trustStorePath)) { trustStore.load(is, trustStorePass.toCharArray()); } try (InputStream is = Files.newInputStream(keyStorePath)) { keyStore.load(is, keyStorePass.toCharArray()); } SSLContextBuilder sslBuilder = SSLContexts.custom() .loadTrustMaterial(trustStore, null) .loadKeyMaterial(keyStore, keyStorePass.toCharArray()); final SSLContext sslContext = sslBuilder.build(); RestClientBuilder builder = RestClient.builder( new HttpHost("localhost", 9200, "https")) .setHttpClientConfigCallback(new HttpClientConfigCallback() { @Override public HttpAsyncClientBuilder customizeHttpClient( HttpAsyncClientBuilder httpClientBuilder) { return httpClientBuilder.setSSLContext(sslContext); } });
如果客户端证书和密钥不在密钥库中,而是以 PEM 编码文件形式提供,则无法直接使用它们来构建 SSLContext。您必须依赖外部库将 PEM 密钥解析为 PrivateKey 实例。或者,您可以使用外部工具从 PEM 文件构建密钥库,如以下示例所示。
openssl pkcs12 -export -in client.crt -inkey private_key.pem \ -name "client" -out client.p12
如果没有提供显式配置,将使用 系统默认配置。