elasticsearch java sdk 访问未认证自签证书 https ssl web

早些年写过一个es的网关服务,当时觉得java对接es过于痛苦,只当是个试验性质的项目

cclient/spring-boot-es-jpa-proxy: spring-boot elasticsearch 聚合 webapi服务 (github.com)

java jvm 栈 通用的https/ssl 自签证书信任办法

https://github.com/lmenezes/cerebro/issues/456

现在又来踩坑了

目标是做一个分发es search和bulk请求读写的网关,兼容同一集群内的多集群

public RestHighLevelClient elasticsearchClient() {
        HttpHeaders defaultHeaders = new HttpHeaders();
        final ClientConfiguration clientConfiguration = ClientConfiguration
                .builder()
                .connectedTo("a.b.c:9200")
                .usingSsl()
                .withConnectTimeout(Duration.ofSeconds(5))
                .withSocketTimeout(Duration.ofSeconds(3))
                .withDefaultHeaders(defaultHeaders)
                .withHeaders(() -> {
                    HttpHeaders headers = new HttpHeaders();
                    headers.add("currentTime", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
                    return headers;
                })
                .build();
        return RestClients.create(clientConfiguration).rest();
    }

未认证证书,报错

javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:818)
	at org.elasticsearch.client.RestClient.performRequest(RestClient.java:248)
	at org.elasticsearch.client.RestClient.performRequest(RestClient.java:235)
	at org.elasticsearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1514)
	... 1 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

看到 usingSsl() 有三个重载方法

    public interface MaybeSecureClientConfigurationBuilder extends ClientConfiguration.TerminalClientConfigurationBuilder {
        ClientConfiguration.TerminalClientConfigurationBuilder usingSsl();

        ClientConfiguration.TerminalClientConfigurationBuilder usingSsl(SSLContext var1);

        ClientConfiguration.TerminalClientConfigurationBuilder usingSsl(SSLContext var1, HostnameVerifier var2);
    }

先试着重载传入SSLContext

        final TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain,
                                                   String authType) {
                    }
                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] chain,
                                                   String authType) {
                    }
                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                }
        };
//            final SSLContext sslContext = SSLContext.getInstance(SSL);
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
        
.usingSsl(sslContext)

报错 Host name 'a.b.c' does not match the certificate subject 证书和域名不匹配

java.io.IOException: Host name 'a.b.c' does not match the certificate subject provided by the peer (CN=instance)
	at ..
Caused by: javax.net.ssl.SSLPeerUnverifiedException: Host name 'a.b.c' does not match the certificate subject provided by the peer (CN=instance)

再试第三个重载办法 传入HostnameVerifier 直接返回true,不验证域名和证书是否匹配,直接返回true

                .usingSsl(sslContext, new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                })

测试成功

end

posted @ 2021-03-24 21:07  cclient  阅读(428)  评论(0编辑  收藏  举报