Skip to content

Instantly share code, notes, and snippets.

@mkoertgen
Created December 16, 2023 11:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkoertgen/52857c4d17353f9cb3cd87d90fb3eff2 to your computer and use it in GitHub Desktop.
Save mkoertgen/52857c4d17353f9cb3cd87d90fb3eff2 to your computer and use it in GitHub Desktop.
Skip SSL Host verification with ElasticSearch Client

Skip SSL Host verification with ElasticSearch Client

When enabling ElasticSearch to use https for inter-component communication, it uses self-signed certs by default. These certs are generated by the eck-operator itself.

In case infrastructure and management processes for self-signed certs and truststore generation is not an option for you, disabling certificate verification seems to be an easy solution to the missing cert management part.

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration

@Configuration
@ConfigurationProperties(prefix = "elastic")
class ElasticsearchProperties {
    // https://stackoverflow.com/a/50828463/2592915
    var url: String? = "https://localhost:9200"
    var username: String? = "elastic"
    var password: String? = null
    var index: String? = "evolution.counter"
    var sslSkipVerify: Boolean? = true
}
import co.elastic.clients.elasticsearch.ElasticsearchClient
import de.thieme.usst.sushi.reports.counter.LegacyReportService
import org.elasticsearch.client.RestHighLevelClient
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration


@Configuration
class ElasticsearchConfig(private val elastic: ElasticsearchProperties) {
    @Bean
    fun elasticsearchRestHighLevelClient(): RestHighLevelClient = ElasticFactory(elastic).getRestHighLevelClient()

	@Bean
	fun elasticsearchClient(): ElasticsearchClient = ElasticFactory(elastic).getJavaClient()
}
import co.elastic.clients.elasticsearch.ElasticsearchClient
import co.elastic.clients.json.jackson.JacksonJsonpMapper
import co.elastic.clients.transport.rest_client.RestClientTransport
import com.fasterxml.jackson.databind.DeserializationFeature
import org.apache.http.HttpHost
import org.apache.http.auth.AuthScope
import org.apache.http.auth.UsernamePasswordCredentials
import org.apache.http.conn.ssl.NoopHostnameVerifier
import org.apache.http.impl.client.BasicCredentialsProvider
import org.apache.http.ssl.SSLContextBuilder
import org.elasticsearch.client.RestClient
import org.elasticsearch.client.RestClientBuilder
import org.elasticsearch.client.RestHighLevelClient

data class ElasticFactory(val config: ElasticsearchProperties) {
	@Deprecated("deprecation due to RestHighLevelClient deprecation", ReplaceWith("getJavaClient"))
	fun getRestHighLevelClient(): RestHighLevelClient {
		val clientBuilder = getClientBuilder()
		return RestHighLevelClient(clientBuilder)
	}

	private fun getClientBuilder(): RestClientBuilder {
		// elastic basic auth, cf.: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/_basic_authentication.html
		val credentialsProvider = BasicCredentialsProvider()
		credentialsProvider.setCredentials(AuthScope.ANY, UsernamePasswordCredentials(config.username, config.password))

		return RestClient.builder(HttpHost.create(config.url!!))
			.setHttpClientConfigCallback {
				// When enabling Elastic to use https for inter-component communication, it uses self-signed certs by default.
				// These certs are generated by the eck-operator itself.
				//
				// Due to missing infrastructure and management processes for self-signed certs and truststore generation,
				// disabling certificate verification seems to be an easy solution to the missing cert management part.
				//
				if (config.sslSkipVerify == true) {
					it.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
					it.setSSLContext(SSLContextBuilder.create().loadTrustMaterial(null) { _, _ -> true }.build())
				}
				it.setDefaultCredentialsProvider(credentialsProvider)
			}
	}

	fun getJavaClient(): ElasticsearchClient {
		val clientBuilder = getClientBuilder()
		val restClient = clientBuilder.build()
		val jacksonMapper = JacksonJsonpMapper()
		jacksonMapper.objectMapper().configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false)
		jacksonMapper.objectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
		val transport = RestClientTransport(restClient, jacksonMapper)
		return ElasticsearchClient(transport)
	}
}
@mkoertgen
Copy link
Author

mkoertgen commented Dec 16, 2023

Similarly, here is how the KafkaConnect-Sink for Elasticsearch handles SSL Host Verification

In case you are into RedPanda here is to manage KafkaConnect-Cluster with the RedPanda Console

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment