2

SOLVED: Turned out problem was caused by forgotten legacy LDAPTrustedGlobalCert directives in various config files, using old certificate for the same FQDN

tl;dr: We uses a self-signed CA and we never had to use directives that disable certificates verification: how to make Apache trust our self-signed CA for mod_ldap?

I am trying to configure my Apache web server for an HTTP authentication using an LDAP directory as user base.

Everything works fine in non-encrypted mode but fails with a HTTP 500 error code with SSL or STARTTLS.

Here is my Apache configuration:

AuthType Basic
AuthName "WebServer"
AuthBasicProvider ldap
AuthzLDAPAuthoritative on

# Plain:
AuthLDAPURL "ldap://ldap.example.com/dc=example,dc=local?uid?sub?(objectClass=person)"

# SSL:
LDAPTrustedGlobalCert CA_BASE64 /etc/ssl/certs/ca-certificates.crt
AuthLDAPURL "ldaps://ldap.example.com:636/dc=example,dc=local?uid?sub?(objectClass=person)" SSL

# StartTLS
LDAPTrustedGlobalCert CA_BASE64 /etc/ssl/certs/ca-certificates.crt
LDAPTrustedMode TLS
AuthLDAPURL "ldap://ldap.example.com/dc=example,dc=local?uid?sub?(objectClass=person)"

AuthLDAPBindDN "cn=webserver.example.com,ou=Apps,dc=example,dc=local"
AuthLDAPBindPassword "secret"

/etc/ssl/certs/ca-certificates.crt is a concatenation of multiple CA certificates (generated by ca-certificates Debian package). I've tried by pointing LDAPTrustedGlobalCert to either the rootCA or the subCA having signed the ldap.example.com certificates: same issue.

error.log says:

# TLS:
auth_ldap authenticate: user john-doe authentication failed; URI / [LDAP: ldap_start_tls_s() failed][Connect error]

# SSL:
auth_ldap authenticate: user john-doe authentication failed; URI / [LDAP: ldap_simple_bind_s() failed][Can't contact LDAP server]

We are using a PKI with a self-managed root CA (self-signed) and several sub-CA that signs certificates for web and LDAP servers. By adding the sub-CA PEM file on our servers and configuring ca-certificates Debian package and ldap.conf (for TLS_CACERT), the LDAP can be successfully accessed via plain non-encrypted (port 389), StartTLS (port 389) and SSL (port 636) for Linux PAM (libnss-ldapd Debian package) and LDAP browser softwares.

How can I tell Apache to check received certificates and trust my rootCA?

Edit to answers @shane-madden ideas

  • Works if using LDAPVerifyServerCert Off.
  • openssl s_client -connect ldap.example.com:636 -showcerts returns the following:

    CONNECTED(00000003)
    depth=3 CN = ExampleRootCa, O = Example, C = FR
    verify error:num=19:self signed certificate in certificate chain
    verify return:0
    ---
    Certificate chain
     0 s:/CN=ldap.example.com/O=Example/C=FR
       i:/CN=ExampleSrvCa/O=Example/C=FR
    -----BEGIN CERTIFICATE-----
    MIIGcDCCBF
    ...
    iyrFEYDcs=
    -----END CERTIFICATE-----
     1 s:/CN=ExampleSrvCa/O=Example/C=FR
       i:/CN=ExampleMainCa/O=Example/C=FR
    -----BEGIN CERTIFICATE-----
    MIIF2DCCA8
    ...
    GrskgqnaEg
    -----END CERTIFICATE-----
     2 s:/CN=ExampleMainCa/O=Example/C=FR
       i:/CN=ExampleRootCa/O=Example/C=FR
    -----BEGIN CERTIFICATE-----
    MIIF1TCCA7
    ...
    RozDAcZnph
    -----END CERTIFICATE-----
     3 s:/CN=ExampleRootCa/O=Example/C=FR
       i:/CN=ExampleRootCa/O=Example/C=FR
    -----BEGIN CERTIFICATE-----
    MIIFWzCCA0
    ...
    RY5xwHgA==
    -----END CERTIFICATE-----
    ---
    Server certificate
    subject=/CN=ldap.example.com/O=Example/C=FR
    issuer=/CN=ExampleSrvCa/O=Example/C=FR
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 6410 bytes and written 934 bytes
    ---
    New, TLSv1/SSLv3, Cipher is AES256-SHA256
    Server public key is 4096 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : AES256-SHA256
        Session-ID: ABC...
        Session-ID-ctx:
        Master-Key: DEF...
        Key-Arg   : None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        Start Time: 1391654253
        Timeout   : 300 (sec)
        Verify return code: 19 (self signed certificate in certificate chain)
    
  • Running openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt CN=ldap.example.com_O=Example_C=FR.crt says certificate is OK
CDuv
  • 240
  • 1
  • 3
  • 12
  • Found some `LDAPTrustedGlobalCert` directives into various VirtualHost files (`/etc/apache2/sites-available/`) but outside ``. Theses where pointing to an old self-signed certificate for the same FQDN (legacy tests). After cleaning the entire Apache config, both SSL and TLS LDAP authentication worked just fine (no need of any `LDAPTrustedGlobalCert` anywhere...) – CDuv Feb 07 '14 at 01:05

1 Answers1

4

Well, first let's confirm that the certificate trust is actually the problem. Does it work with LDAPVerifyServerCert Off?

Also, let's confirm that the LDAP service is talking with a certificate that will work; connect to it:

openssl s_client -connect ldap.example.com:636 -showcerts

If it's just sending its host certificate and not the intermediate or root certificates that signed it, you'll need to be trusting the intermediate certificate explicitly with Apache.

Grab the host cert that was output during that s_client connection and write it to a file, then verify that the signature is good:

openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt received-cert.crt
Shane Madden
  • 112,982
  • 12
  • 174
  • 248
  • Sorry, forgot to specify that it is working if I use `LDAPVerifyServerCert Off`. `openssl s_client ... -showcerts` send every certificates first the LDAP server, then each intermediate CA then the root CA. `openssl verify -CAfile` says LDAP server certificate (first one received) is OK (original post edited to adds theses infos). – CDuv Feb 06 '14 at 14:24