Shield LDAPS Integration Error

Hi all,
I'm testing shield with ldaps.

I'm testing ldap over SSL/TLS to:

domain.com is the load balancer and redirects the traffic to hostname1.domain.com, hostname2.domain.com, hostname3.domain.com etc..

Now if I test the connectivity to ldaps://hostname1.domain.com:636 is working fine both on shield and using the ldapsearch linux command.

Otherwise, If I connect to ldaps://domain.com:636 (this is working with No SSL on port 389) I get a certificate mismatch error:

  • using ldapsearch command
    TLS: hostname (domain.com) does not match common name in certificate (hostname1.domain.com).

  • on shield (same)
    LDAPException(resultCode=91 (connect error), errorMessage='An error occurred while attempting to connect to server domain.com:636: java.io.IOException: Hostname verification failed because the expected hostname 'domain.com' was not found in peer certificate 'subject='CN=hostname.domain.com' dNSName='hostname.domain.com''.')

I understand the error above. All good.

What I don't understand is that If I disable the certificate verification with the option TLS_REQCERT ALLOW in my ldap.conf, the ldapsearch command works fine.

But If I try to do the same on Shield with the option hostname_verification: false I get a different error:
LDAPException(resultCode=81 (server down), errorMessage='An error occurred while attempting to send the LDAP message to server domain.com:636: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake caused by java.io.EOFException: SSL peer shut down incorrectly')

Can you please explaining why or at least address me to find a solution?
Is it a shield issue to be not able to perform the SSL/TLS handshake thorough the ldaps load balancer maybe?

Thanks for the support.

Hi @ccrivelli,

What version of Shield are you using? I think the issue may have to do with the default TLS protocol (TLSv1.2) that Shield uses and the load balancer not supporting that version.

In your elasticsearch.yml, can you add the following:

shield.ssl.protocol: TLS

Then restart the node and try to authenticate again.

Jay

Hi @jaymode ,
thanks for your reply.

shield version: elasticsearch-shield-1.3.1.jar
and

java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)```

I added ```shield.ssl.protocol: TLS``` as your advice to force TLS protocol.
I restarted the nodes, I had no errors in the ES logs this time apparently (all the nodes started correctly), but when I tried to authenticate I got:

```authentication failed for user [username]: failed LDAP authentication;
..
cause: com.unboundid.ldap.sdk.LDAPException: An error occurred while attempting to send the LDAP message to server domain.com:636:  javax.net.ssl.SSLHandshakeException: server certificate change is restricted during renegotiation```

I also tried to force to TLSv1 protocol.

I noticed the following behavior:

- sometimes the ES nodes do not start properly getting the ``` LDAPException(resultCode=81 (server down)``` as mentioned in my first post above;

- sometimes they start (no exceptions in the ES logs), but I'm not able to authenticate getting the error ```com.unboundid.ldap.sdk.LDAPException: An error occurred while attempting to send the LDAP message to server domain.com:636:  javax.net.ssl.SSLHandshakeException: server certificate change is restricted during renegotiation```
- sometimes I'm able to authenticate properly, but after a while it stops working getting the error: ```cause: com.unboundid.ldap.sdk.LDAPException: An error occurred while attempting to send the LDAP message to server domain.com:636:  javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake caused by java.io.EOFException: SSL peer shut down incorrectly```


I also tried to add the Java Options: 
```-Djdk.tls.allowUnsafeServerCertChange=true 
-Dsun.security.ssl.allowUnsafeRenegotiation=true```
as mentioned here: http://stackoverflow.com/questions/27105004/what-means-javax-net-ssl-sslhandshakeexception-server-certificate-change-is-re


But still the same behaviour.

Any other ideas?


Thanks, I appreciate your help.

UPDATE: forcing the TLS protocol with the option shield.ssl.protocol: TLS allows me to authenticate, the problem now is that I get the original error:
LDAPException(resultCode=81 (server down), errorMessage='An error occurred while attempting to send the LDAP message to server domain.com:636: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake caused by java.io.EOFException: SSL peer shut down incorrectly')
only on some ES nodes randomly.

I mean that I have 5 nodes and I get this error only on 2 or 3 randomly when I start elasticsearch service. The nodes are not always the same ones, I guess It could depend on the way the load balancer contact the physical ldap servers, but I tested the ldap load balancer executing many ldapsearch from each ES node (any time contacting different physical ldap servers) and I never faced any issue.
When I get this error on ES logs, elasticsearch service is being shut down automatically.



On the other side ...

The workaround with Java Opts: Java Options:

-Dsun.security.ssl.allowUnsafeRenegotiation=true``` 

seems to solve the error: 
```com.unboundid.ldap.sdk.LDAPException: An error occurred while attempting to send the LDAP message to server domain.com:636: javax.net.ssl.SSLHandshakeException: server certificate change is restricted during renegotiation````

Do not consider this one.

Thanks

That's interesting that you're still seeing the SSL handshake exception. Do you have a list of all the LDAP servers behind the load balancer? If so I wonder if you could use:

openssl s_client -connect servername:636

I'd be looking for output like:

New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES128-SHA

If you can provide the output of each server and the load balancer, we may be able to see a difference as to what is happening.

That said, startup shouldn't fail when a connection error occurs and it is a bug that we are currently working on fixing.

-Jay

Yep,
I don't have a full list of all the ldap servers behind the load balancer (I guess there are hundreds or maybe more .. ), but I found some of them querying the load balancer many times.

And I already noted some differences in terms of Protocol and Cipher, like:

ldap - type1

New, TLSv1/SSLv3, Cipher is AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES128-SHA

ldap - type2

New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA

ldap - type3

New, TLSv1/SSLv3, Cipher is AES128-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES128-SHA256

ldap - type4

New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-SHA384

Carmelo

I think that may have uncovered at least part of the issue. RC4-SHA is not enabled by default for Shield. RC4 is considered weak and your data could be considered vulnerable to decryption. However it appears that the cipher may need to be enabled in order to work with your LDAP type 2 servers.

In your elasticsearch.yml file, you can enable the RC4-SHA cipher by adding the following setting:

shield.ssl.ciphers: [ "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_RC4_128_SHA"]

The first three ciphers are the default ones that Shield uses. We have limited the default enabled cipher suites for security purposes. The last cipher is the Java equivalent of the OpenSSL cipher RC4-SHA.

Jay