Я пытаюсь подключиться к экземпляру elasticsearch, который находится за туннелем ssh. Домен экземпляра elasticsearch — *.ap-south-1.es.amazonaws.com, а локально в туннеле я подключаюсь через localhost:9201.
Вот код, который я использую для подключения к elasticsearch
RestHighLevelClient(RestClient.builder(HttpHost("localhost", 9201, "https")))
Я получаю следующую ошибку
javax.net.ssl.SSLPeerUnverifiedException: Host name 'localhost' does not match the certificate subject provided by the peer (CN=*.ap-south-1.es.amazonaws.com)
Я получил эту ошибку, когда работал с PHP-Elasticsearch, и я исправил ее с помощью
$esClient->setSSLVerification(false);
Я надеялся найти аналогичный метод для Java RestClient.




Для этого вам необходимо отключить параметр, который сверяет имя хоста с именем, которое вы указали. Это ошибка HTTPClient в apache, и вы должны виртуализировать имя хоста, как это проверено в методе setSSLHostnameVerifier, подобно этому.
Хотя этот код находится в Котлине, но можно легко написать альтернативу Java.
val builder = RestClient.builder(host).setHttpClientConfigCallback { httpAsyncClientBuilder ->
httpAsyncClientBuilder.setSSLHostnameVerifier { _, _ -> true }
}
Это всегда будет переопределять ваш параметр для проверки имени хоста как истинного.
Поскольку имя хоста в вашем сертификате не является локальным, у вас возникнет эта проблема, поэтому для ее решения вам необходимо отключить проверку имени хоста SSL, выполнив следующие действия, вы всегда вернете true, и это пропустит проверку.
RestClientBuilder restClientBuilder = RestClient.builder(HttpHost);
restClientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder ->
httpAsyncClientBuilder.setSSLHostnameVerifier((s, sslSession) -> true));
new RestHighLevelClient(restClientBuilder);
Пожалуйста, объясните, как это исправило ошибку или кратко о коде, который вы написали здесь.
Думаю, это относительно очевидно. setSSLHostnameVerifier() вернет true независимо от поведения сеанса SSL.
Я надеюсь, что это даст полный ответ.
Надеюсь, это поможет вам, у меня была такая же проблема, и я решил ее так.
@Bean
public RestHighLevelClient createSimpleElasticClient() throws Exception {
try {
SSLContextBuilder sslBuilder = SSLContexts.custom()
.loadTrustMaterial(null, (x509Certificates, s) -> true);
final SSLContext sslContext = sslBuilder.build();
RestHighLevelClient client = new RestHighLevelClient(RestClient
.builder(new HttpHost(hostNameOrLoadbalancerURL, 443, "https"))
//port number is given as 443 since its https schema
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
}
})
.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
@Override
public RequestConfig.Builder customizeRequestConfig(
RequestConfig.Builder requestConfigBuilder) {
return requestConfigBuilder.setConnectTimeout(5000)
.setSocketTimeout(120000);
}
}));
System.out.println("elasticsearch client created");
return client;
} catch (Exception e) {
System.out.println(e);
throw new Exception("Could not create an elasticsearch client!!");
}
}
Полный рабочий пример для эластичного отключения проверки SSL с помощью Spring Boot на Kotlin
import org.apache.http.conn.ssl.NoopHostnameVerifier
import org.apache.http.conn.ssl.TrustAllStrategy
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder
import org.apache.http.ssl.SSLContexts
import org.elasticsearch.client.RestClientBuilder
import org.springframework.boot.autoconfigure.elasticsearch.RestClientBuilderCustomizer
@Configuration
@ConditionalOnProperty(name = ["spring.elasticsearch.rest.ssl.disable"], havingValue = "DISABLE_SSL")
class ElasticSSLCertDisableConfig {
private val sslContext = SSLContexts.custom()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
.build()
@Bean
fun restClientBuilderCustomizer() = object : RestClientBuilderCustomizer {
override fun customize(builder: HttpAsyncClientBuilder) {
builder.setSSLContext(sslContext)
builder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
}
override fun customize(builder: RestClientBuilder) {}
}
}
ВНИМАНИЕ: Используйте его только для среды разработки.
Вы должны включить краткое объяснение того, что делает код и почему он решает проблему.