I'm new to spring-boot & Elasticsearch technology stack and I want to establish secure HTTPS connection between my spring-boot app & elastic search server which runs locally. These are the configurations that I have done in elasticsearch.yml
Giving credintials for elasticsearch server
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
For secure inter nodes connection inside elasticsearch cluster
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
For secure Https connection with clients and elasticsearch clustrer
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: elastic-certificates.p12
xpack.security.http.ssl.truststore.path: elastic-certificates.p12
xpack.security.http.ssl.client_authentication: optional
Enabling PKI authentication
xpack.security.authc.realms.pki.pki1.order: 1
I have generated CA and client certificate which signed by generated CA according to this link
https://www.elastic.co/blog/elasticsearch-security-configure-tls-ssl-pki-authentication
And I have added CA to my java keystore.
This is the java code i'm using to establish connectivity with elasticsearch server.
@Configuration public class RestClientConfig extends AbstractElasticsearchConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(RestClientConfig.class);
private static final String CERT_FILE = "client.p12";
private static final String CERT_PASSWORD = "";
private static final String USER_NAME = "elastic";
private static final String USER_PASS = "pwd";
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200") // set the address of the Elasticsearch cluster
.usingSsl(createSSLContext()) // use the SSLContext with the client cert
.withBasicAuth(USER_NAME, USER_PASS) // use the headers for authentication
.build();
return RestClients.create(clientConfiguration).rest();
}
private SSLContext createSSLContext() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
KeyManager[] keyManagers = getKeyManagers();
sslContext.init(keyManagers, null, null);
return sslContext;
} catch (Exception e) {
LOG.error("cannot create SSLContext", e);
}
return null;
}
private KeyManager[] getKeyManagers()
throws KeyStoreException, NoSuchAlgorithmException, IOException, CertificateException, UnrecoverableKeyException {
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(CERT_FILE)) {
KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
clientKeyStore.load(inputStream, CERT_PASSWORD.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(clientKeyStore, CERT_PASSWORD.toCharArray());
return kmf.getKeyManagers();
}
}
And my client certificate called "client.p12" included in resources folder in the spring-boot application. In elasticsearch side everything seems to be fine. But when I run the spring-boot app it gives this warning & exception
Cannot create index: Host name 'localhost' does not match the certificate subject provided by the peer (CN=instance); nested exception is java.lang.RuntimeException: Host name 'localhost' does not match the certificate subject provided by the peer (CN=instance)
java.io.IOException: Host name 'localhost' does not match the certificate subject provided by the peer (CN=instance)
Caused by: javax.net.ssl.SSLPeerUnverifiedException: Host name 'localhost' does not match the certificate subject provided by the peer (CN=instance)
I'm doing this because I have an idea to migrate elastic search server to a another VPS hosting later.
this is the command I used for generate client certificate
bin/elasticsearch-certutil cert --ca
config/elastic-stack-ca.p12
-name "CN=something,OU=Consulting Team,DC=mydomain,DC=com"
ENTER
client.p12 ENTER
ENTER
searching this error in internet I figured out there is a issue with my client certificate. It has something to do with SAN names with elastic nodes. But I have very little knowledge about these certificate stuff. So it's really confusion for me. If Some one can give me in-detailed explanation why this is occurring & solution to this I'm really appreciating it & grateful. A Proper link will also be helpful. This question already asked in How to connect 'spring boot 2.1 with elasticsearch 6.6' with cluster node 'https'? link But no luck for me.