官方文档地址:Encrypted communication
使用TLS
的加密通信也可以通过HttpClientConfigCallback
进行配置。 作为参数接收的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
如果没有提供显式配置,将使用系统默认配置。