Add LDAP server certificate to trusted list and enable certificate verification

10,872

Although it has been some years since the original question, I want to answer it anyway to help the lost souls who may be in a similar situation.

The LDAP system was actually an Active Directory and the CA certificate cannot be obtained via network (at least I haven't found a way). Thus, we asked the Windows team, got in contact with the admin who was responsible, and asked him if he could give us the CA certificate. The admin exported it and we just had to convert it into a PEM file, place it in the respective directory, and issue the update-ca-trust command.

Something like this:

openssl x509 -inform der -in ca.example.com.cer -out ca.example.com.pem
cp ca.example.com.pem /etc/pki/ca-trust/source/anchors/ca.example.com.pem
update-ca-trust

Certificate issues were resolved and we used ldapsearch onwards and not curl, because we experienced other issues with curl, like retrieving only partial results.

Share:
10,872

Related videos on Youtube

bm-bergmotte
Author by

bm-bergmotte

Updated on September 18, 2022

Comments

  • bm-bergmotte
    bm-bergmotte over 1 year

    I am trying to use a secure LDAP connection via TLS ldaps://<server_name>:<port> for various applications (e.g. Gitlab). However, the connection raises certificate errors which is due to the fact that the LDAP admins used self-signed certificates.

    Here is what I've tried:

    curl "ldap://ldapserver.example.com:389/DC=example,DC=com?sAMAccountName?sub?(memberOf=CN=custom-group,DC=example,DC=com)" -u [email protected]
    

    Works just as expected and returns the desired query result but is obviously insecure.

    When I tried:

    curl -v "ldaps://ldapserver.example.com:636/DC=example,DC=com?sAMAccountName?sub?(memberOf=CN=custom-group,DC=example,DC=com)" -u [email protected]
    

    I got:

    * About to connect() to ldapserver.example.com port 636 (#0)
    *   Trying 10.10.10.10...
    * Connected to ldapserver.example.com (10.10.10.10) port 636 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    * Server certificate:
    *       subject: CN=ldapserver.example.com
    *       start date: Jan 14 15:00:00 2018 GMT
    *       expire date: Dec 24 14:59:59 2019 GMT
    *       common name: ldapserver.example.com
    *       issuer: O=EXAMPLE,C=UK
    * NSS error -8179 (SEC_ERROR_UNKNOWN_ISSUER)
    * Peer's Certificate issuer is not recognized.
    * Closing connection 0
    curl: (60) Peer's Certificate issuer is not recognized.
    More details here: http://curl.haxx.se/docs/sslcerts.html
    
    curl performs SSL certificate verification by default, using a "bundle"
     of Certificate Authority (CA) public keys (CA certs). If the default
     bundle file isn't adequate, you can specify an alternate file
     using the --cacert option.
    If this HTTPS server uses a certificate signed by a CA represented in
     the bundle, the certificate verification probably failed due to a
     problem with the certificate (it might be expired, or the name might
     not match the domain name in the URL).
    If you'd like to turn off curl's verification of the certificate, use
     the -k (or --insecure) option.
    

    Trying the same command with the --insecure flag then connects to the LDAP server but returns no result:

    * About to connect() to ldapserver.example.com port 636 (#0)
    *   Trying 10.10.10.10...
    * Connected to ldapserver.example.com (10.10.10.10) port 636 (#0)
    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    * skipping SSL peer certificate verification
    * NSS: client certificate not found (nickname not specified)
    * SSL connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    * Server certificate:
    *       subject: CN=ldapserver.example.com
    *       start date: Jan 14 15:00:00 2018 GMT
    *       expire date: Dec 24 14:59:59 2019 GMT
    *       common name: ldapserver.example.com
    *       issuer: O=EXAMPLE,C=UK
    * LDAP local: ldaps://ldapserver.example.com:636/DC=example,DC=com?sAMAccountName?sub?(memberOf=CN=custom-group,DC=example,DC=com)
    

    Alright, I've tried now ldapsearch:

    ldapsearch -x -b 'dc=example,dc=com' -D '[email protected]' -H "ldaps://ldapserver.example.com:636" -W '(memberOf=CN=custom-group,DC=example,DC=com)'
    

    And got:

    ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
    

    After doing an export LDAPTLS_REQCERT=never and issuing the same ldapsearch-command above the query returned a result.

    Disabling certificate verification is obviously not a good option in particularly if LDAP authentication is used for instance within Gitlab.

    I tried to add the certificate of the LDAP server to the trusted certificates by getting the certificate with:

    echo -n | openssl s_client -connect ldapserver.example.com:636 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ldapserver.example.com.pem
    

    Then I've put it to /etc/pki/ca-trust/source/anchors/ and updated the ca-trust

    cp ldapserver.example.com.pem /etc/pki/ca-trust/source/anchors/ldapserver.example.com.crt
    update-ca-trust extract
    

    However, the commands above returned the same result.

    I guess that I probably need to add the CA chain which effectively consists only of that one certificate:

    openssl s_client -showcerts -verify -connect ldapserver.example.com:636 < /dev/null
    
    verify depth is 5
    CONNECTED(00000003)
    depth=0 CN = ldapserver.example.com
    verify error:num=20:unable to get local issuer certificate
    verify return:1
    depth=0 CN = ldapserver.example.com
    verify error:num=21:unable to verify the first certificate
    verify return:1
    ---
    Certificate chain
     0 s:/CN=ldapserver.example.com
       i:/C=UK/O=EXAMPLE
    -----BEGIN CERTIFICATE-----
    [...]
    -----END CERTIFICATE-----
    ---
    Server certificate
    subject=/CN=ldapserver.example.com
    issuer=/C=UK/O=EXAMPLE
    ---
    No client certificate CA names sent
    Client Certificate Types: RSA sign, DSA sign, ECDSA sign
    Requested Signature Algorithms: RSA+SHA512:ECDSA+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:DSA+SHA1
    Shared Requested Signature Algorithms: RSA+SHA512:ECDSA+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA1:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA1:DSA+SHA1
    Peer signing digest: SHA1
    Server Temp Key: ECDH, P-521, 521 bits
    ---
    SSL handshake has read 1666 bytes and written 563 bytes
    ---
    New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : ECDHE-RSA-AES256-SHA384
        Session-ID: 12345678912345678912345791234567891234567891234579
        Session-ID-ctx:
        Master-Key: 123456789123456789123457912345678912345678912345791234567891234567891234579
        Key-Arg   : None
        Krb5 Principal: None
        PSK identity: None
        PSK identity hint: None
        Start Time: 1540914932
        Timeout   : 300 (sec)
        Verify return code: 21 (unable to verify the first certificate)
    ---
    DONE
    

    So my question is: How do I add the certificate in a way that certificate verification works? Can I do that at all or do I have to contact our LDAP admin to provide me something for that?

    Find below some information about the system and tools:

    RHEL 7.5
    
    ldapsearch -V -v
    ldapsearch: @(#) $OpenLDAP: ldapsearch 2.4.44 (Apr  3 2018 08:03:33) $
            [email protected]:/builddir/build/BUILD/openldap-2.4.44/openldap-2.4.44/clients/tools
            (LDAP library: OpenLDAP 20444)
    ldap_initialize( <DEFAULT> )
    ldap_sasl_interactive_bind_s: Can't contact LDAP server (-1)
    
    curl -V -v
    curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.28.4 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
    Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
    Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets
    
    • GracefulRestart
      GracefulRestart over 5 years
      In RHEL 7, there should be a utility update-ca-trust from the package ca-certificates. That should allow you to add the self-signed CA into your trusted store.
    • bm-bergmotte
      bm-bergmotte over 5 years
      @GracefulRestart I've already done that (see question above) and it does not change the behaviour of curl or ldapsearch (still raising security errors that it cannot verify the certificate). I also issued: certutil -d sql:/etc/pki/nssdb -A -t "CP" -n ldapserver.example.com -i /home/my-user/ldapserver.example.com.crt and a cp ldapserver.example.com.crt /etc/openldap/certs/ both with no further effect.
    • bm-bergmotte
      bm-bergmotte over 5 years
      Sorry my previous comment was not entirely correct, the certutil command caused that curl does not require anymore the --insecure flag but it still returns no LDAP query result.