访问反向代理后的Elasticsearch数据库

huangapple go评论63阅读模式
英文:

Acessing elasctiDB behind reverse proxy

问题

我有一个RestHighLevelClient用于连接到一个位于反向代理后面、取消了SSL的远程elasticDB。

        val restClientBuilder: RestClientBuilder = RestClient
                .builder(HttpHost(hostname, port, scheme))

        if(username.isNotEmpty()){
            val credentialsProvider: CredentialsProvider = BasicCredentialsProvider()
            credentialsProvider.setCredentials(AuthScope.ANY, UsernamePasswordCredentials(username, password))
            restClientBuilder.setHttpClientConfigCallback { h: HttpAsyncClientBuilder -> h.setDefaultCredentialsProvider(credentialsProvider).setSSLHostnameVerifier { _, _ -> true }.setSSLContext(SSLContext.getDefault()) }
        }

client = RestHighLevelClient(restClientBuilder)

当我调用以下代码时:

client.index(indexRequest, RequestOptions.DEFAULT)

我收到了一个handshake_failure异常:

javax.net.ssl.SSLException: Received fatal alert: handshake_failure

根据这里这里的描述,我检查了日志并找到了ClientHello:

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1307888763 bytes = { 137, 187, 7, 199, 3, 82, 79, 49, 175, 115, 114, 160, 22, 241, 240, 60, 237, 136, 239, 232, 108, 236, 249, 79, 139, 90, 119, 136 }
Session ID:  {95, 24, 10, 176, 230, 223, 52, 137, 2, 146, 170, 240, 61, 10, 177, 36, 223, 167, 33, 19, 225, 19, 213, 54, 22, 220, 239, 77, 199, 139, 52, 23}
Cipher Suites: [Unknown 0x13:0x1, Unknown 0x13:0x2, Unknown 0x13:0x3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, Unknown 0xcc:0xa9, Unknown 0xcc:0xa8, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
Compression Methods:  { 0 }
Extension server_name, server_name: [type=host_name (0), value=localhost]
Unsupported extension type_23, data: 
Extension renegotiation_info, renegotiated_connection: <empty>
Extension elliptic_curves, curve names: {unknown curve 29, secp256r1, secp384r1}
Extension ec_point_formats, formats: [uncompressed]
Unsupported extension type_35, data: 
Extension signature_algorithms, signature_algorithms: SHA256withECDSA, Unknown (hash:0x8, signature:0x4), SHA256withRSA, SHA384withECDSA, Unknown (hash:0x8, signature:0x5), SHA384withRSA, Unknown (hash:0x8, signature:0x6), SHA512withRSA, SHA1withRSA
Unsupported extension type_51, data: 00:24:00:1d:00:20:6a:06:37:c2:47:97:e9:87:59:c6:0e:8f:9a:7f:12:81:18:20:18:49:77:b3:d4:11:71:37:0e:13:3d:de:6f:10
Unsupported extension type_45, data: 01:01
Unsupported extension type_43, data: 08:03:04:03:03:03:02:03:01
***

然后是ServerHello:

```plaintext
*** ServerHello, TLSv1.2
RandomCookie:  GMT: 1595412045 bytes = { 85, 81, 154, 66, 129, 137, 233, 224, 170, 170, 0, 28, 94, 221, 152, 50, 25, 2, 31, 115, 127, 103, 180, 78, 173, 152, 8, 173 }
Session ID:  {95, 24, 10, 176, 230, 223, 52, 137, 2, 146, 170, 240, 61, 10, 177, 36, 223, 167, 33, 19, 225, 19, 213, 54, 22, 220, 239, 77, 199, 139, 52, 23}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***

加密和明文的请求随后出现。之后又是另一个以以下方式结束的ClientHello:

```plaintext
[Raw read]: length = 5
0000: 15 03 03 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
I/O dispatcher 25, READ: TLSv1.2 Alert, length = 2
I/O dispatcher 25, RECV TLSv1.2 ALERT:  fatal, handshake_failure
I/O dispatcher 25, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
I/O dispatcher 25, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
2020-07-22 12:00:45.360 ERROR 78321 --- [io-8081-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.io.IOException: Received fatal alert: handshake_failure

这一行:

I/O dispatcher 25, READ: TLSv1.2 Alert, length = 2

提示了不同意Cipher suite的可能性,但在上面的行中,双方都同意了

英文:

I have an RestHighLevelClient to connect to a remote elasticDB behind a reversed proxy which strips the ssl.

        val restClientBuilder: RestClientBuilder = RestClient
                .builder(HttpHost(hostname, port, scheme))

        if(username.isNotEmpty()){
            val credentialsProvider: CredentialsProvider = BasicCredentialsProvider()
            credentialsProvider.setCredentials(AuthScope.ANY, UsernamePasswordCredentials(username, password))
            restClientBuilder.setHttpClientConfigCallback { h: HttpAsyncClientBuilder -> h.setDefaultCredentialsProvider(credentialsProvider).setSSLHostnameVerifier { _, _ -> true }.setSSLContext(SSLContext.getDefault()) }
        }

client = RestHighLevelClient(restClientBuilder)

When I call

client.index(indexRequest, RequestOptions.DEFAULT)

I get an handshake_failure Exception

javax.net.ssl.SSLException: Received fatal alert: handshake_failure

As described here and here I checked the logs and found the ClientHello

*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1307888763 bytes = { 137, 187, 7, 199, 3, 82, 79, 49, 175, 115, 114, 160, 22, 241, 240, 60, 237, 136, 239, 232, 108, 236, 249, 79, 139, 90, 119, 136 }
Session ID:  {95, 24, 10, 176, 230, 223, 52, 137, 2, 146, 170, 240, 61, 10, 177, 36, 223, 167, 33, 19, 225, 19, 213, 54, 22, 220, 239, 77, 199, 139, 52, 23}
Cipher Suites: [Unknown 0x13:0x1, Unknown 0x13:0x2, Unknown 0x13:0x3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, Unknown 0xcc:0xa9, Unknown 0xcc:0xa8, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA]
Compression Methods:  { 0 }
Extension server_name, server_name: [type=host_name (0), value=localhost]
Unsupported extension type_23, data: 
Extension renegotiation_info, renegotiated_connection: <empty>
Extension elliptic_curves, curve names: {unknown curve 29, secp256r1, secp384r1}
Extension ec_point_formats, formats: [uncompressed]
Unsupported extension type_35, data: 
Extension signature_algorithms, signature_algorithms: SHA256withECDSA, Unknown (hash:0x8, signature:0x4), SHA256withRSA, SHA384withECDSA, Unknown (hash:0x8, signature:0x5), SHA384withRSA, Unknown (hash:0x8, signature:0x6), SHA512withRSA, SHA1withRSA
Unsupported extension type_51, data: 00:24:00:1d:00:20:6a:06:37:c2:47:97:e9:87:59:c6:0e:8f:9a:7f:12:81:18:20:18:49:77:b3:d4:11:71:37:0e:13:3d:de:6f:10
Unsupported extension type_45, data: 01:01
Unsupported extension type_43, data: 08:03:04:03:03:03:02:03:01
***

and the ServerHello

*** ServerHello, TLSv1.2
RandomCookie:  GMT: 1595412045 bytes = { 85, 81, 154, 66, 129, 137, 233, 228, 170, 170, 0, 28, 94, 221, 152, 50, 25, 2, 31, 115, 127, 103, 180, 78, 173, 152, 8, 173 }
Session ID:  {95, 24, 10, 176, 230, 223, 52, 137, 2, 146, 170, 240, 61, 10, 177, 36, 223, 167, 33, 19, 225, 19, 213, 54, 22, 220, 239, 77, 199, 139, 52, 23}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
Cipher suite:  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Both, Client and Server agree upon the Cipher suite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Then follows the request in encrypted and plain text. Afterwards follows another ClientHello which ends with

[Raw read]: length = 5
0000: 15 03 03 00 02                                     .....
[Raw read]: length = 2
0000: 02 28                                              .(
I/O dispatcher 25, READ: TLSv1.2 Alert, length = 2
I/O dispatcher 25, RECV TLSv1.2 ALERT:  fatal, handshake_failure
I/O dispatcher 25, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
I/O dispatcher 25, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
2020-07-22 12:00:45.360 ERROR 78321 --- [io-8081-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.io.IOException: Received fatal alert: handshake_failure

The line

I/O dispatcher 25, READ: TLSv1.2 Alert, length = 2

gives hint to a non-agreement upon the Cipher suite - but in the lines above both agreed upon a suite.

Does anyone has an idea what is happening here and how the the Exception can be resolved?

答案1

得分: 0

A proper solution is still missing but I found a well-working workaround. I am using curl to transfer the data to the elastic-Instance

val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create()
val fileContent = createTempFile(prefix = "data")
fileContent.writeText(gson.toJson(it))
val fileCommand = createTempFile()
val command = "curl --user $username:$password -PUT '$scheme://$hostname:$port/data/_doc' -H 'Content-Type: application/json' -d @${fileContent.absolutePath}"
fileCommand.writeText(command)

val result = "bash ${fileCommand.absolutePath}".runCommand(createTempDir())
logger.debug(result)
fileCommand.delete()
fileContent.delete()

The runCommand is motivated by this post. Firstly I tried using only one file but the escaping of special characters did not work as expected.

With this method, the handshake failure does not happen, which indicates an error in my previous code.

英文:

A proper solution is still missing but I found a well working workaround. I am using curl to transfer the data to the elastic-Instance

val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create()
val fileContent = createTempFile(prefix = "data")
fileContent.writeText(gson.toJson(it))
val fileCommand = createTempFile()
val command = "curl --user $username:$password -PUT '$scheme://$hostname:$port/data/_doc' -H 'Content-Type: application/json' -d @${fileContent.absolutePath}"
fileCommand.writeText(command)

val result = "bash ${fileCommand.absolutePath}".runCommand(createTempDir())
logger.debug(result)
fileCommand.delete()
fileContent.delete()

The runCommand is motivated by this post. Firstly I tried using only one file but the escaping of special characters did not work as expected.

With this method the handshake failure does not happen, which indicates an error in my previous code.

huangapple
  • 本文由 发表于 2020年7月22日 19:51:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/63033545.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定