背景
最近在搞es登录,不知道是不是低版本问题(6.8.12),开启登录之后springboot连接es,es一直报Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record: 45530000002c000000000000009108004d3603000016696e7465726e616c3a7463702f68616e647368616b650004bb91f302。
最新排查情况,es开启登录,没有springboot应用连接的话,es是没有没有报错的,结合异常信息9300、SSL/TLS协议,猜想是客户端连接没有设置证书,最后一番设置之后证实是连接没有设置证书问题。
另外,查询资料TransportClient 高版本是废弃的,但是6.8.12不高也不低,好像也没废弃,所以还是得对TransportClient 设置证书。
一、es elasticsearch.yml配置文件关于登录最新配置
#开启安全验证
xpack.security.enabled: true
#transport 开启ssl
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
#证书,自己生成吧,es自带工具能生成
xpack.security.transport.ssl.keystore.path: certs/elastic-stack-ca.p12
修改后重启es服务
二、springboot 关于es连接最新配置
maven spring-boot-starter-data-elasticsearch排除x-pack-transport模块,额外引入x-pack-transport6.8.12(版本按实际需求),这样引入才会有PreBuiltXPackTransportClient类,支持xpack相关配置属性。
...
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>x-pack-transport</artifactId>
<version>6.8.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<exclusions>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>x-pack-transport</artifactId>
</exclusion>
</exclusions>
</dependency>
...
yml:enabled控制是否需要配置TransportClient,capath是证书路径文件跟服务器一致就好,username、password稍微移动到ssl(相比之前的文章,当然位置自己随便写)
spring:
data:
elasticsearch:
cluster-name: es
cluster-nodes: xxxx:9300
rest:
uris: http://xxxx:9200
ssl:
enabled: true
username: elastic
password: 123456
capath: /xxxxx/elastic-stack-ca.p12
es 配置类,配置TransportClient对象,由spring.data.elasticsearch.rest.ssl.enabled控制是否需要配置,使用setting配置需要的连接属性
cluster.name:集群名字
xpack.security.user:账号密码
xpack.security.transport.ssl.enabled:开启ssl
xpack.security.transport.ssl.verification_mode:证书模式跟服务配置一致
xpack.security.transport.ssl.keystore.path:证书路径
xpack.security.transport.ssl.keystore.password:证书密码,生成证书时候有输入密码,需要一致
package com.xxxx.configuration;
import java.net.InetAddress;
import java.util.stream.Stream;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.xpack.client.PreBuiltXPackTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
/**
*
* 描述:elasticsearch配置
* @author sakyoka
* @date 2024年10月11日 下午3:47:19
*/
@Configuration
public class ElasticsearchConfiguration extends AbstractElasticsearchConfiguration {
@Value("${spring.data.elasticsearch.cluster-name}")
private String clusterName;
@Value("${spring.data.elasticsearch.cluster-nodes}")
private String clusterNodes;
@Value("${spring.data.elasticsearch.rest.uris}")
private String uris;
@Value("${spring.data.elasticsearch.rest.ssl.username:}")
private String username;
@Value("${spring.data.elasticsearch.rest.ssl.password:}")
private String password;
@Value("${spring.data.elasticsearch.rest.ssl.capath:}")
private String caPath;
@Bean
public ElasticsearchRestTemplate elasticsearchRestTemplate(RestHighLevelClient client) {
return new ElasticsearchRestTemplate(elasticsearchClient());
}
@Override
public RestHighLevelClient elasticsearchClient(){
System.setProperty("es.set.netty.runtime.available.processors", "false");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
RestClientBuilder builder = RestClient.builder(HttpHost.create(uris))
.setHttpClientConfigCallback(http -> {
return http.setDefaultCredentialsProvider(credentialsProvider);
});
return new RestHighLevelClient(builder);
}
@Bean
@ConditionalOnProperty(name = "spring.data.elasticsearch.rest.ssl.enabled")
public TransportClient transportClient() throws Exception {
Settings settings = Settings.builder()
.put("cluster.name", clusterName)
.put("xpack.security.user", username + ":" + password)
.put("xpack.security.transport.ssl.enabled", true)
.put("xpack.security.transport.ssl.verification_mode", "certificate")
.put("xpack.security.transport.ssl.keystore.path", caPath)
.put("xpack.security.transport.ssl.keystore.password", password)
.build();
TransportClient client = new PreBuiltXPackTransportClient(settings);
Stream.of(clusterNodes.split(",")).forEach(nodeName -> {
try {
client.addTransportAddress(new TransportAddress(
InetAddress.getByName(nodeName.split(":")[0]), Integer.valueOf(nodeName.split(":")[1])));
} catch (Exception e) {
throw new RuntimeException("es 注册节点:" + nodeName, e);
}
});
return client;
}
}
相关配置配置好之后启动应用,会发现es日志不再报Caused by: io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record:
总结:
万恶的版本,好多类缺失不兼容,搞了好久